@mesantosrai/pipeline-canvas 1.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 (148) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +545 -0
  3. package/dist/_virtual/dynamic-import-helper.mjs +17 -0
  4. package/dist/_virtual/dynamic-import-helper.mjs.map +1 -0
  5. package/dist/components/CustomHandle.d.ts +9 -0
  6. package/dist/components/CustomHandle.d.ts.map +1 -0
  7. package/dist/components/CustomHandle.mjs +18 -0
  8. package/dist/components/CustomHandle.mjs.map +1 -0
  9. package/dist/components/ExecutionLogsPanel.d.ts +3 -0
  10. package/dist/components/ExecutionLogsPanel.d.ts.map +1 -0
  11. package/dist/components/ExecutionLogsPanel.mjs +189 -0
  12. package/dist/components/ExecutionLogsPanel.mjs.map +1 -0
  13. package/dist/components/NodeContextMenu.d.ts +15 -0
  14. package/dist/components/NodeContextMenu.d.ts.map +1 -0
  15. package/dist/components/NodeContextMenu.mjs +110 -0
  16. package/dist/components/NodeContextMenu.mjs.map +1 -0
  17. package/dist/components/PipelineCanvas.d.ts +4 -0
  18. package/dist/components/PipelineCanvas.d.ts.map +1 -0
  19. package/dist/components/PipelineCanvas.mjs +1016 -0
  20. package/dist/components/PipelineCanvas.mjs.map +1 -0
  21. package/dist/components/PipelineCanvasProvider.d.ts +30 -0
  22. package/dist/components/PipelineCanvasProvider.d.ts.map +1 -0
  23. package/dist/components/PipelineCanvasProvider.mjs +7 -0
  24. package/dist/components/PipelineCanvasProvider.mjs.map +1 -0
  25. package/dist/components/PipelineExecution.d.ts +16 -0
  26. package/dist/components/PipelineExecution.d.ts.map +1 -0
  27. package/dist/components/PipelineExecution.mjs +310 -0
  28. package/dist/components/PipelineExecution.mjs.map +1 -0
  29. package/dist/components/PipelineManager.d.ts +8 -0
  30. package/dist/components/PipelineManager.d.ts.map +1 -0
  31. package/dist/components/PipelineManager.mjs +143 -0
  32. package/dist/components/PipelineManager.mjs.map +1 -0
  33. package/dist/components/PipelineNodeConfig.d.ts +11 -0
  34. package/dist/components/PipelineNodeConfig.d.ts.map +1 -0
  35. package/dist/components/PipelineNodeConfig.mjs +1808 -0
  36. package/dist/components/PipelineNodeConfig.mjs.map +1 -0
  37. package/dist/components/PipelineNodePalette.d.ts +3 -0
  38. package/dist/components/PipelineNodePalette.d.ts.map +1 -0
  39. package/dist/components/PipelineNodePalette.mjs +87 -0
  40. package/dist/components/PipelineNodePalette.mjs.map +1 -0
  41. package/dist/components/SavePipelineDialog.d.ts +9 -0
  42. package/dist/components/SavePipelineDialog.d.ts.map +1 -0
  43. package/dist/components/SavePipelineDialog.mjs +140 -0
  44. package/dist/components/SavePipelineDialog.mjs.map +1 -0
  45. package/dist/components/SavedPipelinesList.d.ts +3 -0
  46. package/dist/components/SavedPipelinesList.d.ts.map +1 -0
  47. package/dist/components/SavedPipelinesList.mjs +172 -0
  48. package/dist/components/SavedPipelinesList.mjs.map +1 -0
  49. package/dist/components/index.d.ts +8 -0
  50. package/dist/components/index.d.ts.map +1 -0
  51. package/dist/components/ui/alert.d.ts +9 -0
  52. package/dist/components/ui/alert.d.ts.map +1 -0
  53. package/dist/components/ui/alert.mjs +51 -0
  54. package/dist/components/ui/alert.mjs.map +1 -0
  55. package/dist/components/ui/button.d.ts +12 -0
  56. package/dist/components/ui/button.d.ts.map +1 -0
  57. package/dist/components/ui/button.mjs +45 -0
  58. package/dist/components/ui/button.mjs.map +1 -0
  59. package/dist/components/ui/dialog.d.ts +20 -0
  60. package/dist/components/ui/dialog.d.ts.map +1 -0
  61. package/dist/components/ui/dialog.mjs +99 -0
  62. package/dist/components/ui/dialog.mjs.map +1 -0
  63. package/dist/components/ui/index.d.ts +8 -0
  64. package/dist/components/ui/index.d.ts.map +1 -0
  65. package/dist/components/ui/input.d.ts +6 -0
  66. package/dist/components/ui/input.d.ts.map +1 -0
  67. package/dist/components/ui/input.mjs +22 -0
  68. package/dist/components/ui/input.mjs.map +1 -0
  69. package/dist/components/ui/label.d.ts +6 -0
  70. package/dist/components/ui/label.d.ts.map +1 -0
  71. package/dist/components/ui/label.mjs +20 -0
  72. package/dist/components/ui/label.mjs.map +1 -0
  73. package/dist/components/ui/select.d.ts +14 -0
  74. package/dist/components/ui/select.d.ts.map +1 -0
  75. package/dist/components/ui/select.mjs +121 -0
  76. package/dist/components/ui/select.mjs.map +1 -0
  77. package/dist/components/ui/tooltip.d.ts +8 -0
  78. package/dist/components/ui/tooltip.d.ts.map +1 -0
  79. package/dist/components/ui/tooltip.mjs +24 -0
  80. package/dist/components/ui/tooltip.mjs.map +1 -0
  81. package/dist/context/PipelineContext.d.ts +50 -0
  82. package/dist/context/PipelineContext.d.ts.map +1 -0
  83. package/dist/context/PipelineContext.mjs +36 -0
  84. package/dist/context/PipelineContext.mjs.map +1 -0
  85. package/dist/index.d.ts +12 -0
  86. package/dist/index.d.ts.map +1 -0
  87. package/dist/index.mjs +45 -0
  88. package/dist/index.mjs.map +1 -0
  89. package/dist/lib/utils.d.ts +3 -0
  90. package/dist/lib/utils.d.ts.map +1 -0
  91. package/dist/lib/utils.mjs +9 -0
  92. package/dist/lib/utils.mjs.map +1 -0
  93. package/dist/node_modules/zustand/esm/middleware.mjs +256 -0
  94. package/dist/node_modules/zustand/esm/middleware.mjs.map +1 -0
  95. package/dist/nodes/alphafold_node/node.json.mjs +82 -0
  96. package/dist/nodes/alphafold_node/node.json.mjs.map +1 -0
  97. package/dist/nodes/http_request_node/node.json.mjs +383 -0
  98. package/dist/nodes/http_request_node/node.json.mjs.map +1 -0
  99. package/dist/nodes/input_node/node.json.mjs +51 -0
  100. package/dist/nodes/input_node/node.json.mjs.map +1 -0
  101. package/dist/nodes/message_input_node/node.json.mjs +90 -0
  102. package/dist/nodes/message_input_node/node.json.mjs.map +1 -0
  103. package/dist/nodes/proteinmpnn_node/node.json.mjs +83 -0
  104. package/dist/nodes/proteinmpnn_node/node.json.mjs.map +1 -0
  105. package/dist/nodes/rfdiffusion_node/node.json.mjs +281 -0
  106. package/dist/nodes/rfdiffusion_node/node.json.mjs.map +1 -0
  107. package/dist/store/pipelineStore.d.ts +108 -0
  108. package/dist/store/pipelineStore.d.ts.map +1 -0
  109. package/dist/store/pipelineStore.mjs +633 -0
  110. package/dist/store/pipelineStore.mjs.map +1 -0
  111. package/dist/style.css +1 -0
  112. package/dist/types/dependencies.d.ts +93 -0
  113. package/dist/types/dependencies.d.ts.map +1 -0
  114. package/dist/types/index.d.ts +56 -0
  115. package/dist/types/index.d.ts.map +1 -0
  116. package/dist/types/logger.d.ts +67 -0
  117. package/dist/types/logger.d.ts.map +1 -0
  118. package/dist/types/logger.mjs +22 -0
  119. package/dist/types/logger.mjs.map +1 -0
  120. package/dist/utils/executionEngine.d.ts +27 -0
  121. package/dist/utils/executionEngine.d.ts.map +1 -0
  122. package/dist/utils/executionEngine.mjs +461 -0
  123. package/dist/utils/executionEngine.mjs.map +1 -0
  124. package/dist/utils/index.d.ts +6 -0
  125. package/dist/utils/index.d.ts.map +1 -0
  126. package/dist/utils/logger.d.ts +23 -0
  127. package/dist/utils/logger.d.ts.map +1 -0
  128. package/dist/utils/logger.mjs +29 -0
  129. package/dist/utils/logger.mjs.map +1 -0
  130. package/dist/utils/nodeLoader.d.ts +76 -0
  131. package/dist/utils/nodeLoader.d.ts.map +1 -0
  132. package/dist/utils/nodeLoader.mjs +48 -0
  133. package/dist/utils/nodeLoader.mjs.map +1 -0
  134. package/dist/utils/templateResolver.d.ts +10 -0
  135. package/dist/utils/templateResolver.d.ts.map +1 -0
  136. package/dist/utils/templateResolver.mjs +64 -0
  137. package/dist/utils/templateResolver.mjs.map +1 -0
  138. package/dist/utils/topologicalSort.d.ts +10 -0
  139. package/dist/utils/topologicalSort.d.ts.map +1 -0
  140. package/dist/utils/topologicalSort.mjs +25 -0
  141. package/dist/utils/topologicalSort.mjs.map +1 -0
  142. package/nodes/alphafold_node/node.json +77 -0
  143. package/nodes/http_request_node/node.json +311 -0
  144. package/nodes/input_node/node.json +47 -0
  145. package/nodes/message_input_node/node.json +56 -0
  146. package/nodes/proteinmpnn_node/node.json +78 -0
  147. package/nodes/rfdiffusion_node/node.json +231 -0
  148. package/package.json +94 -0
