@foresthubai/workflow-builder 0.3.0 → 0.4.1

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 (124) hide show
  1. package/LICENSE +661 -661
  2. package/NOTICE +16 -16
  3. package/README.md +110 -93
  4. package/dist/components/ui/command.d.ts +2 -2
  5. package/dist/components/ui/input.d.ts +1 -1
  6. package/dist/components/ui/resizable.d.ts +1 -1
  7. package/dist/components/ui/textarea.d.ts +1 -1
  8. package/dist/graph/BaseNode.js +10 -10
  9. package/dist/graph/reactFlowRegistry.d.ts.map +1 -1
  10. package/dist/lib/utils.d.ts +3 -0
  11. package/dist/lib/utils.d.ts.map +1 -0
  12. package/dist/lib/utils.js +6 -0
  13. package/dist/lib/utils.js.map +1 -0
  14. package/dist/stores/editorStore.d.ts +0 -1
  15. package/dist/stores/editorStore.d.ts.map +1 -1
  16. package/dist/stores/editorStore.js +1 -11
  17. package/dist/stores/editorStore.js.map +1 -1
  18. package/dist/toolbars/CanvasTabsToolbar.d.ts +11 -0
  19. package/dist/toolbars/CanvasTabsToolbar.d.ts.map +1 -0
  20. package/dist/toolbars/CanvasTabsToolbar.js +101 -0
  21. package/dist/toolbars/CanvasTabsToolbar.js.map +1 -0
  22. package/package.json +2 -2
  23. package/src/BuilderLayout.tsx +345 -345
  24. package/src/Canvas.tsx +261 -261
  25. package/src/CanvasEditor.tsx +142 -142
  26. package/src/CanvasTabsToolbar.tsx +176 -176
  27. package/src/RightConfigPanel.tsx +266 -266
  28. package/src/WorkflowBuilder.tsx +412 -412
  29. package/src/cn.ts +6 -6
  30. package/src/components/ui/add-button.tsx +39 -39
  31. package/src/components/ui/alert-dialog.tsx +141 -141
  32. package/src/components/ui/alert.tsx +59 -59
  33. package/src/components/ui/badge.tsx +36 -36
  34. package/src/components/ui/button.tsx +85 -85
  35. package/src/components/ui/card.tsx +79 -79
  36. package/src/components/ui/checkbox.tsx +28 -28
  37. package/src/components/ui/collapsible.tsx +9 -9
  38. package/src/components/ui/command.tsx +153 -153
  39. package/src/components/ui/delete-button.tsx +23 -23
  40. package/src/components/ui/dialog.tsx +125 -125
  41. package/src/components/ui/dropdown-menu.tsx +198 -198
  42. package/src/components/ui/input.tsx +55 -55
  43. package/src/components/ui/label.tsx +24 -24
  44. package/src/components/ui/readonly-banner.tsx +15 -15
  45. package/src/components/ui/resizable.tsx +43 -43
  46. package/src/components/ui/scroll-area.tsx +102 -102
  47. package/src/components/ui/select.tsx +160 -160
  48. package/src/components/ui/separator.tsx +29 -29
  49. package/src/components/ui/switch.tsx +27 -27
  50. package/src/components/ui/textarea.tsx +51 -51
  51. package/src/components/ui/toast.tsx +127 -127
  52. package/src/components/ui/toaster.tsx +33 -33
  53. package/src/components/ui/toggle-group.tsx +59 -59
  54. package/src/components/ui/toggle.tsx +43 -43
  55. package/src/components/ui/tooltip.tsx +32 -32
  56. package/src/dialogs/NodePickerDialog.tsx +84 -84
  57. package/src/dialogs/ValidationDialog.tsx +184 -184
  58. package/src/graph/BaseNode.tsx +557 -557
  59. package/src/graph/CustomEdge.tsx +185 -185
  60. package/src/graph/CustomNode.tsx +16 -16
  61. package/src/graph/FunctionCallNode.tsx +30 -30
  62. package/src/graph/PortHandle.tsx +189 -189
  63. package/src/graph/reactFlowRegistry.ts +26 -26
  64. package/src/hooks/use-toast.ts +125 -125
  65. package/src/hooks/useAvailableVariables.ts +20 -20
  66. package/src/hooks/useCanvasHistory.ts +22 -22
  67. package/src/hooks/useCanvasTabs.ts +168 -168
  68. package/src/hooks/useFunctionDiagnosticsSync.ts +40 -40
  69. package/src/hooks/useFunctionRegistry.ts +26 -26
  70. package/src/hooks/useFunctions.ts +44 -44
  71. package/src/hooks/useGraph.ts +161 -161
  72. package/src/hooks/useNodeDefinitions.ts +82 -82
  73. package/src/hooks/useParamErrors.ts +26 -26
  74. package/src/hooks/useResolvedTheme.ts +30 -30
  75. package/src/hooks/useResourceDiagnosticsSync.ts +58 -58
  76. package/src/hooks/useSuppressThemeTransition.ts +79 -79
  77. package/src/hooks/useWorkflowSerialization.ts +127 -127
  78. package/src/i18n/index.ts +53 -53
  79. package/src/i18n/locales/de.json +501 -501
  80. package/src/i18n/locales/en.json +557 -557
  81. package/src/index.ts +27 -27
  82. package/src/inputs/ExpressionInput.tsx +297 -297
  83. package/src/inputs/ParameterEditor.tsx +515 -515
  84. package/src/inputs/PortSection.tsx +144 -144
  85. package/src/panels/BuilderSidebar.tsx +301 -301
  86. package/src/panels/ChannelConfigPanel.tsx +49 -49
  87. package/src/panels/ChannelsPanel.tsx +28 -28
  88. package/src/panels/DebugConsolePanel.tsx +73 -73
  89. package/src/panels/DebugContextPanel.tsx +77 -77
  90. package/src/panels/DebugExternalIOPanel.tsx +180 -180
  91. package/src/panels/DiagnosticsPanel.tsx +170 -170
  92. package/src/panels/EdgeConfigPanel.tsx +104 -104
  93. package/src/panels/FunctionConfigPanel.tsx +179 -179
  94. package/src/panels/FunctionListPanel.tsx +45 -45
  95. package/src/panels/MemoryConfigPanel.tsx +55 -55
  96. package/src/panels/MemoryPanel.tsx +40 -40
  97. package/src/panels/ModelConfigPanel.tsx +41 -41
  98. package/src/panels/ModelsPanel.tsx +36 -36
  99. package/src/panels/NodeConfigPanel.tsx +630 -630
  100. package/src/panels/NodeLibrary.tsx +288 -288
  101. package/src/panels/ResourceConfigPanel.tsx +132 -132
  102. package/src/panels/ResourceListPanel.tsx +113 -113
  103. package/src/panels/VariableConfigPanel.tsx +161 -161
  104. package/src/panels/VariablesPanel.tsx +145 -145
  105. package/src/stores/canvasStore.test.ts +44 -44
  106. package/src/stores/canvasStore.ts +245 -245
  107. package/src/stores/debugStore.ts +74 -74
  108. package/src/stores/diagnosticsStore.ts +130 -130
  109. package/src/stores/editorStore.ts +190 -202
  110. package/src/styles/index.css +526 -526
  111. package/src/utils/categoryConstants.ts +26 -26
  112. package/src/utils/channelOperations.ts +86 -86
  113. package/src/utils/connectionRules.ts +137 -137
  114. package/src/utils/functionOperations.ts +179 -179
  115. package/src/utils/graphOperations.ts +550 -550
  116. package/src/utils/history.ts +207 -207
  117. package/src/utils/memoryOperations.ts +57 -57
  118. package/src/utils/migrateFunctionNodes.ts +107 -107
  119. package/src/utils/modelOperations.ts +55 -55
  120. package/src/utils/paramDisplay.ts +71 -71
  121. package/src/utils/resourceHelpers.ts +32 -32
  122. package/src/utils/translation.ts +28 -28
  123. package/src/utils/variableOperations.ts +75 -75
  124. package/tailwind-preset.ts +166 -166
