@tangle-network/sandbox-ui 0.39.1 → 0.40.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.
package/dist/styles.css CHANGED
@@ -623,6 +623,9 @@
623
623
  width: calc(var(--spacing) * 3);
624
624
  height: calc(var(--spacing) * 3);
625
625
  }
626
+ .\!h-2 {
627
+ height: calc(var(--spacing) * 2) !important;
628
+ }
626
629
  .h-1 {
627
630
  height: calc(var(--spacing) * 1);
628
631
  }
@@ -830,6 +833,9 @@
830
833
  .min-h-screen {
831
834
  min-height: 100vh;
832
835
  }
836
+ .\!w-2 {
837
+ width: calc(var(--spacing) * 2) !important;
838
+ }
833
839
  .w-0 {
834
840
  width: calc(var(--spacing) * 0);
835
841
  }
@@ -959,6 +965,9 @@
959
965
  .w-\[72\%\] {
960
966
  width: 72%;
961
967
  }
968
+ .w-\[240px\] {
969
+ width: 240px;
970
+ }
962
971
  .w-\[268px\] {
963
972
  width: 268px;
964
973
  }
@@ -1103,6 +1112,9 @@
1103
1112
  .max-w-xl {
1104
1113
  max-width: var(--container-xl);
1105
1114
  }
1115
+ .\!min-w-0 {
1116
+ min-width: calc(var(--spacing) * 0) !important;
1117
+ }
1106
1118
  .min-w-0 {
1107
1119
  min-width: calc(var(--spacing) * 0);
1108
1120
  }
@@ -1151,6 +1163,9 @@
1151
1163
  .flex-shrink-0 {
1152
1164
  flex-shrink: 0;
1153
1165
  }
1166
+ .shrink {
1167
+ flex-shrink: 1;
1168
+ }
1154
1169
  .shrink-0 {
1155
1170
  flex-shrink: 0;
1156
1171
  }
@@ -1237,6 +1252,9 @@
1237
1252
  .cursor-default {
1238
1253
  cursor: default;
1239
1254
  }
1255
+ .cursor-ew-resize {
1256
+ cursor: ew-resize;
1257
+ }
1240
1258
  .cursor-not-allowed {
1241
1259
  cursor: not-allowed;
1242
1260
  }
@@ -1619,6 +1637,10 @@
1619
1637
  .rounded-bl-lg {
1620
1638
  border-bottom-left-radius: var(--radius-lg);
1621
1639
  }
1640
+ .\!border-0 {
1641
+ border-style: var(--tw-border-style) !important;
1642
+ border-width: 0px !important;
1643
+ }
1622
1644
  .border {
1623
1645
  border-style: var(--tw-border-style);
1624
1646
  border-width: 1px;
@@ -1831,6 +1853,9 @@
1831
1853
  .border-t-transparent {
1832
1854
  border-top-color: transparent;
1833
1855
  }
1856
+ .\!bg-transparent {
1857
+ background-color: transparent !important;
1858
+ }
1834
1859
  .bg-\[color-mix\(in_oklch\,var\(--color-warning\,orange\)_18\%\,transparent\)\] {
1835
1860
  background-color: var(--color-warning,orange);
1836
1861
  @supports (color: color-mix(in lab, red, red)) {
@@ -2952,6 +2977,10 @@
2952
2977
  --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
2953
2978
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2954
2979
  }
2980
+ .shadow-xl {
2981
+ --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
2982
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2983
+ }
2955
2984
  .ring {
2956
2985
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
2957
2986
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -3477,6 +3506,13 @@
3477
3506
  }
3478
3507
  }
3479
3508
  }