@@ -0,0 +1,1016 @@
1
+ import { jsxs as o, jsx as t, Fragment as F } from "react/jsx-runtime";
2
+ import h, { useMemo as oe, useCallback as v, useRef as Ae, useState as Re, useEffect as Pe } from "react";
3
+ import De, { MarkerType as tt, useNodesState as st, useEdgesState as nt, addEdge as Ie, Background as Le, BackgroundVariant as Oe, Controls as $e, MiniMap as rt, Position as S } from "reactflow";
4
+ /* empty css */
5
+ import { usePipelineStore as ot } from "../store/pipelineStore.mjs";
6
+ import { usePipelineContext as lt } from "../context/PipelineContext.mjs";
7
+ import { PipelineNodeConfig as it } from "./PipelineNodeConfig.mjs";
8
+ import { PipelineNodePalette as at } from "./PipelineNodePalette.mjs";
9
+ import { SavedPipelinesList as ct } from "./SavedPipelinesList.mjs";
10
+ import { SavePipelineDialog as dt } from "./SavePipelineDialog.mjs";
11
+ import { ExecutionLogsPanel as ut } from "./ExecutionLogsPanel.mjs";
12
+ import { CustomHandle as E } from "./CustomHandle.mjs";
13
+ import { NodeContextMenu as gt } from "./NodeContextMenu.mjs";
14
+ import { Loader2 as O, CheckCircle2 as f, Plus as ht, XCircle as $, Square as mt, Play as pt, Save as ft, Trash2 as xt, Sparkles as Ue, Globe as bt, AlertCircle as Z, MessageSquare as wt, Atom as Nt, Dna as vt, FileInput as yt } from "lucide-react";
15
+ const z = (e, n, d) => {
16
+ if (d)
17
+ return "border-green-500 shadow-[0_0_10px_rgba(34,197,94,0.3)]";
18
+ switch (e) {
19
+ case "running":
20
+ return "border-blue-500 shadow-[0_0_15px_rgba(59,130,246,0.5)] animate-pulse-glow";
21
+ case "success":
22
+ case "completed":
23
+ return "border-green-500 shadow-[0_0_10px_rgba(34,197,94,0.3)]";
24
+ case "error":
25
+ return "border-red-500 shadow-[0_0_10px_rgba(239,68,68,0.3)]";
26
+ case "pending":
27
+ return n ? "border-gray-300 opacity-60" : "border-gray-300";
28
+ default:
29
+ return "border-gray-300";
30
+ }
31
+ }, H = ({ label: e, nodeId: n, onUpdate: d }) => {
32
+ const [c, m] = Re(!1), [p, u] = Re(e), b = Ae(null);
33
+ Pe(() => {
34
+ c && b.current && (b.current.focus(), b.current.select());
35
+ }, [c]), Pe(() => {
36
+ u(e);
37
+ }, [e]);
38
+ const y = () => {
39
+ m(!0);
40
+ }, j = () => {
41
+ p.trim() !== e && d(n, p.trim() || e), m(!1);
42
+ }, A = (C) => {
43
+ C.key === "Enter" ? (C.preventDefault(), j()) : C.key === "Escape" && (u(e), m(!1));
44
+ };
45
+ return c ? /* @__PURE__ */ t(
46
+ "input",
47
+ {
48
+ ref: b,
49
+ type: "text",
50
+ value: p,
51
+ onChange: (C) => u(C.target.value),
52
+ onBlur: j,
53
+ onKeyDown: A,
54
+ className: "w-full text-center text-xs font-medium text-white bg-gray-700/80 border border-gray-500 rounded px-2 py-1 outline-none focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
55
+ onClick: (C) => C.stopPropagation(),
56
+ onDoubleClick: (C) => C.stopPropagation()
57
+ }
58
+ ) : /* @__PURE__ */ t(
59
+ "div",
60
+ {
61
+ onDoubleClick: y,
62
+ className: "text-center text-xs font-medium text-gray-200 cursor-text hover:text-white transition-colors px-1 py-0.5 rounded hover:bg-gray-800/50",
63
+ title: "Double-click to edit",
64
+ children: e || "Unnamed"
65
+ }
66
+ );
67
+ }, Ct = ({ data: e }) => {
68
+ var b;
69
+ const n = e.status, d = e.isExecuting, c = Ae(0), m = n === "completed" || n === "success" || e.result_metadata && Object.keys(e.result_metadata).length > 0;
70
+ h.useEffect(() => {
71
+ e.id && (n === "completed" || n === "success" || e.result_metadata && Object.keys(e.result_metadata).length > 0) && console.log("[InputNode] Status check:", {
72
+ nodeId: e.id,
73
+ status: n,
74
+ hasResultMetadata: !!(e.result_metadata && Object.keys(e.result_metadata).length > 0),
75
+ isCompleted: m,
76
+ resultMetadataKeys: e.result_metadata ? Object.keys(e.result_metadata) : []
77
+ });
78
+ }, [e.id, n, e.result_metadata, m]);
79
+ const p = () => {
80
+ if (m)
81
+ return /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" });
82
+ switch (n) {
83
+ case "running":
84
+ return /* @__PURE__ */ o("div", { className: "relative", children: [
85
+ /* @__PURE__ */ t(O, { className: "w-4 h-4 animate-spin text-blue-500" }),
86
+ /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-blue-400/30 rounded-full animate-ping" })
87
+ ] });
88
+ case "error":
89
+ return /* @__PURE__ */ t($, { className: "w-4 h-4 text-red-500" });
90
+ default:
91
+ return e.result_metadata && Object.keys(e.result_metadata).length > 0 ? /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" }) : null;
92
+ }
93
+ }, u = (y) => {
94
+ const j = Date.now(), A = j - c.current;
95
+ c.current = j, A > 300 && y.stopPropagation();
96
+ };
97
+ return /* @__PURE__ */ o("div", { className: "flex flex-col items-center", children: [
98
+ /* @__PURE__ */ o(
99
+ "div",
100
+ {
101
+ className: `
102
+ px-4 py-3 bg-white border-2 rounded-xl min-w-[220px] relative transition-all duration-300
103
+ ${z(n, d, !!(e.result_metadata && Object.keys(e.result_metadata).length > 0))}
104
+ `,
105
+ onClick: u,
106
+ onDoubleClick: () => {
107
+ },
108
+ children: [
109
+ /* @__PURE__ */ t(E, { type: "source", position: S.Right }),
110
+ /* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-2", children: [
111
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
112
+ /* @__PURE__ */ t("div", { className: `w-8 h-8 rounded-lg flex items-center justify-center ${n === "running" ? "bg-blue-100" : m ? "bg-green-100" : n === "error" ? "bg-red-100" : "bg-blue-100"}`, children: /* @__PURE__ */ t(yt, { className: `w-4 h-4 ${n === "running" ? "text-blue-600" : m ? "text-green-600" : n === "error" ? "text-red-600" : "text-blue-600"}` }) }),
113
+ /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-gray-900", children: "Input" })
114
+ ] }),
115
+ p()
116
+ ] }),
117
+ /* @__PURE__ */ t("div", { className: "text-xs text-gray-500 pl-10", children: ((b = e.config) == null ? void 0 : b.filename) || "No file selected" }),
118
+ (n === "success" || n === "completed" || e.result_metadata && Object.keys(e.result_metadata).length > 0) && /* @__PURE__ */ t("div", { className: "absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center shadow-lg z-10", children: /* @__PURE__ */ t(f, { className: "w-3 h-3 text-white" }) })
119
+ ]
120
+ }
121
+ ),
122
+ /* @__PURE__ */ t("div", { className: "mt-1 w-full", onClick: (y) => y.stopPropagation(), children: /* @__PURE__ */ t(
123
+ H,
124
+ {
125
+ label: e.label || "Input",
126
+ nodeId: e.id,
127
+ onUpdate: e.onUpdateLabel || (() => {
128
+ })
129
+ }
130
+ ) })
131
+ ] });
132
+ }, kt = ({ data: e }) => {
133
+ var p;
134
+ const n = e.status, d = e.isExecuting, c = n === "completed" || n === "success" || e.result_metadata && Object.keys(e.result_metadata).length > 0, m = () => {
135
+ if (c)
136
+ return /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" });
137
+ switch (n) {
138
+ case "running":
139
+ return /* @__PURE__ */ o("div", { className: "relative", children: [
140
+ /* @__PURE__ */ t(O, { className: "w-4 h-4 animate-spin text-blue-500" }),
141
+ /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-blue-400/30 rounded-full animate-ping" })
142
+ ] });
143
+ case "error":
144
+ return /* @__PURE__ */ t($, { className: "w-4 h-4 text-red-500" });
145
+ default:
146
+ return e.result_metadata && Object.keys(e.result_metadata).length > 0 ? /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" }) : null;
147
+ }
148
+ };
149
+ return /* @__PURE__ */ o("div", { className: "flex flex-col items-center", children: [
150
+ /* @__PURE__ */ o(
151
+ "div",
152
+ {
153
+ className: `
154
+ px-4 py-3 bg-white border-2 rounded-xl min-w-[220px] relative transition-all duration-300
155
+ ${z(n, d, !!(e.result_metadata && Object.keys(e.result_metadata).length > 0))}
156
+ `,
157
+ onClick: (u) => u.stopPropagation(),
158
+ children: [
159
+ /* @__PURE__ */ t(E, { type: "target", position: S.Left }),
160
+ /* @__PURE__ */ t(E, { type: "source", position: S.Right }),
161
+ /* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-2", children: [
162
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
163
+ /* @__PURE__ */ t("div", { className: `w-8 h-8 rounded-lg flex items-center justify-center ${n === "running" ? "bg-blue-100" : c ? "bg-green-100" : n === "error" ? "bg-red-100" : "bg-purple-100"}`, children: /* @__PURE__ */ t(Ue, { className: `w-4 h-4 ${n === "running" ? "text-blue-600" : c ? "text-green-600" : n === "error" ? "text-red-600" : "text-purple-600"}` }) }),
164
+ /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-gray-900", children: "RFdiffusion" })
165
+ ] }),
166
+ m()
167
+ ] }),
168
+ /* @__PURE__ */ o("div", { className: "text-xs text-gray-500 space-y-1 pl-10", children: [
169
+ /* @__PURE__ */ o("div", { children: [
170
+ "Contigs: ",
171
+ ((p = e.config) == null ? void 0 : p.contigs) || "N/A"
172
+ ] }),
173
+ e.error && /* @__PURE__ */ o("div", { className: "text-red-600 flex items-center gap-1", children: [
174
+ /* @__PURE__ */ t(Z, { className: "w-3 h-3" }),
175
+ e.error
176
+ ] })
177
+ ] }),
178
+ (n === "success" || n === "completed" || e.result_metadata && Object.keys(e.result_metadata).length > 0) && /* @__PURE__ */ t("div", { className: "absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center shadow-lg z-10", children: /* @__PURE__ */ t(f, { className: "w-3 h-3 text-white" }) })
179
+ ]
180
+ }
181
+ ),
182
+ /* @__PURE__ */ t("div", { className: "mt-1 w-full", onClick: (u) => u.stopPropagation(), children: /* @__PURE__ */ t(
183
+ H,
184
+ {
185
+ label: e.label || "RFdiffusion",
186
+ nodeId: e.id,
187
+ onUpdate: e.onUpdateLabel || (() => {
188
+ })
189
+ }
190
+ ) })
191
+ ] });
192
+ }, _t = ({ data: e }) => {
193
+ var p;
194
+ const n = e.status, d = e.isExecuting, c = n === "completed" || n === "success" || e.result_metadata && Object.keys(e.result_metadata).length > 0, m = () => {
195
+ if (c)
196
+ return /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" });
197
+ switch (n) {
198
+ case "running":
199
+ return /* @__PURE__ */ o("div", { className: "relative", children: [
200
+ /* @__PURE__ */ t(O, { className: "w-4 h-4 animate-spin text-blue-500" }),
201
+ /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-blue-400/30 rounded-full animate-ping" })
202
+ ] });
203
+ case "error":
204
+ return /* @__PURE__ */ t($, { className: "w-4 h-4 text-red-500" });
205
+ default:
206
+ return e.result_metadata && Object.keys(e.result_metadata).length > 0 ? /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" }) : null;
207
+ }
208
+ };
209
+ return /* @__PURE__ */ o("div", { className: "flex flex-col items-center", children: [
210
+ /* @__PURE__ */ o(
211
+ "div",
212
+ {
213
+ className: `
214
+ px-4 py-3 bg-white border-2 rounded-xl min-w-[220px] relative transition-all duration-300
215
+ ${z(n, d, !!(e.result_metadata && Object.keys(e.result_metadata).length > 0))}
216
+ `,
217
+ onClick: (u) => u.stopPropagation(),
218
+ children: [
219
+ /* @__PURE__ */ t(E, { type: "target", position: S.Left }),
220
+ /* @__PURE__ */ t(E, { type: "source", position: S.Right }),
221
+ /* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-2", children: [
222
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
223
+ /* @__PURE__ */ t("div", { className: `w-8 h-8 rounded-lg flex items-center justify-center ${n === "running" ? "bg-blue-100" : c ? "bg-green-100" : n === "error" ? "bg-red-100" : "bg-green-100"}`, children: /* @__PURE__ */ t(vt, { className: `w-4 h-4 ${n === "running" ? "text-blue-600" : c ? "text-green-600" : n === "error" ? "text-red-600" : "text-green-600"}` }) }),
224
+ /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-gray-900", children: "ProteinMPNN" })
225
+ ] }),
226
+ m()
227
+ ] }),
228
+ /* @__PURE__ */ o("div", { className: "text-xs text-gray-500 space-y-1 pl-10", children: [
229
+ /* @__PURE__ */ o("div", { children: [
230
+ "Sequences: ",
231
+ ((p = e.config) == null ? void 0 : p.num_sequences) || "N/A"
232
+ ] }),
233
+ e.error && /* @__PURE__ */ o("div", { className: "text-red-600 flex items-center gap-1", children: [
234
+ /* @__PURE__ */ t(Z, { className: "w-3 h-3" }),
235
+ e.error
236
+ ] })
237
+ ] }),
238
+ (n === "success" || n === "completed" || e.result_metadata && Object.keys(e.result_metadata).length > 0) && /* @__PURE__ */ t("div", { className: "absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center shadow-lg z-10", children: /* @__PURE__ */ t(f, { className: "w-3 h-3 text-white" }) })
239
+ ]
240
+ }
241
+ ),
242
+ /* @__PURE__ */ t("div", { className: "mt-1 w-full", onClick: (u) => u.stopPropagation(), children: /* @__PURE__ */ t(
243
+ H,
244
+ {
245
+ label: e.label || "ProteinMPNN",
246
+ nodeId: e.id,
247
+ onUpdate: e.onUpdateLabel || (() => {
248
+ })
249
+ }
250
+ ) })
251
+ ] });
252
+ }, Mt = ({ data: e }) => {
253
+ var p;
254
+ const n = e.status, d = e.isExecuting, c = n === "completed" || n === "success" || e.result_metadata && Object.keys(e.result_metadata).length > 0, m = () => {
255
+ if (c)
256
+ return /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" });
257
+ switch (n) {
258
+ case "running":
259
+ return /* @__PURE__ */ o("div", { className: "relative", children: [
260
+ /* @__PURE__ */ t(O, { className: "w-4 h-4 animate-spin text-blue-500" }),
261
+ /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-blue-400/30 rounded-full animate-ping" })
262
+ ] });
263
+ case "error":
264
+ return /* @__PURE__ */ t($, { className: "w-4 h-4 text-red-500" });
265
+ default:
266
+ return e.result_metadata && Object.keys(e.result_metadata).length > 0 ? /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" }) : null;
267
+ }
268
+ };
269
+ return /* @__PURE__ */ o("div", { className: "flex flex-col items-center", children: [
270
+ /* @__PURE__ */ o(
271
+ "div",
272
+ {
273
+ className: `
274
+ px-4 py-3 bg-white border-2 rounded-xl min-w-[220px] relative transition-all duration-300
275
+ ${z(n, d, !!(e.result_metadata && Object.keys(e.result_metadata).length > 0))}
276
+ `,
277
+ onClick: (u) => u.stopPropagation(),
278
+ children: [
279
+ /* @__PURE__ */ t(E, { type: "target", position: S.Left }),
280
+ /* @__PURE__ */ t(E, { type: "source", position: S.Right }),
281
+ /* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-2", children: [
282
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
283
+ /* @__PURE__ */ t("div", { className: `w-8 h-8 rounded-lg flex items-center justify-center ${n === "running" ? "bg-blue-100" : c ? "bg-green-100" : n === "error" ? "bg-red-100" : "bg-orange-100"}`, children: /* @__PURE__ */ t(Nt, { className: `w-4 h-4 ${n === "running" ? "text-blue-600" : c ? "text-green-600" : n === "error" ? "text-red-600" : "text-orange-600"}` }) }),
284
+ /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-gray-900", children: "AlphaFold" })
285
+ ] }),
286
+ m()
287
+ ] }),
288
+ /* @__PURE__ */ o("div", { className: "text-xs text-gray-500 space-y-1 pl-10", children: [
289
+ /* @__PURE__ */ o("div", { children: [
290
+ "Recycles: ",
291
+ ((p = e.config) == null ? void 0 : p.recycle_count) || "N/A"
292
+ ] }),
293
+ e.error && /* @__PURE__ */ o("div", { className: "text-red-600 flex items-center gap-1", children: [
294
+ /* @__PURE__ */ t(Z, { className: "w-3 h-3" }),
295
+ e.error
296
+ ] })
297
+ ] }),
298
+ (n === "success" || n === "completed" || e.result_metadata && Object.keys(e.result_metadata).length > 0) && /* @__PURE__ */ t("div", { className: "absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center shadow-lg z-10", children: /* @__PURE__ */ t(f, { className: "w-3 h-3 text-white" }) })
299
+ ]
300
+ }
301
+ ),
302
+ /* @__PURE__ */ t("div", { className: "mt-1 w-full", onClick: (u) => u.stopPropagation(), children: /* @__PURE__ */ t(
303
+ H,
304
+ {
305
+ label: e.label || "AlphaFold",
306
+ nodeId: e.id,
307
+ onUpdate: e.onUpdateLabel || (() => {
308
+ })
309
+ }
310
+ ) })
311
+ ] });
312
+ }, St = ({ data: e }) => {
313
+ var u;
314
+ const n = e.status, d = e.isExecuting, c = n === "completed" || n === "success" || e.result_metadata && Object.keys(e.result_metadata).length > 0, m = () => {
315
+ if (c)
316
+ return /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" });
317
+ switch (n) {
318
+ case "running":
319
+ return /* @__PURE__ */ o("div", { className: "relative", children: [
320
+ /* @__PURE__ */ t(O, { className: "w-4 h-4 animate-spin text-blue-500" }),
321
+ /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-blue-400/30 rounded-full animate-ping" })
322
+ ] });
323
+ case "error":
324
+ return /* @__PURE__ */ t($, { className: "w-4 h-4 text-red-500" });
325
+ default:
326
+ return e.result_metadata && Object.keys(e.result_metadata).length > 0 ? /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" }) : null;
327
+ }
328
+ }, p = (u = e.config) != null && u.code ? e.config.code.length > 40 ? e.config.code.substring(0, 40).replace(/\n/g, " ") + "..." : e.config.code.replace(/\n/g, " ") : "No code";
329
+ return /* @__PURE__ */ o("div", { className: "flex flex-col items-center", children: [
330
+ /* @__PURE__ */ o(
331
+ "div",
332
+ {
333
+ className: `
334
+ px-4 py-3 bg-white border-2 rounded-xl min-w-[220px] relative transition-all duration-300
335
+ ${z(n, d, !!(e.result_metadata && Object.keys(e.result_metadata).length > 0))}
336
+ `,
337
+ onClick: (b) => b.stopPropagation(),
338
+ children: [
339
+ /* @__PURE__ */ t(E, { type: "source", position: S.Right }),
340
+ /* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-2", children: [
341
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
342
+ /* @__PURE__ */ t("div", { className: `w-8 h-8 rounded-lg flex items-center justify-center ${n === "running" ? "bg-blue-100" : c ? "bg-green-100" : n === "error" ? "bg-red-100" : "bg-green-100"}`, children: /* @__PURE__ */ t(wt, { className: `w-4 h-4 ${n === "running" ? "text-blue-600" : c ? "text-green-600" : n === "error" ? "text-red-600" : "text-green-600"}` }) }),
343
+ /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-gray-900", children: "Code Execution" })
344
+ ] }),
345
+ m()
346
+ ] }),
347
+ /* @__PURE__ */ t("div", { className: "text-xs text-gray-500 pl-10 font-mono", children: p }),
348
+ (n === "success" || n === "completed" || e.result_metadata && Object.keys(e.result_metadata).length > 0) && /* @__PURE__ */ t("div", { className: "absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center shadow-lg z-10", children: /* @__PURE__ */ t(f, { className: "w-3 h-3 text-white" }) })
349
+ ]
350
+ }
351
+ ),
352
+ /* @__PURE__ */ t("div", { className: "mt-1 w-full", onClick: (b) => b.stopPropagation(), children: /* @__PURE__ */ t(
353
+ H,
354
+ {
355
+ label: e.label || "Code Execution",
356
+ nodeId: e.id,
357
+ onUpdate: e.onUpdateLabel || (() => {
358
+ })
359
+ }
360
+ ) })
361
+ ] });
362
+ }, Et = ({ data: e }) => {
363
+ var u, b;
364
+ const n = e.status, d = e.isExecuting, c = n === "completed" || n === "success" || e.result_metadata && Object.keys(e.result_metadata).length > 0, m = () => {
365
+ if (c)
366
+ return /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" });
367
+ switch (n) {
368
+ case "running":
369
+ return /* @__PURE__ */ o("div", { className: "relative", children: [
370
+ /* @__PURE__ */ t(O, { className: "w-4 h-4 animate-spin text-blue-500" }),
371
+ /* @__PURE__ */ t("div", { className: "absolute inset-0 bg-blue-400/30 rounded-full animate-ping" })
372
+ ] });
373
+ case "error":
374
+ return /* @__PURE__ */ t($, { className: "w-4 h-4 text-red-500" });
375
+ default:
376
+ return e.result_metadata && Object.keys(e.result_metadata).length > 0 ? /* @__PURE__ */ t(f, { className: "w-4 h-4 text-green-500" }) : null;
377
+ }
378
+ }, p = (u = e.config) != null && u.url ? e.config.url.length > 30 ? e.config.url.substring(0, 30) + "..." : e.config.url : "No URL";
379
+ return /* @__PURE__ */ o("div", { className: "flex flex-col items-center", children: [
380
+ /* @__PURE__ */ o(
381
+ "div",
382
+ {
383
+ className: `
384
+ px-4 py-3 bg-white border-2 rounded-xl min-w-[220px] relative transition-all duration-300
385
+ ${z(n, d, !!(e.result_metadata && Object.keys(e.result_metadata).length > 0))}
386
+ `,
387
+ onClick: (y) => y.stopPropagation(),
388
+ children: [
389
+ /* @__PURE__ */ t(E, { type: "target", position: S.Left }),
390
+ /* @__PURE__ */ t(E, { type: "source", position: S.Right }),
391
+ /* @__PURE__ */ o("div", { className: "flex items-center justify-between mb-2", children: [
392
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
393
+ /* @__PURE__ */ t("div", { className: `w-8 h-8 rounded-lg flex items-center justify-center ${n === "running" ? "bg-blue-100" : c ? "bg-green-100" : n === "error" ? "bg-red-100" : "bg-blue-100"}`, children: /* @__PURE__ */ t(bt, { className: `w-4 h-4 ${n === "running" ? "text-blue-600" : c ? "text-green-600" : n === "error" ? "text-red-600" : "text-blue-600"}` }) }),
394
+ /* @__PURE__ */ t("span", { className: "font-semibold text-sm text-gray-900", children: "HTTP Request" })
395
+ ] }),
396
+ m()
397
+ ] }),
398
+ /* @__PURE__ */ o("div", { className: "text-xs text-gray-500 space-y-1 pl-10", children: [
399
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
400
+ /* @__PURE__ */ t("span", { className: "font-medium", children: ((b = e.config) == null ? void 0 : b.method) || "GET" }),
401
+ /* @__PURE__ */ t("span", { className: "text-gray-400", children: "•" }),
402
+ /* @__PURE__ */ t("span", { className: "truncate", children: p })
403
+ ] }),
404
+ e.error && /* @__PURE__ */ o("div", { className: "text-red-600 flex items-center gap-1", children: [
405
+ /* @__PURE__ */ t(Z, { className: "w-3 h-3" }),
406
+ e.error
407
+ ] })
408
+ ] }),
409
+ (n === "success" || n === "completed" || e.result_metadata && Object.keys(e.result_metadata).length > 0) && /* @__PURE__ */ t("div", { className: "absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center shadow-lg z-10", children: /* @__PURE__ */ t(f, { className: "w-3 h-3 text-white" }) })
410
+ ]
411
+ }
412
+ ),
413
+ /* @__PURE__ */ t("div", { className: "mt-1 w-full", onClick: (y) => y.stopPropagation(), children: /* @__PURE__ */ t(
414
+ H,
415
+ {
416
+ label: e.label || "HTTP Request",
417
+ nodeId: e.id,
418
+ onUpdate: e.onUpdateLabel || (() => {
419
+ })
420
+ }
421
+ ) })
422
+ ] });
423
+ }, jt = Object.freeze({
424
+ input_node: Ct,
425
+ rfdiffusion_node: kt,
426
+ proteinmpnn_node: _t,
427
+ alphafold_node: Mt,
428
+ message_input_node: St,
429
+ http_request_node: Et
430
+ }), Vt = () => {
431
+ const {
432
+ currentPipeline: e,
433
+ ghostBlueprint: n,
434
+ isExecuting: d,
435
+ viewMode: c,
436
+ setViewMode: m,
437
+ approveBlueprint: p,
438
+ rejectBlueprint: u,
439
+ updateNode: b,
440
+ deleteNode: y,
441
+ addNode: j,
442
+ addEdge: A,
443
+ startExecution: C,
444
+ stopExecution: Be,
445
+ clearPipeline: Fe,
446
+ lastSavedAt: le,
447
+ isSaving: ze,
448
+ setCurrentPipeline: ie,
449
+ syncPipelines: ae
450
+ } = ot(), { authState: X, apiClient: ee } = lt(), ce = X == null ? void 0 : X.user;
451
+ h.useEffect(() => {
452
+ ce && ee && (console.log("[PipelineCanvas] Syncing pipelines from backend..."), ae({ apiClient: ee, authState: X }).catch((s) => {
453
+ console.error("[PipelineCanvas] Failed to sync pipelines:", s);
454
+ }));
455
+ }, [ce, ee, X, ae]);
456
+ const de = oe(() => jt, []), [L, R] = h.useState(null), [ue, He] = h.useState(!1), [Xe, ge] = h.useState(!1), he = h.useRef(null), J = h.useRef(!1);
457
+ h.useEffect(() => {
458
+ const s = (e == null ? void 0 : e.id) || null, r = s !== he.current;
459
+ if (e && e.nodes.length > 0 && r && J.current && !L && c === "editor") {
460
+ const i = e.nodes.find((g) => g.type === "input_node") || e.nodes[0];
461
+ i && (console.log("[PipelineCanvas] Auto-selecting first node for configuration:", i.id, i.type), setTimeout(() => {
462
+ R(i.id);
463
+ }, 100)), J.current = !1;
464
+ } else r && !J.current && L && R(null);
465
+ he.current = s;
466
+ }, [e == null ? void 0 : e.id, e == null ? void 0 : e.nodes.length, L, c]), h.useEffect(() => {
467
+ const s = () => {
468
+ console.log("[PipelineCanvas] Blueprint approved, will auto-select first node"), J.current = !0;
469
+ };
470
+ return window.addEventListener("blueprint-approved", s), () => {
471
+ window.removeEventListener("blueprint-approved", s);
472
+ };
473
+ }, []);
474
+ const [x, me] = h.useState(null), [q, pe] = h.useState({ right: 16, top: 80 }), [P, qe] = h.useState({ width: 900, height: 600 }), [V, fe] = h.useState(!1), [W, xe] = h.useState(!1), [l, be] = h.useState(null), [te, Ve] = h.useState({ x: 0, y: 0 }), [w, We] = h.useState({ x: 0, y: 0, width: 0, height: 0, right: 0, top: 0 }), k = h.useRef(null), Ye = v((s) => {
475
+ const r = s.target;
476
+ if (!(r.tagName === "BUTTON" || r.tagName === "INPUT" || r.tagName === "SELECT" || r.tagName === "TEXTAREA" || r.closest("button") || r.closest("input") || r.closest("select") || r.closest("textarea") || r.closest('[role="button"]') || r.closest('[class*="cursor-col-resize"]') || r.closest('[class*="cursor-row-resize"]') || r.closest('[class*="cursor-nwse-resize"]') || r.closest('[class*="cursor-nesw-resize"]')) && k.current) {
477
+ fe(!0);
478
+ const a = k.current.getBoundingClientRect();
479
+ Ve({
480
+ x: s.clientX - a.left,
481
+ y: s.clientY - a.top
482
+ }), s.preventDefault();
483
+ }
484
+ }, []), se = v((s) => {
485
+ var r, a;
486
+ if (W && k.current) {
487
+ const i = (r = k.current.parentElement) == null ? void 0 : r.getBoundingClientRect();
488
+ if (i) {
489
+ const g = s.clientX - w.x, N = s.clientY - w.y;
490
+ let _ = w.width, M = w.height, I = w.right, B = w.top;
491
+ l != null && l.includes("width-right") || l != null && l.includes("both-bottom-right") || l != null && l.includes("both-top-right") ? _ = Math.max(400, Math.min(1200, w.width + g)) : (l != null && l.includes("width-left") || l != null && l.includes("both-bottom-left") || l != null && l.includes("both-top-left")) && (_ = Math.max(400, Math.min(1200, w.width - g)), I = w.right + (w.width - _), I = Math.max(0, Math.min(i.width - _, I))), l != null && l.includes("height-bottom") || l != null && l.includes("both-bottom-right") || l != null && l.includes("both-bottom-left") ? M = Math.max(300, Math.min(i.height - w.top, w.height + N)) : (l != null && l.includes("height-top") || l != null && l.includes("both-top-right") || l != null && l.includes("both-top-left")) && (M = Math.max(300, Math.min(i.height - w.top, w.height - N)), B = w.top + (w.height - M), B = Math.max(0, Math.min(i.height - M, B))), qe({ width: _, height: M }), pe({ right: I, top: B });
492
+ }
493
+ } else if (V && k.current) {
494
+ const i = (a = k.current.parentElement) == null ? void 0 : a.getBoundingClientRect();
495
+ if (i) {
496
+ const g = s.clientX - i.left - te.x, N = s.clientY - i.top - te.y, _ = i.width - g - P.width, M = 0, I = i.width - P.width, B = 0, et = i.height - 100;
497
+ pe({
498
+ right: Math.max(M, Math.min(_, I)),
499
+ top: Math.max(B, Math.min(N, et))
500
+ });
501
+ }
502
+ }
503
+ }, [V, W, te, w, l, P.width]), ne = v(() => {
504
+ fe(!1), xe(!1), be(null);
505
+ }, []), D = v((s, r) => {
506
+ var a;
507
+ if (s.preventDefault(), s.stopPropagation(), k.current) {
508
+ xe(!0), be(r);
509
+ const i = k.current.getBoundingClientRect();
510
+ if ((a = k.current.parentElement) == null ? void 0 : a.getBoundingClientRect()) {
511
+ let N = s.clientX;
512
+ r.includes("width-left") || r.includes("both-bottom-left") || r.includes("both-top-left") ? N = i.left : (r.includes("width-right") || r.includes("both-bottom-right") || r.includes("both-top-right")) && (N = i.right), We({
513
+ x: N,
514
+ y: s.clientY,
515
+ width: P.width,
516
+ height: P.height,
517
+ right: q.right,
518
+ top: q.top
519
+ });
520
+ }
521
+ }
522
+ }, [P, q]);
523
+ h.useEffect(() => {
524
+ if (V || W)
525
+ return document.addEventListener("mousemove", se), document.addEventListener("mouseup", ne), () => {
526
+ document.removeEventListener("mousemove", se), document.removeEventListener("mouseup", ne);
527
+ };
528
+ }, [V, W, se, ne]);
529
+ const U = oe(() => {
530
+ const s = [];
531
+ return n && n.nodes.forEach((r, a) => {
532
+ s.push({
533
+ ...r,
534
+ status: "idle",
535
+ position: { x: 100 + a % 3 * 300, y: 100 + Math.floor(a / 3) * 200 }
536
+ });
537
+ }), e && e.nodes.forEach((r) => {
538
+ s.push(r);
539
+ }), s.map((r, a) => ({
540
+ id: r.id,
541
+ type: r.type,
542
+ position: r.position || { x: 100 + a % 3 * 300, y: 100 + Math.floor(a / 3) * 200 },
543
+ data: {
544
+ ...r,
545
+ label: r.label,
546
+ config: r.config,
547
+ status: r.status,
548
+ error: r.error,
549
+ result_metadata: r.result_metadata,
550
+ isExecuting: d,
551
+ onUpdateLabel: (i, g) => {
552
+ b(i, { label: g });
553
+ }
554
+ },
555
+ style: {
556
+ opacity: n && !e ? 0.5 : 1,
557
+ borderStyle: n && !e ? "dashed" : "solid"
558
+ }
559
+ }));
560
+ }, [e, n, d]), T = oe(() => {
561
+ const s = [];
562
+ return n && s.push(...n.edges), e && s.push(...e.edges), s.map((r) => {
563
+ const a = e == null ? void 0 : e.nodes.find((N) => N.id === r.source), i = (a == null ? void 0 : a.status) === "running", g = (a == null ? void 0 : a.status) === "success" || (a == null ? void 0 : a.status) === "completed";
564
+ return {
565
+ id: `e${r.source}-${r.target}`,
566
+ source: r.source,
567
+ target: r.target,
568
+ type: "smoothstep",
569
+ animated: d && (i || g),
570
+ style: {
571
+ stroke: g ? "#22c55e" : i ? "#3b82f6" : "#9ca3af",
572
+ strokeWidth: i ? 3 : 2
573
+ },
574
+ markerEnd: {
575
+ type: tt.ArrowClosed,
576
+ color: g ? "#22c55e" : i ? "#3b82f6" : "#9ca3af"
577
+ }
578
+ };
579
+ });
580
+ }, [e, n, d]), [Y, we, Ne] = st(U), [ve, K, ye] = nt(T), Ce = h.useRef(""), ke = h.useRef("");
581
+ h.useEffect(() => {
582
+ const s = JSON.stringify(U.map((r) => ({ id: r.id, data: r.data, position: r.position })));
583
+ s !== Ce.current && (Ce.current = s, we(U));
584
+ }, [U, we]), h.useEffect(() => {
585
+ const s = JSON.stringify(T.map((r) => ({ id: r.id, source: r.source, target: r.target })));
586
+ s !== ke.current && (ke.current = s, K(T));
587
+ }, [T, K]);
588
+ const G = h.useRef(null);
589
+ h.useEffect(() => (Y.length > 0 && e && (G.current && clearTimeout(G.current), G.current = setTimeout(() => {
590
+ const s = e.nodes.map((a) => {
591
+ const i = Y.find((g) => g.id === a.id);
592
+ return i && i.position ? {
593
+ ...a,
594
+ position: i.position
595
+ } : a;
596
+ });
597
+ s.some((a) => {
598
+ var g, N, _, M;
599
+ const i = e.nodes.find((I) => I.id === a.id);
600
+ return i && (((g = i.position) == null ? void 0 : g.x) !== ((N = a.position) == null ? void 0 : N.x) || ((_ = i.position) == null ? void 0 : _.y) !== ((M = a.position) == null ? void 0 : M.y));
601
+ }) && ie({
602
+ ...e,
603
+ nodes: s,
604
+ updatedAt: /* @__PURE__ */ new Date()
605
+ });
606
+ }, 500)), () => {
607
+ G.current && clearTimeout(G.current);
608
+ }), [Y, e, ie]);
609
+ const _e = v(
610
+ (s) => {
611
+ if (!s || !s.source || !s.target) {
612
+ console.warn("[PipelineCanvas] Invalid connection params:", s);
613
+ return;
614
+ }
615
+ try {
616
+ A(s.source, s.target), K((r) => Ie(s, r)), K((r) => Ie(s, r));
617
+ } catch (r) {
618
+ console.error("[PipelineCanvas] Error adding edge:", r);
619
+ }
620
+ },
621
+ [A, K]
622
+ ), Me = v((s, r) => {
623
+ R(r.id);
624
+ }, []), Se = v((s, r) => {
625
+ R(r.id);
626
+ }, []), Ee = v((s, r) => {
627
+ s.preventDefault(), s.stopPropagation(), me({
628
+ nodeId: r.id,
629
+ x: s.clientX,
630
+ y: s.clientY
631
+ });
632
+ }, []), re = v(
633
+ (s) => {
634
+ y(s), R(null);
635
+ },
636
+ [y]
637
+ ), Ke = v(() => {
638
+ if (!x) return;
639
+ (e == null ? void 0 : e.nodes.find((r) => r.id === x.nodeId)) && R(x.nodeId);
640
+ }, [x, e]), Ge = v(() => {
641
+ x && confirm("Are you sure you want to delete this node?") && re(x.nodeId);
642
+ }, [x, re]), Je = v(() => {
643
+ x && R(x.nodeId);
644
+ }, [x]), Te = v(() => {
645
+ var a, i;
646
+ if (!x || !e) return;
647
+ const s = e.nodes.find((g) => g.id === x.nodeId);
648
+ if (!s) return;
649
+ const r = {
650
+ ...s,
651
+ id: `node_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`,
652
+ label: `${s.label} (Copy)`,
653
+ position: {
654
+ x: (((a = s.position) == null ? void 0 : a.x) || 0) + 50,
655
+ y: (((i = s.position) == null ? void 0 : i.y) || 0) + 50
656
+ },
657
+ status: "idle",
658
+ error: void 0,
659
+ result_metadata: void 0
660
+ };
661
+ j(r);
662
+ }, [x, e, j]), Qe = v(() => {
663
+ me(null);
664
+ }, []), Ze = () => {
665
+ ge(!0);
666
+ }, Q = !!n && !e, je = ((e == null ? void 0 : e.nodes.length) || 0) > 0;
667
+ return /* @__PURE__ */ o("div", { className: "h-full flex flex-col bg-[#1a1a2e]", children: [
668
+ /* @__PURE__ */ o("div", { className: "h-14 flex items-center justify-between px-4 border-b border-gray-700/50 bg-[#1e1e32]", children: [
669
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-4", children: [
670
+ e && /* @__PURE__ */ t("div", { className: "flex items-center gap-2 text-xs text-gray-400", children: ze ? /* @__PURE__ */ o(F, { children: [
671
+ /* @__PURE__ */ t(O, { className: "w-3 h-3 animate-spin" }),
672
+ /* @__PURE__ */ t("span", { children: "Saving..." })
673
+ ] }) : le ? /* @__PURE__ */ o(F, { children: [
674
+ /* @__PURE__ */ t(f, { className: "w-3 h-3 text-green-500" }),
675
+ /* @__PURE__ */ t("span", { className: "text-gray-300", children: "Saved" }),
676
+ /* @__PURE__ */ t("span", { className: "text-gray-500", children: "•" }),
677
+ /* @__PURE__ */ t("span", { children: ((s) => {
678
+ if (!s) return "";
679
+ const r = s instanceof Date ? s : new Date(s);
680
+ if (isNaN(r.getTime())) return "";
681
+ const i = (/* @__PURE__ */ new Date()).getTime() - r.getTime(), g = Math.floor(i / 1e3), N = Math.floor(g / 60);
682
+ return g < 10 ? "Just now" : g < 60 ? `${g}s ago` : N < 60 ? `${N}m ago` : r.toLocaleTimeString([], { hour: "2-digit", minute: "2-digit" });
683
+ })(le) })
684
+ ] }) : null }),
685
+ /* @__PURE__ */ o("div", { className: "flex bg-gray-800/50 rounded-lg p-0.5", children: [
686
+ /* @__PURE__ */ t(
687
+ "button",
688
+ {
689
+ onClick: () => m("editor"),
690
+ className: `px-4 py-1.5 text-xs font-medium rounded-md transition-all ${c === "editor" ? "bg-gray-700 text-white shadow-sm" : "text-gray-400 hover:text-gray-200"}`,
691
+ children: "Editor"
692
+ }
693
+ ),
694
+ /* @__PURE__ */ o(
695
+ "button",
696
+ {
697
+ onClick: () => m("executions"),
698
+ className: `px-4 py-1.5 text-xs font-medium rounded-md transition-all flex items-center gap-1.5 ${c === "executions" ? "bg-gray-700 text-white shadow-sm" : "text-gray-400 hover:text-gray-200"}`,
699
+ children: [
700
+ "Executions",
701
+ d && /* @__PURE__ */ o("span", { className: "relative flex h-2 w-2", children: [
702
+ /* @__PURE__ */ t("span", { className: "animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75" }),
703
+ /* @__PURE__ */ t("span", { className: "relative inline-flex rounded-full h-2 w-2 bg-green-500" })
704
+ ] })
705
+ ]
706
+ }
707
+ )
708
+ ] }),
709
+ Q && /* @__PURE__ */ t("span", { className: "px-2 py-1 text-xs bg-yellow-500/20 text-yellow-400 rounded border border-yellow-500/30", children: "Review Blueprint" })
710
+ ] }),
711
+ /* @__PURE__ */ o("div", { className: "flex items-center gap-2", children: [
712
+ !Q && c === "editor" && /* @__PURE__ */ o(
713
+ "button",
714
+ {
715
+ onClick: () => He(!ue),
716
+ className: "px-3 py-1.5 text-xs bg-gray-700 text-gray-200 rounded-lg hover:bg-gray-600 flex items-center gap-1.5 transition-colors",
717
+ title: "Toggle node palette",
718
+ children: [
719
+ /* @__PURE__ */ t(ht, { className: "w-3.5 h-3.5" }),
720
+ "Add Node"
721
+ ]
722
+ }
723
+ ),
724
+ Q ? /* @__PURE__ */ o(F, { children: [
725
+ /* @__PURE__ */ o(
726
+ "button",
727
+ {
728
+ onClick: p,
729
+ className: "px-3 py-1.5 text-xs bg-green-600 text-white rounded-lg hover:bg-green-500 flex items-center gap-1.5 transition-colors",
730
+ children: [
731
+ /* @__PURE__ */ t(f, { className: "w-3.5 h-3.5" }),
732
+ "Approve"
733
+ ]
734
+ }
735
+ ),
736
+ /* @__PURE__ */ o(
737
+ "button",
738
+ {
739
+ onClick: u,
740
+ className: "px-3 py-1.5 text-xs bg-red-600/80 text-white rounded-lg hover:bg-red-500 flex items-center gap-1.5 transition-colors",
741
+ children: [
742
+ /* @__PURE__ */ t($, { className: "w-3.5 h-3.5" }),
743
+ "Reject"
744
+ ]
745
+ }
746
+ )
747
+ ] }) : /* @__PURE__ */ o(F, { children: [
748
+ je && /* @__PURE__ */ o(F, { children: [
749
+ d ? /* @__PURE__ */ o(
750
+ "button",
751
+ {
752
+ onClick: Be,
753
+ className: "px-3 py-1.5 text-xs bg-red-600/80 text-white rounded-lg hover:bg-red-500 flex items-center gap-1.5 transition-colors",
754
+ children: [
755
+ /* @__PURE__ */ t(mt, { className: "w-3.5 h-3.5" }),
756
+ "Stop"
757
+ ]
758
+ }
759
+ ) : /* @__PURE__ */ o(
760
+ "button",
761
+ {
762
+ onClick: C,
763
+ className: "px-3 py-1.5 text-xs bg-green-600 text-white rounded-lg hover:bg-green-500 flex items-center gap-1.5 transition-colors",
764
+ children: [
765
+ /* @__PURE__ */ t(pt, { className: "w-3.5 h-3.5" }),
766
+ "Run All"
767
+ ]
768
+ }
769
+ ),
770
+ /* @__PURE__ */ o(
771
+ "button",
772
+ {
773
+ onClick: Ze,
774
+ className: "px-3 py-1.5 text-xs bg-gray-700 text-gray-200 rounded-lg hover:bg-gray-600 flex items-center gap-1.5 transition-colors",
775
+ children: [
776
+ /* @__PURE__ */ t(ft, { className: "w-3.5 h-3.5" }),
777
+ "Save"
778
+ ]
779
+ }
780
+ )
781
+ ] }),
782
+ je && /* @__PURE__ */ o(
783
+ "button",
784
+ {
785
+ onClick: Fe,
786
+ className: "px-3 py-1.5 text-xs bg-gray-700 text-red-400 rounded-lg hover:bg-red-600/20 flex items-center gap-1.5 transition-colors",
787
+ children: [
788
+ /* @__PURE__ */ t(xt, { className: "w-3.5 h-3.5" }),
789
+ "Clear"
790
+ ]
791
+ }
792
+ )
793
+ ] })
794
+ ] })
795
+ ] }),
796
+ /* @__PURE__ */ t("div", { className: "flex-1 relative flex min-h-0", children: c === "editor" ? (
797
+ // Editor View - Canvas with saved pipelines on left and palette on right
798
+ /* @__PURE__ */ o(F, { children: [
799
+ /* @__PURE__ */ t(ct, {}),
800
+ /* @__PURE__ */ t("div", { className: "flex-1 relative", children: U.length === 0 ? /* @__PURE__ */ t("div", { className: "h-full flex flex-col items-center justify-center bg-[#1a1a2e]", children: /* @__PURE__ */ o("div", { className: "text-center", children: [
801
+ /* @__PURE__ */ t("div", { className: "w-16 h-16 rounded-full bg-gray-800/50 flex items-center justify-center mx-auto mb-4", children: /* @__PURE__ */ t(Ue, { className: "w-8 h-8 text-gray-500" }) }),
802
+ /* @__PURE__ */ t("p", { className: "text-gray-400 mb-2", children: "No pipeline nodes yet" }),
803
+ /* @__PURE__ */ t("p", { className: "text-sm text-gray-500", children: 'Ask the agent to create a pipeline, or click "Add Node" to build one manually' })
804
+ ] }) }) : /* @__PURE__ */ o(
805
+ De,
806
+ {
807
+ nodes: Y,
808
+ edges: ve,
809
+ onNodesChange: Ne,
810
+ onEdgesChange: ye,
811
+ onConnect: _e,
812
+ onNodeClick: Me,
813
+ onNodeDoubleClick: Se,
814
+ onNodeContextMenu: Ee,
815
+ nodeTypes: de,
816
+ fitView: !0,
817
+ className: "bg-[#1a1a2e]",
818
+ children: [
819
+ /* @__PURE__ */ t(
820
+ Le,
821
+ {
822
+ variant: Oe.Dots,
823
+ gap: 20,
824
+ size: 1,
825
+ color: "#374151"
826
+ }
827
+ ),
828
+ /* @__PURE__ */ t($e, { className: "bg-gray-800 border-gray-700 rounded-lg" }),
829
+ /* @__PURE__ */ t(
830
+ rt,
831
+ {
832
+ className: "bg-gray-800/50 rounded-lg",
833
+ nodeColor: (s) => {
834
+ var r;
835
+ switch ((r = s.data) == null ? void 0 : r.status) {
836
+ case "running":
837
+ return "#3b82f6";
838
+ case "success":
839
+ return "#22c55e";
840
+ case "error":
841
+ return "#ef4444";
842
+ default:
843
+ return "#6b7280";
844
+ }
845
+ }
846
+ }
847
+ )
848
+ ]
849
+ }
850
+ ) }),
851
+ ue && !Q && /* @__PURE__ */ t(at, {})
852
+ ] })
853
+ ) : (
854
+ // Executions View - Split canvas and logs
855
+ /* @__PURE__ */ o("div", { className: "flex-1 flex min-h-0", children: [
856
+ /* @__PURE__ */ o("div", { className: "w-1/2 border-r border-gray-700/50 relative", children: [
857
+ U.length === 0 ? /* @__PURE__ */ t("div", { className: "h-full flex items-center justify-center bg-[#1a1a2e]", children: /* @__PURE__ */ t("p", { className: "text-gray-500", children: "No nodes to display" }) }) : /* @__PURE__ */ o(
858
+ De,
859
+ {
860
+ nodes: Y,
861
+ edges: ve,
862
+ onNodesChange: Ne,
863
+ onEdgesChange: ye,
864
+ onConnect: _e,
865
+ onNodeClick: Me,
866
+ onNodeDoubleClick: Se,
867
+ onNodeContextMenu: Ee,
868
+ nodeTypes: de,
869
+ fitView: !0,
870
+ className: "bg-[#1a1a2e]",
871
+ nodesDraggable: !d,
872
+ nodesConnectable: !d,
873
+ elementsSelectable: !d,
874
+ children: [
875
+ /* @__PURE__ */ t(
876
+ Le,
877
+ {
878
+ variant: Oe.Dots,
879
+ gap: 20,
880
+ size: 1,
881
+ color: "#374151"
882
+ }
883
+ ),
884
+ /* @__PURE__ */ t($e, { className: "bg-gray-800 border-gray-700 rounded-lg" })
885
+ ]
886
+ }
887
+ ),
888
+ /* @__PURE__ */ o("div", { className: "absolute bottom-4 left-4 flex items-center gap-2", children: [
889
+ /* @__PURE__ */ t("button", { className: "p-2 bg-gray-800/80 rounded-lg text-gray-400 hover:text-white transition-colors", children: /* @__PURE__ */ t("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 8V4m0 0h4M4 4l5 5m11-1V4m0 0h-4m4 0l-5 5M4 16v4m0 0h4m-4 0l5-5m11 5l-5-5m5 5v-4m0 4h-4" }) }) }),
890
+ /* @__PURE__ */ t("button", { className: "p-2 bg-gray-800/80 rounded-lg text-gray-400 hover:text-white transition-colors", children: /* @__PURE__ */ t("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM10 7v3m0 0v3m0-3h3m-3 0H7" }) }) }),
891
+ /* @__PURE__ */ t("button", { className: "p-2 bg-gray-800/80 rounded-lg text-gray-400 hover:text-white transition-colors", children: /* @__PURE__ */ t("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M21 21l-6-6m2-5a7 7 0 11-14 0 7 7 0 0114 0zM13 10H7" }) }) }),
892
+ /* @__PURE__ */ t("button", { className: "p-2 bg-gray-800/80 rounded-lg text-gray-400 hover:text-white transition-colors", children: /* @__PURE__ */ t("svg", { className: "w-4 h-4", fill: "none", viewBox: "0 0 24 24", stroke: "currentColor", children: /* @__PURE__ */ t("path", { strokeLinecap: "round", strokeLinejoin: "round", strokeWidth: 2, d: "M4 4v5h.582m15.356 2A8.001 8.001 0 004.582 9m0 0H9m11 11v-5h-.581m0 0a8.003 8.003 0 01-15.357-2m15.357 2H15" }) }) })
893
+ ] })
894
+ ] }),
895
+ /* @__PURE__ */ t("div", { className: "w-1/2 bg-[#1e1e32]", children: /* @__PURE__ */ t(ut, {}) })
896
+ ] })
897
+ ) }),
898
+ /* @__PURE__ */ t(
899
+ dt,
900
+ {
901
+ isOpen: Xe,
902
+ onClose: () => ge(!1)
903
+ }
904
+ ),
905
+ L && c === "editor" && /* @__PURE__ */ o(
906
+ "div",
907
+ {
908
+ ref: k,
909
+ className: "absolute bg-[#1e1e32] border border-gray-700/50 rounded-xl shadow-2xl z-10 flex flex-col",
910
+ style: {
911
+ right: `${q.right}px`,
912
+ top: `${q.top}px`,
913
+ width: `${P.width}px`,
914
+ height: `${P.height}px`,
915
+ maxHeight: "calc(100vh - 100px)",
916
+ // Constrain height
917
+ cursor: V ? "grabbing" : W ? l != null && l.includes("both-top-left") || l != null && l.includes("both-bottom-right") ? "nwse-resize" : l != null && l.includes("both-top-right") || l != null && l.includes("both-bottom-left") ? "nesw-resize" : l != null && l.includes("width") ? "col-resize" : "row-resize" : "grab",
918
+ userSelect: "none"
919
+ },
920
+ onMouseDown: Ye,
921
+ children: [
922
+ /* @__PURE__ */ t("div", { className: "flex-1 overflow-y-auto", children: /* @__PURE__ */ t(
923
+ it,
924
+ {
925
+ nodeId: L,
926
+ onUpdate: (s) => b(L, s),
927
+ onDelete: () => re(L),
928
+ onClose: () => R(null)
929
+ }
930
+ ) }),
931
+ /* @__PURE__ */ t(
932
+ "div",
933
+ {
934
+ className: "absolute top-0 left-0 right-0 h-1 cursor-row-resize hover:bg-blue-500/50 transition-colors z-20",
935
+ onMouseDown: (s) => D(s, "height-top"),
936
+ style: { height: "4px" }
937
+ }
938
+ ),
939
+ /* @__PURE__ */ t(
940
+ "div",
941
+ {
942
+ className: "absolute top-0 bottom-0 right-0 w-1 cursor-col-resize hover:bg-blue-500/50 transition-colors z-20",
943
+ onMouseDown: (s) => D(s, "width-right"),
944
+ style: { width: "4px" }
945
+ }
946
+ ),
947
+ /* @__PURE__ */ t(
948
+ "div",
949
+ {
950
+ className: "absolute bottom-0 left-0 right-0 h-1 cursor-row-resize hover:bg-blue-500/50 transition-colors z-20",
951
+ onMouseDown: (s) => D(s, "height-bottom"),
952
+ style: { height: "4px" }
953
+ }
954
+ ),
955
+ /* @__PURE__ */ t(
956
+ "div",
957
+ {
958
+ className: "absolute top-0 bottom-0 left-0 w-1 cursor-col-resize hover:bg-blue-500/50 transition-colors z-20",
959
+ onMouseDown: (s) => D(s, "width-left"),
960
+ style: { width: "4px" }
961
+ }
962
+ ),
963
+ /* @__PURE__ */ t(
964
+ "div",
965
+ {
966
+ className: "absolute top-0 left-0 w-4 h-4 cursor-nwse-resize z-30",
967
+ onMouseDown: (s) => D(s, "both-top-left")
968
+ }
969
+ ),
970
+ /* @__PURE__ */ t(
971
+ "div",
972
+ {
973
+ className: "absolute top-0 right-0 w-4 h-4 cursor-nesw-resize z-30",
974
+ onMouseDown: (s) => D(s, "both-top-right")
975
+ }
976
+ ),
977
+ /* @__PURE__ */ t(
978
+ "div",
979
+ {
980
+ className: "absolute bottom-0 right-0 w-4 h-4 cursor-nwse-resize z-30",
981
+ onMouseDown: (s) => D(s, "both-bottom-right")
982
+ }
983
+ ),
984
+ /* @__PURE__ */ t(
985
+ "div",
986
+ {
987
+ className: "absolute bottom-0 left-0 w-4 h-4 cursor-nesw-resize z-30",
988
+ onMouseDown: (s) => D(s, "both-bottom-left")
989
+ }
990
+ )
991
+ ]
992
+ }
993
+ ),
994
+ x && (() => {
995
+ const s = (e == null ? void 0 : e.nodes.find((r) => r.id === x.nodeId)) || (n == null ? void 0 : n.nodes.find((r) => r.id === x.nodeId));
996
+ return s ? /* @__PURE__ */ t(
997
+ gt,
998
+ {
999
+ x: x.x,
1000
+ y: x.y,
1001
+ nodeId: x.nodeId,
1002
+ nodeLabel: s.label || s.type,
1003
+ onRename: Ke,
1004
+ onDelete: Ge,
1005
+ onConfigure: Je,
1006
+ onDuplicate: Te,
1007
+ onClose: Qe
1008
+ }
1009
+ ) : null;
1010
+ })()
1011
+ ] });
1012
+ };
1013
+ export {
1014
+ Vt as PipelineCanvas
1015
+ };
1016
+ //# sourceMappingURL=PipelineCanvas.mjs.map