package/NOTICE CHANGED
@@ -1,16 +1,16 @@
1
- edge-agents/workflow-builder
2
- Copyright (c) 2026 ForestHub. All rights reserved.
3
-
4
- This product includes software developed by ForestHub
5
- (https://foresthub.ai).
6
-
7
- The @foresthubai/workflow-builder package is the React canvas/editor
8
- component library for the edge-agents platform. This package is
9
- licensed under the GNU Affero General Public License Version 3.0
10
- (AGPL-3.0-only) or a separate commercial license.
11
-
12
- It depends on @foresthubai/workflow-core which is licensed under the
13
- Apache License, Version 2.0. AGPL allows consumption of Apache-licensed
14
- dependencies; the AGPL terms apply to this package only.
15
-
16
- For commercial licensing inquiries: root@foresthub.ai
1
+ edge-agents/workflow-builder
2
+ Copyright (c) 2026 ForestHub. All rights reserved.
3
+
4
+ This product includes software developed by ForestHub
5
+ (https://foresthub.ai).
6
+
7
+ The @foresthubai/workflow-builder package is the React canvas/editor
8
+ component library for the edge-agents platform. This package is
9
+ licensed under the GNU Affero General Public License Version 3.0
10
+ (AGPL-3.0-only) or a separate commercial license.
11
+
12
+ It depends on @foresthubai/workflow-core which is licensed under the
13
+ Apache License, Version 2.0. AGPL allows consumption of Apache-licensed
14
+ dependencies; the AGPL terms apply to this package only.
15
+
16
+ For commercial licensing inquiries: root@foresthub.ai
package/README.md CHANGED
@@ -1,93 +1,110 @@
1
- # @foresthubai/workflow-builder
2
-
3
- The ForestHub workflow **canvas/editor** — a reusable React component library. It
4
- renders the visual builder (node graph, panels, dialogs) and pairs with the
5
- headless [`@foresthubai/workflow-core`](../workflow-core) for the model, serialization
6
- and validation. Core owns the data; this package owns the UI.
7
-
8
- ## Requirements
9
-
10
- - **React 18** (peer dependency).
11
- - **Tailwind CSS 3** (peer dependency). This package is consumed the Tailwind way —
12
- it ships design tokens + a Tailwind preset, not a prebuilt stylesheet. A host that
13
- doesn't use Tailwind can't consume it as-is. This is the single supported path.
14
-
15
- ## Setup
16
-
17
- Four steps in the host app:
18
-
19
- ```ts
20
- // 1. Import the design-system tokens + builder CSS layers, once, at your entry.
21
- import "@foresthubai/workflow-builder/styles/index.css";
22
-
23
- // 2. Adopt the Tailwind preset (tokens → utilities, fonts, animations, plugin).
24
- // tailwind.config.ts:
25
- import workflowBuilderPreset from "@foresthubai/workflow-builder/tailwind-preset";
26
- export default {
27
- presets: [workflowBuilderPreset],
28
- content: [
29
- "./src/**/*.{ts,tsx}",
30
- // 3. Scan the builder so the utility classes its components use are emitted.
31
- "./node_modules/@foresthubai/workflow-builder/dist/**/*.js",
32
- ],
33
- };
34
- ```
35
-
36
- ```tsx
37
- // 4. Render it inside a HEIGHT-CONSTRAINED container — the builder fills h-full/
38
- // w-full and never assumes the viewport.
39
- import { WorkflowBuilder } from "@foresthubai/workflow-builder";
40
-
41
- <div style={{ height: "100vh" }}>
42
- <WorkflowBuilder models={models} language="en" onChange={...} onError={...} />
43
- </div>
44
- ```
45
-
46
- ## Ownership rules
47
-
48
- The builder is a guest in your app. It dresses **itself** and speaks **its own**
49
- language, but it never reaches into things the host owns.
50
-
51
- ### Styles
52
-
53
- - **The builder owns its base look** (font, text color, its panels/canvas/nodes)
54
- and ships the design tokens as **defaults** on `:root` (dark) and `.light`.
55
- - **The host owns the page.** The builder does **not** style `<body>` — no page
56
- background, no page font, no `overscroll-behavior`. The host provides page chrome.
57
- (The builder's translucent "glass" surfaces blur whatever's behind them, so give
58
- the area a backdrop if you want the glass to read its best.)
59
- - **The host drives color mode** by toggling a `.light` class on an ancestor
60
- (typically `<html>`). Default — no class — is dark.
61
- - **The host themes by overriding tokens.** Redeclare the CSS variables. The
62
- contract: values are **HSL channels** (`262 83% 58%`, not `#hex`/`hsl()`); override
63
- in **both** `:root` and `.light`; override at **`:root`/`html`, not a nested
64
- wrapper** — Radix dialogs/menus/tooltips/selects portal to `<body>`, outside the
65
- builder root, so a scoped override won't reach them. See
66
- [`workflow-cli/src/theme-overrides.css`](../workflow-cli/src/theme-overrides.css) for a worked example.
67
-
68
- ### Translations
69
-
70
- - **The builder owns its strings** (ships `en` + `de`) in a **private** i18next
71
- instance, served only through its own `I18nextProvider`. It deliberately does
72
- **not** register with react-i18next's global default (no `initReactI18next`, hence
73
- no `setI18n`) — that default is a single library-wide pointer with last-init-wins
74
- semantics, and a guest component must not own it. So the builder never collides
75
- with the host's i18next.
76
- - **No host i18n setup is required.** A host with no i18next, or one using
77
- react-i18next its own way (with or without an `<I18nextProvider>`), both work
78
- unchanged — the builder's instance is reachable only inside its own subtree and
79
- leaves the host's `useTranslation()` untouched.
80
- - **The host drives locale** via the `language` prop. The builder follows it and
81
- never auto-detects (no `LanguageDetector`, no localStorage writes).
82
-
83
- ## What the builder relies on from the host
84
-
85
- - React 18; Tailwind with the preset adopted and the builder in `content`.
86
- - A **sized parent** container (the builder fills it; it never sizes the viewport).
87
- - **Page chrome** (background/page font) — the builder no longer provides it.
88
- - A **`.light`** class on an ancestor for light mode (default dark).
89
- - The **`language`** prop for locale.
90
- - The **`models`** catalog, `onChange` / `onError` (and other) callbacks, and the
91
- imperative **ref handle** (`loadWorkflow` / `exportWorkflow` / `clear` / `validate`
92
- / undo-redo / selection / `setDebugPhase`). See `WorkflowBuilderProps` and
93
- `WorkflowBuilderHandle` in [`src/WorkflowBuilder.tsx`](./src/WorkflowBuilder.tsx).
1
+ # @foresthubai/workflow-builder
2
+
3
+ The ForestHub workflow **canvas/editor** — a reusable React component library. It
4
+ renders the visual builder (node graph, panels, dialogs) and pairs with the
5
+ headless [`@foresthubai/workflow-core`](../workflow-core) for the model, serialization
6
+ and validation. Core owns the data; this package owns the UI.
7
+
8
+ ## Requirements
9
+
10
+ - **React 18** (peer dependency).
11
+ - **Tailwind CSS 3** (peer dependency). This package is consumed the Tailwind way —
12
+ it ships design tokens + a Tailwind preset, not a prebuilt stylesheet. A host that
13
+ doesn't use Tailwind can't consume it as-is. This is the single supported path.
14
+
15
+ ## Setup
16
+
17
+ Four steps in the host app:
18
+
19
+ ```ts
20
+ // 1. Import the design-system tokens + builder CSS layers, once, at your entry.
21
+ import "@foresthubai/workflow-builder/styles/index.css";
22
+
23
+ // 2. Adopt the Tailwind preset (tokens → utilities, fonts, animations, plugin).
24
+ // tailwind.config.ts:
25
+ import workflowBuilderPreset from "@foresthubai/workflow-builder/tailwind-preset";
26
+ export default {
27
+ presets: [workflowBuilderPreset],
28
+ content: [
29
+ "./src/**/*.{ts,tsx}",
30
+ // 3. Scan the builder so the utility classes its components use are emitted.
31
+ "./node_modules/@foresthubai/workflow-builder/dist/**/*.js",
32
+ ],
33
+ };
34
+ ```
35
+
36
+ ```tsx
37
+ // 4. Render it inside a HEIGHT-CONSTRAINED container — the builder fills h-full/
38
+ // w-full and never assumes the viewport.
39
+ import { WorkflowBuilder } from "@foresthubai/workflow-builder";
40
+
41
+ <div style={{ height: "100vh" }}>
42
+ <WorkflowBuilder models={models} language="en" onChange={...} onError={...} />
43
+ </div>
44
+ ```
45
+
46
+ ## Ownership rules
47
+
48
+ The builder is a guest in your app. It dresses **itself** and speaks **its own**
49
+ language, but it never reaches into things the host owns.
50
+
51
+ ### Styles
52
+
53
+ - **The builder owns its base look** (font, text color, its panels/canvas/nodes)
54
+ and ships the design tokens as **defaults** on `:root` (dark) and `.light`.
55
+ - **The host owns the page.** The builder does **not** style `<body>` — no page
56
+ background, no page font, no `overscroll-behavior`. The host provides page chrome.
57
+ (The builder's translucent "glass" surfaces blur whatever's behind them, so give
58
+ the area a backdrop if you want the glass to read its best.)
59
+ - **The host drives color mode** by toggling a `.light` class on an ancestor
60
+ (typically `<html>`). Default — no class — is dark.
61
+ - **The host themes by overriding tokens.** Redeclare the CSS variables. The
62
+ contract: values are **HSL channels** (`262 83% 58%`, not `#hex`/`hsl()`); override
63
+ in **both** `:root` and `.light`; override at **`:root`/`html`, not a nested
64
+ wrapper** — Radix dialogs/menus/tooltips/selects portal to `<body>`, outside the
65
+ builder root, so a scoped override won't reach them. See
66
+ [`workflow-cli/src/theme-overrides.css`](../workflow-cli/src/theme-overrides.css) for a worked example.
67
+
68
+ ### Translations
69
+
70
+ - **The builder owns its strings** (ships `en` + `de`) in a **private** i18next
71
+ instance, served only through its own `I18nextProvider`. It deliberately does
72
+ **not** register with react-i18next's global default (no `initReactI18next`, hence
73
+ no `setI18n`) — that default is a single library-wide pointer with last-init-wins
74
+ semantics, and a guest component must not own it. So the builder never collides
75
+ with the host's i18next.
76
+ - **No host i18n setup is required.** A host with no i18next, or one using
77
+ react-i18next its own way (with or without an `<I18nextProvider>`), both work
78
+ unchanged — the builder's instance is reachable only inside its own subtree and
79
+ leaves the host's `useTranslation()` untouched.
80
+ - **The host drives locale** via the `language` prop. The builder follows it and
81
+ never auto-detects (no `LanguageDetector`, no localStorage writes).
82
+
83
+ ## What the builder relies on from the host
84
+
85
+ - React 18; Tailwind with the preset adopted and the builder in `content`.
86
+ - A **sized parent** container (the builder fills it; it never sizes the viewport).
87
+ - **Page chrome** (background/page font) — the builder no longer provides it.
88
+ - A **`.light`** class on an ancestor for light mode (default dark).
89
+ - The **`language`** prop for locale.
90
+ - The **`models`** catalog, `onChange` / `onError` (and other) callbacks, and the
91
+ imperative **ref handle** (`loadWorkflow` / `exportWorkflow` / `clear` / `validate`
92
+ / undo-redo / selection / `setDebugPhase`). See `WorkflowBuilderProps` and
93
+ `WorkflowBuilderHandle` in [`src/WorkflowBuilder.tsx`](./src/WorkflowBuilder.tsx).
94
+
95
+ ## License
96
+
97
+ **AGPL-3.0-only** or a separate commercial license — same dual-license terms as the
98
+ edge-agents engine.
99
+
100
+ Read this before embedding: AGPL-3.0 is **network copyleft (§13)**. Because
101
+ `<WorkflowBuilder>` is a React component you bundle into your own web app, serving that
102
+ app to users over a network makes your **entire combined frontend** a "modified work"
103
+ whose corresponding source you must offer to those users. Embedding the builder in a
104
+ proprietary or closed-source SaaS frontend is therefore not possible under the AGPL — for
105
+ that, take the commercial license (contact **root@foresthub.ai**). If your frontend is
106
+ itself AGPL-3.0, you're fine.
107
+
108
+ The headless [`@foresthubai/workflow-core`](../workflow-core) (model, serialization,
109
+ validation) is **Apache-2.0** and carries no such obligation — if you only need the data
110
+ layer, depend on core directly and skip this component.
@@ -23,7 +23,7 @@ declare const CommandInput: React.ForwardRefExoticComponent<Omit<Omit<Pick<Pick<
23
23
  ref?: React.Ref<HTMLInputElement>;
