@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,66 @@
1
+ .container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 1rem;
5
+ height: 100%;
6
+ }
7
+
8
+ .header {
9
+ display: flex;
10
+ align-items: center;
11
+ justify-content: space-between;
12
+ padding-bottom: 0.5rem;
13
+ border-bottom: 1px solid var(--vscode-panel-border);
14
+ }
15
+
16
+ .title {
17
+ margin: 0;
18
+ font-size: 1.1rem;
19
+ font-weight: 600;
20
+ }
21
+
22
+ .count {
23
+ color: var(--vscode-descriptionForeground);
24
+ font-size: 0.9rem;
25
+ }
26
+
27
+ .table {
28
+ flex: 1;
29
+ overflow: auto;
30
+ }
31
+
32
+ .titleCell {
33
+ font-weight: 500;
34
+ }
35
+
36
+ .idCell code {
37
+ font-size: 0.85rem;
38
+ color: var(--vscode-textPreformat-foreground);
39
+ background-color: var(--vscode-textCodeBlock-background);
40
+ padding: 0.125rem 0.375rem;
41
+ border-radius: 3px;
42
+ }
43
+
44
+ .groupCell {
45
+ color: var(--vscode-descriptionForeground);
46
+ font-size: 0.9rem;
47
+ }
48
+
49
+ .optionsCell {
50
+ gap: 0.375rem;
51
+ flex-wrap: wrap;
52
+ }
53
+
54
+ .badge {
55
+ display: inline-block;
56
+ padding: 0.125rem 0.5rem;
57
+ background-color: var(--vscode-badge-background);
58
+ color: var(--vscode-badge-foreground);
59
+ border-radius: 10px;
60
+ font-size: 0.75rem;
61
+ font-weight: 500;
62
+ }
63
+
64
+ .actionCell {
65
+ text-align: right;
66
+ }
@@ -0,0 +1,88 @@
1
+ import React, { useMemo } from 'react';
2
+ import { useSystem } from '@/system/provider';
3
+ import {
4
+ VscodeButton,
5
+ VscodeTable,
6
+ VscodeTableBody,
7
+ VscodeTableCell,
8
+ VscodeTableHeader,
9
+ VscodeTableHeaderCell,
10
+ VscodeTableRow
11
+ } from '@vscode-elements/react-elements';
12
+ import { BasePanel } from '../base';
13
+ import styles from './index.module.css';
14
+
15
+ export const PanelPanel = () => {
16
+ const system = useSystem();
17
+
18
+ // Get all registered panels from the TabLoader
19
+ const registeredPanels = useMemo(() => {
20
+ const panels = Object.keys(system.tabLoader.tabs).map((id) => {
21
+ const tabData = system.tabLoader.tabs[id]?.();
22
+ return {
23
+ id,
24
+ title: tabData?.title || id,
25
+ group: tabData?.group || 'default',
26
+ closable: tabData?.closable ?? true,
27
+ cached: tabData?.cached ?? false
28
+ };
29
+ });
30
+
31
+ // Sort by title for easier browsing
32
+ return panels.sort((a, b) => a.title.localeCompare(b.title));
33
+ }, [system.tabLoader.tabs]);
34
+
35
+ const handleOpenPanel = (panelId: string) => {
36
+ system.tabStore.getState().openTab(panelId);
37
+ };
38
+
39
+ return (
40
+ <BasePanel>
41
+ <div className={styles.container}>
42
+ <div className={styles.header}>
43
+ <h2 className={styles.title}>Registered Panels</h2>
44
+ <div className={styles.count}>{registeredPanels.length} panels</div>
45
+ </div>
46
+
47
+ <VscodeTable className={styles.table}>
48
+ <VscodeTableHeader slot="header">
49
+ <VscodeTableHeaderCell>Panel</VscodeTableHeaderCell>
50
+ <VscodeTableHeaderCell>ID</VscodeTableHeaderCell>
51
+ <VscodeTableHeaderCell>Group</VscodeTableHeaderCell>
52
+ <VscodeTableHeaderCell>Options</VscodeTableHeaderCell>
53
+ <VscodeTableHeaderCell>Action</VscodeTableHeaderCell>
54
+ </VscodeTableHeader>
55
+ <VscodeTableBody slot="body">
56
+ {registeredPanels.map((panel) => (
57
+ <VscodeTableRow key={panel.id}>
58
+ <VscodeTableCell className={styles.titleCell}>
59
+ {panel.title}
60
+ </VscodeTableCell>
61
+ <VscodeTableCell className={styles.idCell}>
62
+ <code>{panel.id}</code>
63
+ </VscodeTableCell>
64
+ <VscodeTableCell className={styles.groupCell}>
65
+ {panel.group}
66
+ </VscodeTableCell>
67
+ <VscodeTableCell className={styles.optionsCell}>
68
+ {panel.cached && <span className={styles.badge}>cached</span>}
69
+ {!panel.closable && (
70
+ <span className={styles.badge}>not closable</span>
71
+ )}
72
+ </VscodeTableCell>
73
+ <VscodeTableCell className={styles.actionCell}>
74
+ <VscodeButton
75
+ onClick={() => handleOpenPanel(panel.id)}
76
+ secondary
77
+ >
78
+ Open
79
+ </VscodeButton>
80
+ </VscodeTableCell>
81
+ </VscodeTableRow>
82
+ ))}
83
+ </VscodeTableBody>
84
+ </VscodeTable>
85
+ </div>
86
+ </BasePanel>
87
+ );
88
+ };
@@ -0,0 +1,66 @@
1
+ .container {
2
+ display: flex;
3
+ flex-direction: column;
4
+ gap: 8px;
5
+ }
6
+
7
+ .searchGroup {
8
+ display: flex;
9
+ flex-direction: column;
10
+ gap: 4px;
11
+
12
+ }
13
+
14
+ .searchRow {
15
+ display: flex;
16
+ gap: 4px;
17
+ align-items: center;
18
+ }
19
+
20
+ .fullWidth {
21
+ width: 100%;
22
+ }
23
+
24
+ .resultsContainer {
25
+ display: flex;
26
+ flex-direction: column;
27
+ gap: 4px;
28
+ margin-top: 8px;
29
+ }
30
+
31
+ .resultsList {
32
+ display: flex;
33
+ flex-direction: column;
34
+ gap: 4px;
35
+ max-height: 400px;
36
+ overflow-y: auto;
37
+ border: 1px solid var(--vscode-panel-border);
38
+ border-radius: 4px;
39
+ padding: 8px;
40
+ }
41
+
42
+ .resultItem {
43
+ display: flex;
44
+ flex-direction: column;
45
+ gap: 4px;
46
+ cursor: pointer;
47
+ border: 1px solid var(--vscode-panel-border);
48
+ border-radius: 4px;
49
+ background-color: var(--vscode-list-hoverBackground);
50
+ padding: 8px;
51
+ transition: all 0.2s;
52
+ }
53
+
54
+ .resultItem:hover {
55
+ background-color: var(--vscode-list-activeSelectionBackground);
56
+ }
57
+
58
+ .resultId {
59
+ font-weight: bold;
60
+ font-size: 0.9em;
61
+ }
62
+
63
+ .resultType {
64
+ font-size: 0.8em;
65
+ opacity: 0.7;
66
+ }
@@ -0,0 +1,215 @@
1
+ import { annotatedTitle } from '@/annotations/index.js';
2
+ import React from 'react';
3
+ import {
4
+ VscodeButton,
5
+ VscodeTextfield,
6
+ VscodeSingleSelect,
7
+ VscodeOption,
8
+ VscodeLabel,
9
+ VscodeTreeItem,
10
+ VscodeTree,
11
+ VscodeCollapsible,
12
+ VscodeBadge
13
+ } from '@vscode-elements/react-elements';
14
+ import { useRefFromStore, useSystem } from '@/system';
15
+ import type { Node } from 'reactflow';
16
+ import { Search } from 'iconoir-react';
17
+ import Fuse from 'fuse.js';
18
+ import { useStore } from 'zustand';
19
+ import { BasePanel } from '../base';
20
+ import styles from './index.module.css';
21
+ import { Icon } from '@/components/primitives/icon';
22
+
23
+ type AnnotatedNode = Node & {
24
+ annotations: Record<string, string>;
25
+ };
26
+
27
+ type SearchResult = {
28
+ id: string;
29
+ type: string;
30
+ title?: string;
31
+ };
32
+
33
+ export const SearchPanel = () => {
34
+ const [id, setId] = React.useState('');
35
+ const [title, setTitle] = React.useState('');
36
+ const [nodeType, setNodeType] = React.useState('');
37
+ const [searchResults, setSearchResults] = React.useState<SearchResult[]>([]);
38
+
39
+ const sys = useSystem();
40
+ const graphNodes = useStore(sys.nodeStore, (s) => s.nodes);
41
+ const reactflow = useRefFromStore(sys.refStore, 'reactflow');
42
+
43
+ // Get available node types from the current graph
44
+ const availableNodeTypes = React.useMemo(() => {
45
+ const types = new Set<string>();
46
+
47
+ for (const node of graphNodes) {
48
+ const type = node?.data?.type;
49
+ if (typeof type === 'string' && type.length > 0) {
50
+ types.add(type);
51
+ }
52
+ }
53
+
54
+ return [...types].sort();
55
+ }, [graphNodes]);
56
+
57
+ const onClick = () => {
58
+ if (!reactflow) {
59
+ return;
60
+ }
61
+
62
+ const nodes = sys.nodeStore.getState().nodes;
63
+ const graphNodes = Object.values(nodes);
64
+
65
+ // Find all nodes matching the ID (partial match)
66
+ const matchingNodes = graphNodes.filter((n) =>
67
+ n.id.toLowerCase().includes(id.toLowerCase())
68
+ );
69
+
70
+ const results: SearchResult[] = matchingNodes.map((n) => ({
71
+ id: n.id,
72
+ type: n.data.type,
73
+ title: (n as AnnotatedNode).annotations?.[annotatedTitle]
74
+ }));
75
+
76
+ setSearchResults(results);
77
+ };
78
+
79
+ const onClickTitle = () => {
80
+ if (!reactflow) {
81
+ return;
82
+ }
83
+
84
+ const nodes = sys.nodeStore.getState().nodes;
85
+ const graphNodes = Object.values(nodes);
86
+
87
+ // Filter nodes that have titles
88
+ const nodesWithTitles = graphNodes.map((n) => ({
89
+ node: n,
90
+ title: (n as AnnotatedNode).data.type
91
+ }));
92
+
93
+ // Use Fuse.js for fuzzy search
94
+ const fuse = new Fuse(nodesWithTitles, {
95
+ keys: ['title'],
96
+ threshold: 0.4, // Lower = more strict, Higher = more fuzzy (0.0 = exact, 1.0 = match anything)
97
+ includeScore: true,
98
+ ignoreLocation: true
99
+ });
100
+
101
+ const fuseResults = fuse.search(title);
102
+ const matchingNodes = fuseResults.map((result) => result.item.node);
103
+
104
+ const results: SearchResult[] = matchingNodes.map((n) => ({
105
+ id: n.id,
106
+ type: n.data.type,
107
+ title: (n as AnnotatedNode).annotations?.[annotatedTitle]
108
+ }));
109
+
110
+ setSearchResults(results);
111
+ };
112
+
113
+ const onClickType = () => {
114
+ if (!reactflow || !nodeType) {
115
+ return;
116
+ }
117
+
118
+ const nodes = sys.nodeStore.getState().nodes;
119
+ const graphNodes = Object.values(nodes);
120
+
121
+ // Find all nodes matching the selected type
122
+ const matchingNodes = graphNodes.filter((n) => n.data.type === nodeType);
123
+
124
+ const results: SearchResult[] = matchingNodes.map((n) => ({
125
+ id: n.id,
126
+ type: n.data.type,
127
+ title: (n as AnnotatedNode).annotations?.[annotatedTitle]
128
+ }));
129
+
130
+ setSearchResults(results);
131
+ };
132
+
133
+ const handleTreeSelect = (ev: unknown) => {
134
+ const detail = (ev as CustomEvent<any>)?.detail;
135
+ const selectedItems = Array.isArray(detail)
136
+ ? detail
137
+ : detail?.selectedItems;
138
+ const firstSelected = selectedItems?.[0] as HTMLElement | undefined;
139
+ const key = firstSelected?.dataset?.varKey;
140
+
141
+ if (key) {
142
+ sys.actionStore.getState().actions.focusNode(key);
143
+ }
144
+ };
145
+
146
+ return (
147
+ <BasePanel>
148
+ <span style={{ fontWeight: 'bold', fontSize: '1.1em' }}>Find Node</span>
149
+
150
+ <div className={styles.searchGroup}>
151
+ <VscodeLabel>Find by ID</VscodeLabel>
152
+ <div className={styles.searchRow}>
153
+ <VscodeTextfield
154
+ className={styles.fullWidth}
155
+ value={id}
156
+ onChange={(e: any) => setId(e.target.value)}
157
+ />
158
+ <Icon onClick={onClick}>
159
+ <Search />
160
+ </Icon>
161
+ </div>
162
+ </div>
163
+
164
+ <div className={styles.searchGroup}>
165
+ <VscodeLabel>Find by Title</VscodeLabel>
166
+ <div className={styles.searchRow}>
167
+ <VscodeTextfield
168
+ className={styles.fullWidth}
169
+ value={title}
170
+ onChange={(e: any) => setTitle(e.target.value)}
171
+ />
172
+ <Icon onClick={onClickTitle}>
173
+ <Search />
174
+ </Icon>
175
+ </div>
176
+ </div>
177
+
178
+ <div className={styles.searchGroup}>
179
+ <VscodeLabel>Find by Type</VscodeLabel>
180
+
181
+ <VscodeSingleSelect
182
+ className={styles.fullWidth}
183
+ value={nodeType}
184
+ onChange={(e: any) => setNodeType(e.target.value)}
185
+ >
186
+ <VscodeOption value="">Select a type...</VscodeOption>
187
+ {availableNodeTypes.map((type) => (
188
+ <VscodeOption key={type} value={type}>
189
+ {type}
190
+ </VscodeOption>
191
+ ))}
192
+ </VscodeSingleSelect>
193
+ <VscodeButton onClick={onClickType} disabled={!nodeType}>
194
+ Search
195
+ </VscodeButton>
196
+ </div>
197
+
198
+ {searchResults.length > 0 && (
199
+ <VscodeCollapsible title="Results" open>
200
+ <VscodeBadge slot="decorations">{searchResults.length}</VscodeBadge>
201
+ <VscodeTree onVscTreeSelect={handleTreeSelect}>
202
+ {searchResults.map((result) => (
203
+ <VscodeTreeItem key={result.id} data-var-key={result.id}>
204
+ <span>
205
+ # {result.id} / {result.title}
206
+ </span>
207
+ <span slot="description">{result.type}</span>
208
+ </VscodeTreeItem>
209
+ ))}
210
+ </VscodeTree>
211
+ </VscodeCollapsible>
212
+ )}
213
+ </BasePanel>
214
+ );
215
+ };
@@ -0,0 +1,206 @@
1
+ import { useSystem } from '@/system/provider';
2
+ import {
3
+ EDGE_TYPE,
4
+ LAYOUT_TYPE,
5
+ type EdgeType,
6
+ type LayoutType
7
+ } from '@/store/settings';
8
+
9
+ import {
10
+ VscodeCheckbox,
11
+ VscodeDivider,
12
+ VscodeLabel,
13
+ VscodeOption,
14
+ VscodeSingleSelect
15
+ } from '@vscode-elements/react-elements';
16
+ import { useStore } from 'zustand';
17
+ import styles from './styles.module.css';
18
+ import { BasePanel } from '../base';
19
+
20
+ const EdgeValues = Object.values(EDGE_TYPE);
21
+ const LayoutValues = Object.values(LAYOUT_TYPE);
22
+
23
+ const SectionTitle = ({ children }: { children: React.ReactNode }) => {
24
+ return <div className={styles.title}>{children}</div>;
25
+ };
26
+
27
+ const Description = ({ children }: { children: React.ReactNode }) => {
28
+ return (
29
+ <div
30
+ style={{
31
+ fontSize: '0.85em',
32
+ color: 'var(--vscode-descriptionForeground)',
33
+ opacity: 0.9
34
+ }}
35
+ >
36
+ {children}
37
+ </div>
38
+ );
39
+ };
40
+
41
+ const SelectSetting = ({
42
+ label,
43
+ description,
44
+ value,
45
+ onChange,
46
+ children
47
+ }: {
48
+ label: string;
49
+ description: React.ReactNode;
50
+ value: string;
51
+ onChange: (value: string) => void;
52
+ children: React.ReactNode;
53
+ }) => {
54
+ return (
55
+ <div className="flex flex-col gap-1 justify-start">
56
+ <VscodeLabel>{label}</VscodeLabel>
57
+ <Description>{description}</Description>
58
+ <VscodeSingleSelect
59
+ value={value}
60
+ onChange={(e: any) => {
61
+ const next = e?.target?.value as string | undefined;
62
+ if (next) onChange(next);
63
+ }}
64
+ >
65
+ {children}
66
+ </VscodeSingleSelect>
67
+ </div>
68
+ );
69
+ };
70
+
71
+ const ToggleSetting = ({
72
+ label,
73
+ description,
74
+ checked,
75
+ onChange
76
+ }: {
77
+ label: string;
78
+ description: React.ReactNode;
79
+ checked: boolean;
80
+ onChange: (checked: boolean) => void;
81
+ }) => {
82
+ return (
83
+ <div className="flex gap-2 justify-start">
84
+ <VscodeCheckbox
85
+ toggle
86
+ checked={checked}
87
+ onChange={(event: any) => onChange(Boolean(event?.target?.checked))}
88
+ />
89
+ <div className="flex flex-col justify-start gap-0.5">
90
+ <VscodeLabel>{label}</VscodeLabel>
91
+ <Description>{description}</Description>
92
+ </div>
93
+ </div>
94
+ );
95
+ };
96
+
97
+ export const Settings = () => {
98
+ const system = useSystem();
99
+
100
+ const settings = useStore(system.systemSettings);
101
+
102
+ return (
103
+ <BasePanel>
104
+ <div className="flex flex-col gap-3">
105
+ <SectionTitle>Layout</SectionTitle>
106
+ <SelectSetting
107
+ label="Edge Type"
108
+ description="Select the type of edge to use in the graph editor."
109
+ value={settings.edgeType}
110
+ onChange={(value) => settings.setEdgeType(value as EdgeType)}
111
+ >
112
+ <VscodeOption value="">Select an edge type...</VscodeOption>
113
+ {EdgeValues.map((type) => (
114
+ <VscodeOption key={type} value={type}>
115
+ {type}
116
+ </VscodeOption>
117
+ ))}
118
+ </SelectSetting>
119
+
120
+ <SelectSetting
121
+ label="Layout Type"
122
+ description="Select the type of layout engine to use in the graph editor."
123
+ value={settings.layoutType}
124
+ onChange={(value) => settings.setLayoutType(value as LayoutType)}
125
+ >
126
+ <VscodeOption value="">Select a layout type...</VscodeOption>
127
+ {LayoutValues.map((type) => (
128
+ <VscodeOption key={type} value={type}>
129
+ {type}
130
+ </VscodeOption>
131
+ ))}
132
+ </SelectSetting>
133
+
134
+ <VscodeDivider />
135
+
136
+ <SectionTitle>Accessibility</SectionTitle>
137
+ <ToggleSetting
138
+ label="Show inline types"
139
+ description={
140
+ 'Adds additional spans to help differentiate types for colorblind users.'
141
+ }
142
+ checked={settings.inlineTypes}
143
+ onChange={(value) => settings.setInlineTypes(value)}
144
+ />
145
+
146
+ <VscodeDivider />
147
+
148
+ <SectionTitle>Interaction</SectionTitle>
149
+ <ToggleSetting
150
+ label="Use delayed interaction"
151
+ description={'Forces a user to click save to update port.'}
152
+ checked={settings.delayedUpdate}
153
+ onChange={(value) => settings.setDelayedUpdate(value)}
154
+ />
155
+ <ToggleSetting
156
+ label="Click to connect"
157
+ description={
158
+ 'Allows you to quick connect nodes by clicking on the 2 port.'
159
+ }
160
+ checked={settings.connectOnClick}
161
+ onChange={(value) => settings.setConnectOnClick(value)}
162
+ />
163
+
164
+ <VscodeDivider />
165
+
166
+ <SectionTitle>Display</SectionTitle>
167
+ <ToggleSetting
168
+ label="Show inline values"
169
+ description={
170
+ 'Shows values directly on the node. Useful for debugging but can be cluttered.'
171
+ }
172
+ checked={settings.inlineValues}
173
+ onChange={(value) => settings.setInlineValues(value)}
174
+ />
175
+ <ToggleSetting
176
+ label="Show Minimap"
177
+ description={'Shows the minimap in the graph editing area.'}
178
+ checked={settings.showMinimap}
179
+ onChange={(value) => settings.setShowMinimap(value)}
180
+ />
181
+ <ToggleSetting
182
+ label="Show Grid"
183
+ description={'Shows the grid in the graph editing area.'}
184
+ checked={settings.showGrid}
185
+ onChange={(value) => settings.setShowGrid(value)}
186
+ />
187
+ <ToggleSetting
188
+ label="Snap to Grid"
189
+ description={'Snaps nodes to the grid while dragging.'}
190
+ checked={settings.snapGrid}
191
+ onChange={(value) => settings.setSnapGrid(value)}
192
+ />
193
+
194
+ <VscodeDivider />
195
+
196
+ <SectionTitle>Performance</SectionTitle>
197
+ <ToggleSetting
198
+ label="Show execution time"
199
+ description={'Shows how long it takes for a node to process.'}
200
+ checked={settings.showTimings}
201
+ onChange={(value) => settings.setShowTimings(value)}
202
+ />
203
+ </div>
204
+ </BasePanel>
205
+ );
206
+ };
@@ -0,0 +1,11 @@
1
+ .title {
2
+ font-size: 0.9em;
3
+ font-weight: 600;
4
+ color: var(--vscode-foreground);
5
+ }
6
+
7
+ .description {
8
+ font-size: 0.85em;
9
+ color: var(--vscode-descriptionForeground);
10
+ opacity: 0.9;
11
+ }
@@ -0,0 +1,38 @@
1
+ import { memo } from 'react';
2
+ import type { Tick } from './types';
3
+
4
+ const LINE_STYLE_BASE: React.CSSProperties = {
5
+ position: 'absolute',
6
+ top: 0,
7
+ bottom: 0,
8
+ width: 1,
9
+ backgroundColor: 'var(--vscode-panel-border)',
10
+ opacity: 0.3
11
+ };
12
+
13
+ type GridLinesProps = {
14
+ ticks: Tick[];
15
+ padding: number;
16
+ };
17
+
18
+ export const GridLines = memo(function GridLines({
19
+ ticks,
20
+ padding
21
+ }: GridLinesProps) {
22
+ return (
23
+ <div
24
+ style={{
25
+ position: 'absolute',
26
+ top: 0,
27
+ left: padding,
28
+ right: padding,
29
+ bottom: 0,
30
+ pointerEvents: 'none'
31
+ }}
32
+ >
33
+ {ticks.map(({ time, leftPct }) => (
34
+ <div key={time} style={{ ...LINE_STYLE_BASE, left: `${leftPct}%` }} />
35
+ ))}
36
+ </div>
37
+ );
38
+ });