3509
+ .hover\:opacity-90 {
3510
+ &:hover {
3511
+ @media (hover: hover) {
3512
+ opacity: 90%;
3513
+ }
3514
+ }
3515
+ }
3480
3516
  .hover\:opacity-100 {
3481
3517
  &:hover {
3482
3518
  @media (hover: hover) {
@@ -3686,6 +3722,11 @@
3686
3722
  opacity: 30%;
3687
3723
  }
3688
3724
  }
3725
+ .disabled\:opacity-40 {
3726
+ &:disabled {
3727
+ opacity: 40%;
3728
+ }
3729
+ }
3689
3730
  .disabled\:opacity-50 {
3690
3731
  &:disabled {
3691
3732
  opacity: 50%;
@@ -0,0 +1,67 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ /**
4
+ * Turns a workflow YAML definition into a positioned node/edge graph for the
5
+ * visualizer. Pure and React-Flow-agnostic so the parsing + layout is unit
6
+ * testable on its own; the component maps these shapes onto React Flow nodes.
7
+ *
8
+ * The workflow model is a linear spine (trigger → action → action …) with
9
+ * one-level fan-out: a `parallel` action has N leaf branches and a `foreach`
10
+ * action has one leaf template. Branches dangle to the right of their structural
11
+ * node on the spine; they never continue the chain (the schema forbids nesting),
12
+ * so the spine stays a single readable column.
13
+ */
14
+ type WfNodeTone = "trigger" | "structural" | "action";
15
+ interface WfNodeData extends Record<string, unknown> {
16
+ /** Headline for the node, e.g. "Run agent". */
17
+ title: string;
18
+ /** Secondary detail, e.g. an integration path or a cron expression. */
19
+ subtitle?: string;
20
+ /** Connector slug (e.g. `github`) for the provider chip, when one applies. */
21
+ provider?: string;
22
+ /** Small corner tag, e.g. "×3" for a parallel fan-out. */
23
+ badge?: string;
24
+ /** Whether this node fans out to branch leaves (renders a right handle). */
25
+ hasBranches: boolean;
26
+ /** Whether this node is the spine root (no incoming/target handle). */
27
+ isRoot: boolean;
28
+ tone: WfNodeTone;
29
+ }
30
+ interface WfNode {
31
+ id: string;
32
+ position: {
33
+ x: number;
34
+ y: number;
35
+ };
36
+ data: WfNodeData;
37
+ }
38
+ interface WfEdge {
39
+ id: string;
40
+ source: string;
41
+ target: string;
42
+ /** "out" for spine edges (bottom handle), "branch" for fan-out (right). */
43
+ sourceHandle: "out" | "branch";
44
+ }
45
+ interface WfGraph {
46
+ nodes: WfNode[];
47
+ edges: WfEdge[];
48
+ /** Set when the YAML couldn't be parsed into a renderable graph. */
49
+ error: string | null;
50
+ }
51
+ /** Build a positioned graph from a workflow YAML string. Never throws —
52
+ * malformed YAML or an empty definition returns an `error` the UI can fall
53
+ * back on (e.g. show the raw YAML while authoring). */
54
+ declare function buildWorkflowGraph(yaml: string): WfGraph;
55
+
56
+ interface WorkflowGraphProps {
57
+ /** Workflow YAML to render. */
58
+ yaml: string;
59
+ /** "full" = interactive (pan/zoom/drag + controls); "preview" = static fit. */
60
+ variant?: "full" | "preview";
61
+ /** Sizing for the wrapper; the caller controls height. */
62
+ className?: string;
63
+ }
64
+
65
+ declare function WorkflowGraph(props: WorkflowGraphProps): react_jsx_runtime.JSX.Element;
66
+
67
+ export { type WfEdge, type WfGraph, type WfNode, type WfNodeData, type WfNodeTone, WorkflowGraph as WorkflowGraphLazy, type WorkflowGraphProps, buildWorkflowGraph };
@@ -0,0 +1,63 @@
1
+ import {
2
+ buildWorkflowGraph
3
+ } from "./chunk-SUC6ZJZW.js";
4
+ import "./chunk-7JLB7UZ3.js";
5
+
6
+ // src/workflows/WorkflowGraphLazy.tsx
7
+ import { Component, lazy, Suspense } from "react";
8
+ import { jsx, jsxs } from "react/jsx-runtime";
9
+ var WorkflowGraphImpl = lazy(
10
+ () => import("./WorkflowGraph-5QO6WCY2.js").then((m) => ({ default: m.WorkflowGraph }))
11
+ );
12
+ var GraphErrorBoundary = class extends Component {
13
+ state = { hasError: false };
14
+ static getDerivedStateFromError() {
15
+ return { hasError: true };
16
+ }
17
+ render() {
18
+ return this.state.hasError ? this.props.fallback : this.props.children;
19
+ }
20
+ };
21
+ function GraphFallback({ yaml, className }) {
22
+ return /* @__PURE__ */ jsxs(
23
+ "div",
24
+ {
25
+ className: `overflow-auto rounded-lg border border-border bg-background p-2 ${className ?? ""}`,
26
+ children: [
27
+ /* @__PURE__ */ jsx("p", { className: "mb-1 text-text-muted text-xs", children: "Couldn't render the graph \u2014 showing the definition." }),
28
+ /* @__PURE__ */ jsx("pre", { className: "text-text text-xs", children: /* @__PURE__ */ jsx("code", { children: yaml }) })
29
+ ]
30
+ }
31
+ );
32
+ }
33
+ function WorkflowGraph(props) {
34
+ return (
35
+ // Key the boundary by the workflow so a different/edited definition remounts
36
+ // it and re-attempts the graph — a transient chunk/render failure on one
37
+ // workflow doesn't permanently pin the YAML fallback for the next.
38
+ /* @__PURE__ */ jsx(
39
+ GraphErrorBoundary,
40
+ {
41
+ fallback: /* @__PURE__ */ jsx(GraphFallback, { ...props }),
42
+ children: /* @__PURE__ */ jsx(
43
+ Suspense,
44
+ {
45
+ fallback: /* @__PURE__ */ jsx(
46
+ "div",
47
+ {
48
+ className: `flex items-center justify-center rounded-lg border border-border border-dashed text-text-muted text-xs ${props.className ?? ""}`,
49
+ children: "Loading graph\u2026"
50
+ }
51
+ ),
52
+ children: /* @__PURE__ */ jsx(WorkflowGraphImpl, { ...props })
53
+ }
54
+ )
55
+ },
56
+ props.yaml
57
+ )
58
+ );
59
+ }
60
+ export {
61
+ WorkflowGraph as WorkflowGraphLazy,
62
+ buildWorkflowGraph
63
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.39.1",
3
+ "version": "0.40.0",
4
4
  "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -26,6 +26,14 @@
26
26
  "import": "./dist/chat.js",
27
27
  "types": "./dist/chat.d.ts"
28
28
  },
29
+ "./assistant": {
30
+ "import": "./dist/assistant.js",
31
+ "types": "./dist/assistant.d.ts"
32
+ },
33
+ "./workflows": {
34
+ "import": "./dist/workflows.js",
35
+ "types": "./dist/workflows.d.ts"
36
+ },
29
37
  "./run": {
30
38
  "import": "./dist/run.js",
31
39
  "types": "./dist/run.d.ts"
@@ -118,9 +126,13 @@
118
126
  "@tangle-network/ui": "^4.0.0",
119
127
  "react": "^18 || ^19",
120
128
  "react-dom": "^18 || ^19",
121
- "@tangle-network/agent-interface": ">=0.10.0 <1.0.0"
129
+ "@tangle-network/agent-interface": ">=0.10.0 <1.0.0",
130
+ "@xyflow/react": "^12.0.0"
122
131
  },
123
132
  "peerDependenciesMeta": {
133
+ "@xyflow/react": {
134
+ "optional": true
135
+ },
124
136
  "@xterm/xterm": {
125
137
  "optional": true
126
138
  },
@@ -145,7 +157,8 @@
145
157
  "@radix-ui/react-dropdown-menu": "^2.1.0",
146
158
  "@radix-ui/react-select": "^2.1.0",
147
159
  "lucide-react": "^0.469.0",
148
- "nanostores": "^1.2.0"
160
+ "nanostores": "^1.2.0",
161
+ "yaml": "^2.5.0"
149
162
  },
150
163
  "pnpm": {
151
164
  "overrides": {
@@ -155,6 +168,7 @@
155
168
  "devDependencies": {
156
169
  "@hocuspocus/provider": "^3.4.4",
157
170
  "@nanostores/react": "^1.1.0",
171
+ "@xyflow/react": "^12.11.0",
158
172
  "@pierre/trees": "1.0.0-beta.3",
159
173
  "@storybook/addon-essentials": "^8",
160
174
  "@storybook/addon-mcp": "^0.4.2",