24
24
  } & {
25
25
  asChild?: boolean;
26
- }, "key" | "asChild" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "type" | "onChange" | "value"> & {
26
+ }, "key" | "asChild" | keyof React.InputHTMLAttributes<HTMLInputElement>>, "type" | "value" | "onChange"> & {
27
27
  value?: string;
28
28
  onValueChange?: (search: string) => void;
29
29
  } & React.RefAttributes<HTMLInputElement>, "ref"> & React.RefAttributes<HTMLInputElement>>;
@@ -67,7 +67,7 @@ declare const CommandItem: React.ForwardRefExoticComponent<Omit<{
67
67
  ref?: React.Ref<HTMLDivElement>;
68
68
  } & {
69
69
  asChild?: boolean;
70
- }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "onSelect" | "disabled" | "value"> & {
70
+ }, "key" | "asChild" | keyof React.HTMLAttributes<HTMLDivElement>>, "disabled" | "value" | "onSelect"> & {
71
71
  disabled?: boolean;
72
72
  onSelect?: (value: string) => void;
73
73
  value?: string;
@@ -3,7 +3,7 @@ import { type VariantProps } from "class-variance-authority";
3
3
  declare const inputVariants: (props?: ({
4
4
  size?: "sm" | "lg" | "md" | null | undefined;
5
5
  variant?: "default" | "ghost" | "subtle" | null | undefined;
6
- status?: "none" | "success" | "error" | null | undefined;
6
+ status?: "success" | "none" | "error" | null | undefined;
7
7
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
8
8
  export interface InputProps extends Omit<React.InputHTMLAttributes<HTMLInputElement>, 'size'>, VariantProps<typeof inputVariants> {
9
9
  htmlSize?: number;
@@ -1,6 +1,6 @@
1
1
  import * as ResizablePrimitive from "react-resizable-panels";
2
2
  declare const ResizablePanelGroup: ({ className, ...props }: React.ComponentProps<typeof ResizablePrimitive.PanelGroup>) => import("react/jsx-runtime").JSX.Element;
3
- declare const ResizablePanel: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLOListElement | HTMLElement | HTMLObjectElement | HTMLAnchorElement | HTMLButtonElement | HTMLDivElement | HTMLFormElement | HTMLHeadingElement | HTMLImageElement | HTMLInputElement | HTMLLabelElement | HTMLLIElement | HTMLParagraphElement | HTMLSelectElement | HTMLSpanElement | HTMLUListElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLLegendElement | HTMLLinkElement | HTMLMapElement | HTMLMetaElement | HTMLMeterElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPreElement | HTMLProgressElement | HTMLSlotElement | HTMLScriptElement | HTMLSourceElement | HTMLStyleElement | HTMLTableElement | HTMLTemplateElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLVideoElement | HTMLTableCaptionElement | HTMLMenuElement | HTMLPictureElement>, "id" | "onResize"> & {
3
+ declare const ResizablePanel: import("react").ForwardRefExoticComponent<Omit<import("react").HTMLAttributes<HTMLButtonElement | HTMLElement | HTMLDivElement | HTMLObjectElement | HTMLAnchorElement | HTMLFormElement | HTMLHeadingElement | HTMLImageElement | HTMLInputElement | HTMLLabelElement | HTMLLIElement | HTMLOListElement | HTMLParagraphElement | HTMLSelectElement | HTMLSpanElement | HTMLUListElement | HTMLAreaElement | HTMLAudioElement | HTMLBaseElement | HTMLQuoteElement | HTMLBodyElement | HTMLBRElement | HTMLCanvasElement | HTMLTableColElement | HTMLDataElement | HTMLDataListElement | HTMLModElement | HTMLDetailsElement | HTMLDialogElement | HTMLDListElement | HTMLEmbedElement | HTMLFieldSetElement | HTMLHeadElement | HTMLHRElement | HTMLHtmlElement | HTMLIFrameElement | HTMLLegendElement | HTMLLinkElement | HTMLMapElement | HTMLMetaElement | HTMLMeterElement | HTMLOptGroupElement | HTMLOptionElement | HTMLOutputElement | HTMLPreElement | HTMLProgressElement | HTMLSlotElement | HTMLScriptElement | HTMLSourceElement | HTMLStyleElement | HTMLTableElement | HTMLTemplateElement | HTMLTableSectionElement | HTMLTableCellElement | HTMLTextAreaElement | HTMLTimeElement | HTMLTitleElement | HTMLTableRowElement | HTMLTrackElement | HTMLVideoElement | HTMLTableCaptionElement | HTMLMenuElement | HTMLPictureElement>, "id" | "onResize"> & {
4
4
  className?: string | undefined;
5
5
  collapsedSize?: number | undefined;
6
6
  collapsible?: boolean | undefined;
@@ -5,7 +5,7 @@ export interface TextareaProps extends React.TextareaHTMLAttributes<HTMLTextArea
5
5
  declare const textareaVariants: (props?: ({
6
6
  size?: "sm" | "lg" | "md" | null | undefined;
7
7
  variant?: "default" | "ghost" | "subtle" | null | undefined;
8
- status?: "none" | "success" | "error" | null | undefined;
8
+ status?: "success" | "none" | "error" | null | undefined;
9
9
  } & import("class-variance-authority/types").ClassProp) | undefined) => string;
10
10
  declare const Textarea: React.ForwardRefExoticComponent<TextareaProps & React.RefAttributes<HTMLTextAreaElement>>;
11
11
  export { Textarea, textareaVariants };
@@ -259,16 +259,16 @@ export const BaseNode = memo(({ id, data, selected, nodeDefinition, isStale = fa
259
259
  : {};
260
260
  if (nodeShape === "tapered-right") {
261
261
  const inset = strokeW / 2;
262
- return (_jsxs("svg", { className: "absolute inset-0 z-0 transition-all duration-300 will-change-[filter]", width: nodeWidth, height: minHeight, viewBox: `0 0 ${nodeWidth} ${minHeight}`, preserveAspectRatio: "none", style: glowStyle, children: [_jsx("defs", { children: _jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "70%", x2: "100%", y2: "0%", children: [_jsx("stop", { offset: "0%", stopColor: gradientStartColor }), _jsx("stop", { offset: "100%", stopColor: gradientEndColor })] }) }), _jsx("path", { d: `
263
- M ${12 + inset} ${0 + inset}
264
- L ${nodeWidth - taperWidth - inset} ${0 + inset}
265
- L ${nodeWidth - inset} ${minHeight / 2}
266
- L ${nodeWidth - taperWidth - inset} ${minHeight - inset}
267
- L ${12 + inset} ${minHeight - inset}
268
- Q ${0 + inset} ${minHeight - inset} ${0 + inset} ${minHeight - 12 - inset}
269
- L ${0 + inset} ${12 + inset}
270
- Q ${0 + inset} ${0 + inset} ${12 + inset} ${0 + inset}
271
- Z
262
+ return (_jsxs("svg", { className: "absolute inset-0 z-0 transition-all duration-300 will-change-[filter]", width: nodeWidth, height: minHeight, viewBox: `0 0 ${nodeWidth} ${minHeight}`, preserveAspectRatio: "none", style: glowStyle, children: [_jsx("defs", { children: _jsxs("linearGradient", { id: gradientId, x1: "0%", y1: "70%", x2: "100%", y2: "0%", children: [_jsx("stop", { offset: "0%", stopColor: gradientStartColor }), _jsx("stop", { offset: "100%", stopColor: gradientEndColor })] }) }), _jsx("path", { d: `
263
+ M ${12 + inset} ${0 + inset}
264
+ L ${nodeWidth - taperWidth - inset} ${0 + inset}
265
+ L ${nodeWidth - inset} ${minHeight / 2}
266
+ L ${nodeWidth - taperWidth - inset} ${minHeight - inset}
267
+ L ${12 + inset} ${minHeight - inset}
268
+ Q ${0 + inset} ${minHeight - inset} ${0 + inset} ${minHeight - 12 - inset}
269
+ L ${0 + inset} ${12 + inset}
270
+ Q ${0 + inset} ${0 + inset} ${12 + inset} ${0 + inset}
271
+ Z
272
272
  `, fill: `url(#${gradientId})`, stroke: hasErrors
273
273
  ? "hsl(var(--destructive))"
274
274
  : fancyBg
@@ -1 +1 @@
1
- {"version":3,"file":"reactFlowRegistry.d.ts","sourceRoot":"","sources":["../../src/graph/reactFlowRegistry.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,SAAS;;;;;;CAMrB,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;;;;;YAOq9B,CAAC;gBAAuB,CAAC;;;;;;;;;;YAAzB,CAAC;gBAAuB,CAAC;;;;;;;;;;YAAzB,CAAC;gBAAuB,CAAC;;;;;;;;;;YAAzB,CAAC;gBAAuB,CAAC;;;;;;;;;;YAAzB,CAAC;gBAAuB,CAAC;;CADngC,CAAC"}
1
+ {"version":3,"file":"reactFlowRegistry.d.ts","sourceRoot":"","sources":["../../src/graph/reactFlowRegistry.ts"],"names":[],"mappings":"AAWA,eAAO,MAAM,SAAS;;;;;;CAMrB,CAAC;AAEF,eAAO,MAAM,SAAS;;;;;;;;;YAOy7B,CAAC;gBAAsB,CAAC;;;;;;;;;;YAAxB,CAAC;gBAAsB,CAAC;;;;;;;;;;YAAxB,CAAC;gBAAsB,CAAC;;;;;;;;;;YAAxB,CAAC;gBAAsB,CAAC;;;;;;;;;;YAAxB,CAAC;gBAAsB,CAAC;;CADt+B,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type ClassValue } from "clsx";
2
+ export declare function cn(...inputs: ClassValue[]): string;
3
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAQ,KAAK,UAAU,EAAE,MAAM,MAAM,CAAA;AAG5C,wBAAgB,EAAE,CAAC,GAAG,MAAM,EAAE,UAAU,EAAE,UAEzC"}
@@ -0,0 +1,6 @@
1
+ import { clsx } from "clsx";
2
+ import { twMerge } from "tailwind-merge";
3
+ export function cn(...inputs) {
4
+ return twMerge(clsx(inputs));
5
+ }
6
+ //# sourceMappingURL=utils.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.js","sourceRoot":"","sources":["../../src/lib/utils.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAmB,MAAM,MAAM,CAAA;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAA;AAExC,MAAM,UAAU,EAAE,CAAC,GAAG,MAAoB;IACxC,OAAO,OAAO,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAA;AAC9B,CAAC"}
@@ -2,7 +2,6 @@ import type { Channel } from "@foresthubai/workflow-core/channel";
2
2
  import type { Memory } from "@foresthubai/workflow-core/memory";
3
3
  import type { Model, ModelInfo } from "@foresthubai/workflow-core/model";
4
4
  import type { FunctionDeclaration } from "@foresthubai/workflow-core/function";
5
- export declare function createDefaultChannels(): Record<string, Channel>;
6
5
  import type { BuilderMode } from "../WorkflowBuilder";
7
6
  import type { SidebarTab } from "../panels/BuilderSidebar";
8
7
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"editorStore.d.ts","sourceRoot":"","sources":["../../src/stores/editorStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editorStore.d.ts","sourceRoot":"","sources":["../../src/stores/editorStore.ts"],"names":[],"mappings":"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"}
@@ -1,15 +1,5 @@
1
1
  import { create } from "zustand";
2
2
  import { getCanvasStore, getOrCreateCanvasStore, MAIN_CANVAS_ID } from "./canvasStore";
3
- // ---------------------------------------------------------------------------
4
- // Default Channels — every workflow starts pre-initialized with a UART
5
- // port so nodes that need a serial port (SerialRead/Write, OnSerialReceive)
6
- // have something to bind to out of the box. Domain shape only — the driver
7
- // binding is supplied at deploy time via the DeploymentMapping, not here.
8
- // ---------------------------------------------------------------------------
9
- export function createDefaultChannels() {
10
- const uart = { id: "uart0", label: "Serial", type: "UART", arguments: {} };
11
- return { [uart.id]: uart };
12
- }
13
3
  const NO_SELECTION = { kind: "none" };
14
4
  // Drop ReactFlow's visual selection on a canvas so previously-glowing nodes/edges
15
5
  // stop glowing. Peek (never create) — clearing selection must not resurrect a
@@ -22,7 +12,7 @@ export const useEditorStore = create((set, get) => ({
22
12
  builderMode: { type: "edit" },
23
13
  selection: NO_SELECTION,
24
14
  activeSidebarTab: "nodes",
25
- channels: createDefaultChannels(),
15
+ channels: {},
26
16
  memory: {},
27
17
  models: {},
28
18
  functions: {},
@@ -1 +1 @@
1
- {"version":3,"file":"editorStore.js","sourceRoot":"","sources":["../../src/stores/editorStore.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"editorStore.js","sourceRoot":"","sources":["../../src/stores/editorStore.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { CanvasTab } from "../hooks/useCanvasTabs";
2
+ interface CanvasTabsToolbarProps {
3
+ tabs: CanvasTab[];
4
+ activeTabId: string;
5
+ onTabChange: (tabId: string) => void;
6
+ onTabClose: (tabId: string) => void;
7
+ onTabReorder: (fromIndex: number, toIndex: number) => void;
8
+ }
9
+ export declare const CanvasTabsToolbar: ({ tabs, activeTabId, onTabChange, onTabClose, onTabReorder, }: CanvasTabsToolbarProps) => import("react/jsx-runtime").JSX.Element;
10
+ export {};
11
+ //# sourceMappingURL=CanvasTabsToolbar.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasTabsToolbar.d.ts","sourceRoot":"","sources":["../../src/toolbars/CanvasTabsToolbar.tsx"],"names":[],"mappings":"AAIA,OAAO,EAAE,SAAS,EAAE,MAAM,wBAAwB,CAAC;AAGnD,UAAU,sBAAsB;IAC9B,IAAI,EAAE,SAAS,EAAE,CAAC;IAClB,WAAW,EAAE,MAAM,CAAC;IACpB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,UAAU,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACpC,YAAY,EAAE,CAAC,SAAS,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,KAAK,IAAI,CAAC;CAC5D;AAED,eAAO,MAAM,iBAAiB,GAAI,+DAM/B,sBAAsB,4CA0JxB,CAAC"}
@@ -0,0 +1,101 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
2
+ import { ScrollArea } from "../components/ui/scroll-area";
3
+ import { cn } from "../lib/utils";
4
+ import { FunctionSquare, Workflow, X } from "lucide-react";
5
+ import React, { useCallback, useEffect, useRef, useState } from "react";
6
+ import { MAIN_CANVAS_ID } from "../stores/canvasStore";
7
+ export const CanvasTabsToolbar = ({ tabs, activeTabId, onTabChange, onTabClose, onTabReorder, }) => {
8
+ const containerRef = useRef(null);
9
+ const viewportRef = useRef(null);
10
+ const dragIndex = useRef(null);
11
+ // Translate vertical mouse-wheel deltas into horizontal scroll on the tabs
12
+ // viewport. A non-passive native listener is required because React's
13
+ // synthetic onWheel is passive — preventDefault() there is a no-op, so the
14
+ // page would also scroll vertically alongside the toolbar shift. We leave
15
+ // genuine horizontal wheels (touchpads, tilt wheels) alone by gating on
16
+ // deltaY, and skip the override entirely when there's nothing to scroll
17
+ // so vertical-page scrolling still works when the pointer happens to
18
+ // hover an unfilled toolbar.
19
+ useEffect(() => {
20
+ const el = viewportRef.current;
21
+ if (!el)
22
+ return;
23
+ const handler = (e) => {
24
+ if (e.deltaY === 0)
25
+ return;
26
+ if (el.scrollWidth <= el.clientWidth)
27
+ return;
28
+ e.preventDefault();
29
+ el.scrollLeft += e.deltaY;
30
+ };
31
+ el.addEventListener("wheel", handler, { passive: false });
32
+ return () => el.removeEventListener("wheel", handler);
33
+ }, []);
34
+ // dropSlot: insertion index (before which tab the dragged tab lands)
35
+ const [dropSlot, setDropSlot] = useState(null);
36
+ // indicatorX: pixel offset from container left for the visual line
37
+ const [indicatorX, setIndicatorX] = useState(null);
38
+ const isMainTab = (index) => tabs[index]?.id === MAIN_CANVAS_ID;
39
+ const clearDrag = useCallback(() => {
40
+ dragIndex.current = null;
41
+ setDropSlot(null);
42
+ setIndicatorX(null);
43
+ }, []);
44
+ const handleTabDragOver = useCallback((e, index) => {
45
+ if (dragIndex.current === null || !containerRef.current)
46
+ return;
47
+ // Ignore Main tab entirely — not a valid drag target
48
+ if (tabs[index]?.id === MAIN_CANVAS_ID)
49
+ return;
50
+ e.preventDefault();
51
+ e.stopPropagation();
52
+ e.dataTransfer.dropEffect = "move";
53
+ const rect = e.currentTarget.getBoundingClientRect();
54
+ const containerRect = containerRef.current.getBoundingClientRect();
55
+ const midX = rect.left + rect.width / 2;
56
+ const isLeftHalf = e.clientX < midX;
57
+ // Slot: insertion index
58
+ const slot = isLeftHalf ? index : index + 1;
59
+ // Tabs are now flush with a 1px separator between them — land the indicator on that seam.
60
+ const raw = isLeftHalf ? rect.left - containerRect.left : rect.right - containerRect.left;
61
+ // Clamp so the indicator stays fully visible inside the container
62
+ const x = Math.round(Math.max(0, Math.min(raw, containerRef.current.clientWidth - 2)));
63
+ setDropSlot(slot);
64
+ setIndicatorX(x);
65
+ }, [tabs]);
66
+ return (
67
+ // ScrollArea provides the horizontal overlay scrollbar (hover-only, in the
68
+ // panel gutter so the tab row doesn't shift). The Root carries the bg +
69
+ // bottom border; the inner div inside the Viewport stays the drag/drop
70
+ // container — containerRef points at it so the indicator's coordinates
71
+ // remain relative to the (scrollable) tab row, not the fixed Root.
72
+ _jsx(ScrollArea, { className: "bg-card/80 border-b border-border/50", viewportRef: viewportRef, children: _jsxs("div", { ref: containerRef, className: "relative flex items-stretch", onDragOver: (e) => {
73
+ // Fallback for empty area past last tab
74
+ if (dragIndex.current === null || !containerRef.current)
75
+ return;
76
+ e.preventDefault();
77
+ e.dataTransfer.dropEffect = "move";
78
+ }, onDrop: (e) => {
79
+ e.preventDefault();
80
+ if (dragIndex.current !== null && dropSlot !== null) {
81
+ const from = dragIndex.current;
82
+ const target = dropSlot > from ? dropSlot - 1 : dropSlot;
83
+ if (target > 0 && target !== from) {
84
+ onTabReorder(from, target);
85
+ }
86
+ }
87
+ clearDrag();
88
+ }, children: [indicatorX !== null && (_jsx("div", { className: "absolute top-0 bottom-0 bg-primary z-10 pointer-events-none", style: { left: 0, width: "2px", transform: `translateX(${indicatorX}px)` } })), tabs.map((tab, index) => {
89
+ const isDraggable = !isMainTab(index);
90
+ return (_jsxs(React.Fragment, { children: [index > 0 && _jsx("div", { className: "w-px bg-border/70 shrink-0" }), _jsxs("div", { draggable: isDraggable, onDragStart: (e) => {
91
+ if (!isDraggable)
92
+ return;
93
+ dragIndex.current = index;
94
+ e.dataTransfer.effectAllowed = "move";
95
+ }, onDragOver: (e) => handleTabDragOver(e, index), onDragEnd: clearDrag, className: cn("group flex items-center gap-1.5 pl-2 pr-1 text-sm font-medium cursor-pointer transition-colors", "hover:bg-field/80", activeTabId === tab.id ? "bg-field text-foreground" : "text-muted-foreground hover:text-foreground", isDraggable ? "cursor-grab active:cursor-grabbing" : "select-none"), onClick: () => onTabChange(tab.id), children: [isMainTab(index) ? (_jsx(Workflow, { className: "w-3.5 h-3.5 shrink-0" })) : (_jsx(FunctionSquare, { className: "w-3.5 h-3.5 shrink-0" })), _jsx("span", { className: "truncate max-w-[120px] py-1", children: tab.label }), tab.id !== MAIN_CANVAS_ID ? (_jsx("button", { type: "button", "aria-label": `Close tab ${tab.label}`, title: `Close tab ${tab.label}`, className: "flex items-center justify-center w-4 h-4 shrink-0 rounded opacity-0 group-hover:opacity-100 transition-opacity hover:bg-destructive/15 hover:text-destructive", onClick: (e) => {
96
+ e.stopPropagation();
97
+ onTabClose(tab.id);
98
+ }, children: _jsx(X, { className: "w-3.5 h-3.5" }) })) : (_jsx("span", { className: "w-1 shrink-0" }))] })] }, tab.id));
99
+ })] }) }));
100
+ };
101
+ //# sourceMappingURL=CanvasTabsToolbar.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CanvasTabsToolbar.js","sourceRoot":"","sources":["../../src/toolbars/CanvasTabsToolbar.tsx"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@foresthubai/workflow-builder",
3
- "version": "0.3.0",
3
+ "version": "0.4.1",
4
4
  "description": "Reusable React component library: the workflow canvas/editor. Imports workflow-core for types and validation.",
5
5
  "license": "AGPL-3.0-only",
6
6
  "repository": {
@@ -41,7 +41,7 @@
41
41
  "tailwindcss": "^3.4.0"
42
42
  },
43
43
  "dependencies": {
44
- "@foresthubai/workflow-core": "0.3.0",
44
+ "@foresthubai/workflow-core": "0.4.1",
45
45
  "@radix-ui/react-alert-dialog": "^1.1.1",
46
46
  "@radix-ui/react-checkbox": "^1.1.1",
47
47
  "@radix-ui/react-collapsible": "^1.1.0",