@loopstack/loopstack-studio 0.22.0 → 0.23.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 (98) hide show
  1. package/dist/app/EnvironmentEmbedRoot.js +20 -18
  2. package/dist/components/dynamic-form/Form.js +50 -27
  3. package/dist/components/dynamic-form/InputController.js +3 -1
  4. package/dist/components/dynamic-form/fields/MarkdownViewField.js +20 -0
  5. package/dist/components/feedback/ErrorBoundary.js +43 -0
  6. package/dist/components/{LoadingCentered.js → feedback/LoadingCentered.js} +1 -1
  7. package/dist/components/feedback/index.js +5 -0
  8. package/dist/components/index.js +6 -3
  9. package/dist/components/layout/MainLayout.js +32 -16
  10. package/dist/components/layout/StudioSidebar.js +165 -0
  11. package/dist/components/ui-widgets/widgets/SandboxRun.js +1 -0
  12. package/dist/features/code-explorer/CodeExplorer.js +6 -0
  13. package/dist/features/code-explorer/components/CodeExplorerTree.js +5 -0
  14. package/dist/features/code-explorer/components/CodeExplorerTreeNode.js +82 -0
  15. package/dist/features/code-explorer/components/FileContentViewer.js +1 -0
  16. package/dist/features/code-explorer/components/FileTabsBar.js +3 -190
  17. package/dist/features/code-explorer/components/FileTabsBarBase.js +190 -0
  18. package/dist/features/code-explorer/index.js +4 -0
  19. package/dist/features/code-explorer/providers/CodeExplorerProvider.js +2 -162
  20. package/dist/features/code-explorer/utils/fileIcons.js +7 -4
  21. package/dist/features/debug/components/ConfigFlowViewer.js +1 -1
  22. package/dist/features/debug/components/PipelineFlowViewer.js +47 -46
  23. package/dist/features/debug/components/pipeline-flow/WorkflowGraph.js +19 -19
  24. package/dist/features/debug/index.js +3 -0
  25. package/dist/features/documents/DocumentRenderer.js +58 -0
  26. package/dist/features/{workbench → documents}/components/DocumentItem.js +1 -1
  27. package/dist/features/{workbench → documents}/components/DocumentMetadataPills.js +2 -2
  28. package/dist/features/{workbench/components → documents}/document-details/DocumentDetails.js +3 -3
  29. package/dist/features/{workbench/components → documents}/document-details/PromptDetails.js +3 -3
  30. package/dist/features/documents/index.js +4 -0
  31. package/dist/features/{workbench/components/document-renderer → documents/renderers}/AiMessage.js +5 -5
  32. package/dist/features/documents/renderers/ClaudeMessage.js +96 -0
  33. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentDebugRenderer.js +1 -1
  34. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentFormRenderer.js +3 -3
  35. package/dist/features/{workbench/components/document-renderer → documents/renderers}/DocumentMessageRenderer.js +1 -1
  36. package/dist/features/{workbench/components/document-renderer → documents/renderers}/ErrorMessageRenderer.js +1 -1
  37. package/dist/features/{workbench/components/document-renderer → documents/renderers}/LinkMessageRenderer.js +1 -1
  38. package/dist/features/{workbench/components/document-renderer → documents/renderers}/MarkdownMessageRenderer.js +2 -2
  39. package/dist/features/{workbench/components/document-renderer → documents/renderers}/PlainMessageRenderer.js +1 -1
  40. package/dist/features/health/index.js +1 -0
  41. package/dist/features/workbench/NavigationItems.js +29 -29
  42. package/dist/features/workbench/Workbench.js +71 -99
  43. package/dist/features/workbench/WorkflowItem.js +63 -55
  44. package/dist/features/workbench/WorkflowList.js +52 -81
  45. package/dist/features/workbench/components/NewRunDialog.js +2 -1
  46. package/dist/features/workbench/components/RemoteFileTabsBar.js +18 -0
  47. package/dist/features/workbench/components/RemoteFileTree.js +90 -0
  48. package/dist/features/workbench/components/WorkbenchFilesPanel.js +60 -0
  49. package/dist/features/workbench/components/WorkbenchFlowPanel.js +4 -3
  50. package/dist/features/workbench/components/WorkbenchIconSidebar.js +37 -29
  51. package/dist/features/workbench/components/WorkflowHistoryItem.js +11 -11
  52. package/dist/features/workbench/components/buttons/WorkflowButtons.js +49 -50
  53. package/dist/features/workbench/hooks/useWorkflowData.js +49 -0
  54. package/dist/features/workbench/hooks/useWorkflowListState.js +50 -0
  55. package/dist/features/workbench/index.js +8 -0
  56. package/dist/features/workbench/providers/RemoteFileExplorerProvider.js +145 -0
  57. package/dist/features/workbench/providers/WorkbenchLayoutProvider.js +47 -45
  58. package/dist/features/workspaces/components/CreateWorkspace.js +1 -1
  59. package/dist/features/workspaces/components/ExecutionTimeline.js +1 -1
  60. package/dist/features/workspaces/components/PipelineForm.js +2 -2
  61. package/dist/features/workspaces/components/WorkspaceHomePage.js +93 -0
  62. package/dist/features/workspaces/index.js +3 -0
  63. package/dist/hooks/index.js +3 -2
  64. package/dist/hooks/query-keys.js +138 -0
  65. package/dist/hooks/useAuth.js +43 -42
  66. package/dist/hooks/useConfig.js +31 -35
  67. package/dist/hooks/useDashboard.js +9 -13
  68. package/dist/hooks/useDebounce.js +8 -17
  69. package/dist/hooks/useDocuments.js +4 -9
  70. package/dist/hooks/useFiles.js +1 -51
  71. package/dist/hooks/useNamespaces.js +2 -8
  72. package/dist/hooks/usePipelines.js +132 -155
  73. package/dist/hooks/useProcessor.js +11 -14
  74. package/dist/hooks/useWorkflows.js +40 -62
  75. package/dist/hooks/useWorkspaces.js +105 -110
  76. package/dist/index.d.ts +105 -3
  77. package/dist/index.js +15 -7
  78. package/dist/node_modules/@xyflow/react/dist/esm/index.js +1 -1
  79. package/dist/pages/DashboardPage.js +1 -1
  80. package/dist/pages/DebugWorkflowDetailsPage.js +2 -2
  81. package/dist/pages/EmbedWorkbenchPage.js +4 -3
  82. package/dist/pages/PipelineDebugPage.js +6 -5
  83. package/dist/pages/PreviewWorkbenchPage.js +228 -128
  84. package/dist/pages/RunsListPage.js +52 -24
  85. package/dist/pages/StudioLandingPage.js +1 -0
  86. package/dist/pages/WorkbenchPage.js +3 -2
  87. package/dist/pages/WorkspacePage.js +103 -51
  88. package/dist/pages/WorkspaceRunsPage.js +71 -0
  89. package/dist/providers/InvalidationEventsProvider.js +9 -11
  90. package/dist/providers/StudioProvider.js +2 -2
  91. package/dist/routing/LocalRouter.js +18 -8
  92. package/package.json +2 -2
  93. package/dist/features/workbench/components/DocumentRenderer.js +0 -54
  94. /package/dist/components/{content → feedback}/ErrorAlert.js +0 -0
  95. /package/dist/components/{snackbars → feedback}/ErrorSnackbar.js +0 -0
  96. /package/dist/components/{snackbars → feedback}/Snackbar.js +0 -0
  97. /package/dist/features/{workbench → documents}/components/DocumentList.js +0 -0
  98. /package/dist/features/{workbench/components/document-renderer → documents/renderers}/AiMessageContent.js +0 -0
@@ -1,25 +1,29 @@
1
- import { useFilterPipelines, usePipeline, usePipelineConfig } from "../hooks/usePipelines.js";
1
+ import { useStudio } from "../providers/StudioProvider.js";
2
+ import { useFilterPipelines, usePipeline, usePipelineConfigByName } from "../hooks/usePipelines.js";
2
3
  import { useWorkspace } from "../hooks/useWorkspaces.js";
3
- import { useFetchWorkflowsByPipeline } from "../hooks/useWorkflows.js";
4
4
  import { Button } from "../components/ui/button.js";
5
5
  import { Collapsible, CollapsibleContent, CollapsibleTrigger } from "../components/ui/collapsible.js";
6
6
  import { SidebarMenu, SidebarProvider } from "../components/ui/sidebar.js";
7
- import ErrorSnackbar_default from "../components/snackbars/ErrorSnackbar.js";
8
- import LoadingCentered_default from "../components/LoadingCentered.js";
7
+ import LoadingCentered_default from "../components/feedback/LoadingCentered.js";
8
+ import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
9
9
  import { require_enums } from "../packages/contracts/dist/enums/index.js";
10
- import { ReactFlowProvider } from "../node_modules/@xyflow/react/dist/esm/index.js";
10
+ import { useFetchWorkflowsByPipeline } from "../hooks/useWorkflows.js";
11
11
  import WorkflowItem_default from "../features/workbench/WorkflowItem.js";
12
12
  import WorkflowButtons_default from "../features/workbench/components/buttons/WorkflowButtons.js";
13
+ import { ReactFlowProvider } from "../node_modules/@xyflow/react/dist/esm/index.js";
14
+ import PipelineFlowViewer_default from "../features/debug/components/PipelineFlowViewer.js";
15
+ import "../features/debug/index.js";
13
16
  import { useNamespaceTree } from "../hooks/useNamespaceTree.js";
14
17
  import WorkbenchNavigation_default from "../features/workbench/WorkbenchNavigation.js";
15
18
  import PipelineHistoryList_default from "../features/workbench/components/PipelineHistoryList.js";
16
- import PipelineFlowViewer_default from "../features/debug/components/PipelineFlowViewer.js";
17
19
  import { NewRunDialog } from "../features/workbench/components/NewRunDialog.js";
20
+ import "../features/workbench/index.js";
18
21
  import { c } from "react/compiler-runtime";
19
22
  import { useCallback, useEffect, useMemo, useRef, useState } from "react";
20
23
  import { jsx, jsxs } from "react/jsx-runtime";
24
+ import { useQuery } from "@tanstack/react-query";
21
25
  import { useNavigate, useParams } from "react-router-dom";
22
- import { ChevronDown, ChevronRight, ListOrdered, Loader2, Navigation, Play, ScrollText, Workflow } from "lucide-react";
26
+ import { ChevronDown, ChevronRight, ListOrdered, Loader2, Navigation, Play, RefreshCw, ScrollText, Workflow } from "lucide-react";
23
27
  import { formatDistanceToNow } from "date-fns";
24
28
  var import_enums = require_enums(), EMBED_MESSAGE_TYPE = "loopstack:embed:workflow-completed", EMBED_RESIZE_MESSAGE_TYPE = "loopstack:embed:resize", EMBED_NEW_RUN_MESSAGE_TYPE = "loopstack:embed:new-run";
25
29
  function PreviewWorkbenchPage() {
@@ -46,113 +50,121 @@ function PreviewWorkbenchPage() {
46
50
  }), e[3] = t, e[4] = o), o;
47
51
  }
48
52
  function PreviewWorkbenchContent(e) {
49
- let o = c(57), { pipelineId: s, onNewRunSuccess: l } = e, u = useRef(null), [d, m] = useState("output"), [_, v] = useState(!1), y = usePipeline(s), S = useFetchWorkflowsByPipeline(s), w;
50
- o[0] === S.data ? w = o[1] : (w = S.data ?? [], o[0] = S.data, o[1] = w);
51
- let T = w, E = useRef(!1), ge = y.data?.workspaceId, D = useWorkspace(ge).data?.blockName, O = y.data?.blockName, k = usePipelineConfig(D, O), A, j;
52
- o[2] !== S.data || o[3] !== s ? (A = () => {
53
- !S.data || E.current || S.data.length > 0 && S.data.every(_temp) && window.parent !== window && (E.current = !0, window.parent.postMessage({
53
+ let t = c(61), { pipelineId: o, onNewRunSuccess: s } = e, l = useRef(null), [u, d] = useState("output"), [m, _] = useState(!1), b = usePipeline(o), x = useFetchWorkflowsByPipeline(o), C;
54
+ t[0] === x.data ? C = t[1] : (C = x.data ?? [], t[0] = x.data, t[1] = C);
55
+ let T = C, E = useRef(!1), _e = b.data?.workspaceId, ve = useWorkspace(_e).data?.blockName, ye = b.data?.blockName, D = usePipelineConfigByName(ve, ye), O, k;
56
+ t[2] !== x.data || t[3] !== o ? (O = () => {
57
+ !x.data || E.current || x.data.length > 0 && x.data.every(_temp) && window.parent !== window && (E.current = !0, window.parent.postMessage({
54
58
  type: EMBED_MESSAGE_TYPE,
55
- pipelineId: s
59
+ pipelineId: o
56
60
  }, window.location.origin));
57
- }, j = [S.data, s], o[2] = S.data, o[3] = s, o[4] = A, o[5] = j) : (A = o[4], j = o[5]), useEffect(A, j);
58
- let M, N;
59
- o[6] === s ? (M = o[7], N = o[8]) : (M = () => {
60
- if (window.parent === window || !u.current) return;
61
+ }, k = [x.data, o], t[2] = x.data, t[3] = o, t[4] = O, t[5] = k) : (O = t[4], k = t[5]), useEffect(O, k);
62
+ let A, j;
63
+ t[6] === o ? (A = t[7], j = t[8]) : (A = () => {
64
+ if (window.parent === window || !l.current) return;
61
65
  let e = new ResizeObserver(() => {
62
- if (!u.current) return;
66
+ if (!l.current) return;
63
67
  let e = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
64
68
  window.parent.postMessage({
65
69
  type: EMBED_RESIZE_MESSAGE_TYPE,
66
- pipelineId: s,
70
+ pipelineId: o,
67
71
  height: e
68
72
  }, window.location.origin);
69
73
  });
70
- return e.observe(u.current), () => e.disconnect();
71
- }, N = [s], o[6] = s, o[7] = M, o[8] = N), useEffect(M, N);
72
- let P;
73
- o[9] === l ? P = o[10] : (P = (e) => {
74
- v(!1), l(e);
75
- }, o[9] = l, o[10] = P);
76
- let F = P, I = _temp2, L;
77
- o[11] === Symbol.for("react.memo_cache_sentinel") ? (L = {
74
+ return e.observe(l.current), () => e.disconnect();
75
+ }, j = [o], t[6] = o, t[7] = A, t[8] = j), useEffect(A, j);
76
+ let M;
77
+ t[9] === s ? M = t[10] : (M = (e) => {
78
+ _(!1), s(e);
79
+ }, t[9] = s, t[10] = M);
80
+ let N = M, P = _temp2, F;
81
+ t[11] === Symbol.for("react.memo_cache_sentinel") ? (F = {
78
82
  enableDebugMode: !1,
79
83
  showFullMessageHistory: !1
80
- }, o[11] = L) : L = o[11];
81
- let R = L, z;
82
- o[12] === Symbol.for("react.memo_cache_sentinel") ? (z = {
84
+ }, t[11] = F) : F = t[11];
85
+ let I = F, L;
86
+ t[12] === Symbol.for("react.memo_cache_sentinel") ? (L = {
83
87
  value: "output",
84
88
  label: "Output",
85
89
  icon: /* @__PURE__ */ jsx(ScrollText, { className: "h-3.5 w-3.5" })
86
- }, o[12] = z) : z = o[12];
87
- let B;
88
- o[13] === Symbol.for("react.memo_cache_sentinel") ? (B = {
90
+ }, t[12] = L) : L = t[12];
91
+ let R;
92
+ t[13] === Symbol.for("react.memo_cache_sentinel") ? (R = {
89
93
  value: "graph",
90
94
  label: "Graph",
91
95
  icon: /* @__PURE__ */ jsx(Workflow, { className: "h-3.5 w-3.5" })
92
- }, o[13] = B) : B = o[13];
93
- let V;
94
- o[14] === Symbol.for("react.memo_cache_sentinel") ? (V = [
96
+ }, t[13] = R) : R = t[13];
97
+ let z;
98
+ t[14] === Symbol.for("react.memo_cache_sentinel") ? (z = {
99
+ value: "run-log",
100
+ label: "Run Log",
101
+ icon: /* @__PURE__ */ jsx(ListOrdered, { className: "h-3.5 w-3.5" })
102
+ }, t[14] = z) : z = t[14];
103
+ let B;
104
+ t[15] === Symbol.for("react.memo_cache_sentinel") ? (B = [
105
+ L,
106
+ R,
95
107
  z,
96
- B,
97
108
  {
98
- value: "run-log",
99
- label: "Run Log",
100
- icon: /* @__PURE__ */ jsx(ListOrdered, { className: "h-3.5 w-3.5" })
109
+ value: "logs",
110
+ label: "Logs",
111
+ icon: /* @__PURE__ */ jsx(ScrollText, { className: "h-3.5 w-3.5" })
101
112
  }
102
- ], o[14] = V) : V = o[14];
103
- let _e = V, H;
104
- o[15] === d ? H = o[16] : (H = /* @__PURE__ */ jsx("div", {
113
+ ], t[15] = B) : B = t[15];
114
+ let be = B, V;
115
+ t[16] === u ? V = t[17] : (V = /* @__PURE__ */ jsx("div", {
105
116
  className: "bg-background flex items-center rounded-md border p-0.5",
106
- children: _e.map((e) => /* @__PURE__ */ jsxs("button", {
107
- onClick: () => m(e.value),
108
- className: `flex items-center gap-1.5 rounded-sm px-2.5 py-1 text-xs font-medium transition-colors ${d === e.value ? "bg-foreground text-background shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
117
+ children: be.map((e) => /* @__PURE__ */ jsxs("button", {
118
+ onClick: () => d(e.value),
119
+ className: `flex items-center gap-1.5 rounded-sm px-2.5 py-1 text-xs font-medium transition-colors ${u === e.value ? "bg-foreground text-background shadow-sm" : "text-muted-foreground hover:text-foreground"}`,
109
120
  children: [e.icon, e.label]
110
121
  }, e.value))
111
- }), o[15] = d, o[16] = H);
112
- let U;
113
- o[17] === Symbol.for("react.memo_cache_sentinel") ? (U = /* @__PURE__ */ jsxs(Button, {
122
+ }), t[16] = u, t[17] = V);
123
+ let H;
124
+ t[18] === Symbol.for("react.memo_cache_sentinel") ? (H = /* @__PURE__ */ jsxs(Button, {
114
125
  variant: "outline",
115
126
  size: "sm",
116
127
  className: "h-7 gap-1.5",
117
- onClick: () => v(!0),
128
+ onClick: () => _(!0),
118
129
  children: [/* @__PURE__ */ jsx(Play, { className: "h-3 w-3" }), "New Run"]
119
- }), o[17] = U) : U = o[17];
120
- let W;
121
- o[18] === H ? W = o[19] : (W = /* @__PURE__ */ jsxs("div", {
130
+ }), t[18] = H) : H = t[18];
131
+ let U;
132
+ t[19] === V ? U = t[20] : (U = /* @__PURE__ */ jsxs("div", {
122
133
  className: "bg-muted/50 flex h-11 shrink-0 items-center justify-between border-b px-3",
123
- children: [H, U]
124
- }), o[18] = H, o[19] = W);
134
+ children: [V, H]
135
+ }), t[19] = V, t[20] = U);
136
+ let W;
137
+ t[21] === b.error ? W = t[22] : (W = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: b.error }), t[21] = b.error, t[22] = W);
125
138
  let G;
126
- o[20] === y.error ? G = o[21] : (G = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: y.error }), o[20] = y.error, o[21] = G);
139
+ t[23] === x.error ? G = t[24] : (G = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: x.error }), t[23] = x.error, t[24] = G);
127
140
  let K;
128
- o[22] === S.error ? K = o[23] : (K = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: S.error }), o[22] = S.error, o[23] = K);
129
- let q;
130
- o[24] !== d || o[25] !== y.data || o[26] !== y.isLoading || o[27] !== S.data || o[28] !== S.isLoading ? (q = d === "output" && /* @__PURE__ */ jsx("div", {
141
+ t[25] !== u || t[26] !== b.data || t[27] !== b.isLoading || t[28] !== x.data || t[29] !== x.isLoading ? (K = u === "output" && /* @__PURE__ */ jsx("div", {
131
142
  className: "px-4 py-3",
132
143
  children: /* @__PURE__ */ jsx(LoadingCentered_default, {
133
- loading: y.isLoading || S.isLoading,
134
- children: y.data && S.data ? S.data.map((e) => /* @__PURE__ */ jsx(EmbedWorkflowSection, {
144
+ loading: b.isLoading || x.isLoading,
145
+ children: b.data && x.data ? x.data.map((e) => /* @__PURE__ */ jsx(EmbedWorkflowSection, {
135
146
  workflow: e,
136
- pipeline: y.data,
137
- collapsible: S.data.length > 1,
147
+ pipeline: b.data,
148
+ collapsible: x.data.length > 1,
138
149
  children: /* @__PURE__ */ jsx(WorkflowItem_default, {
139
- pipeline: y.data,
150
+ pipeline: b.data,
140
151
  workflowId: e.id,
141
- scrollTo: I,
142
- settings: R
152
+ scrollTo: P,
153
+ settings: I
143
154
  })
144
155
  }, e.id)) : null
145
156
  })
146
- }), o[24] = d, o[25] = y.data, o[26] = y.isLoading, o[27] = S.data, o[28] = S.isLoading, o[29] = q) : q = o[29];
147
- let J;
148
- o[30] !== d || o[31] !== y.isLoading || o[32] !== k || o[33] !== S.isLoading || o[34] !== s || o[35] !== T ? (J = d === "graph" && /* @__PURE__ */ jsx("div", {
157
+ }), t[25] = u, t[26] = b.data, t[27] = b.isLoading, t[28] = x.data, t[29] = x.isLoading, t[30] = K) : K = t[30];
158
+ let q;
159
+ t[31] !== u || t[32] !== b.isLoading || t[33] !== D || t[34] !== x.isLoading || t[35] !== o || t[36] !== T ? (q = u === "graph" && /* @__PURE__ */ jsx("div", {
149
160
  className: "h-full",
150
161
  children: /* @__PURE__ */ jsx(LoadingCentered_default, {
151
- loading: y.isLoading || S.isLoading,
162
+ loading: b.isLoading || x.isLoading,
152
163
  children: T.length > 0 ? /* @__PURE__ */ jsx(ReactFlowProvider, { children: /* @__PURE__ */ jsx(PipelineFlowViewer_default, {
153
- pipelineId: s,
164
+ pipelineId: o,
154
165
  workflows: T,
155
- pipelineConfig: k.data
166
+ pipelineConfig: D.data,
167
+ direction: "TB"
156
168
  }) }) : /* @__PURE__ */ jsx("div", {
157
169
  className: "text-muted-foreground flex h-full items-center justify-center",
158
170
  children: /* @__PURE__ */ jsx("p", {
@@ -161,21 +173,24 @@ function PreviewWorkbenchContent(e) {
161
173
  })
162
174
  })
163
175
  })
164
- }), o[30] = d, o[31] = y.isLoading, o[32] = k, o[33] = S.isLoading, o[34] = s, o[35] = T, o[36] = J) : J = o[36];
165
- let Y;
166
- o[37] !== d || o[38] !== y.data ? (Y = d === "run-log" && /* @__PURE__ */ jsx("div", {
176
+ }), t[31] = u, t[32] = b.isLoading, t[33] = D, t[34] = x.isLoading, t[35] = o, t[36] = T, t[37] = q) : q = t[37];
177
+ let J;
178
+ t[38] !== u || t[39] !== b.data ? (J = u === "run-log" && /* @__PURE__ */ jsx("div", {
167
179
  className: "px-4",
168
- children: /* @__PURE__ */ jsx(PipelineHistoryList_default, { pipeline: y.data })
169
- }), o[37] = d, o[38] = y.data, o[39] = Y) : Y = o[39];
170
- let X;
171
- o[40] !== d || o[41] !== s ? (X = d === "navigate" && /* @__PURE__ */ jsx("div", {
180
+ children: /* @__PURE__ */ jsx(PipelineHistoryList_default, { pipeline: b.data })
181
+ }), t[38] = u, t[39] = b.data, t[40] = J) : J = t[40];
182
+ let Y;
183
+ t[41] !== u || t[42] !== o ? (Y = u === "navigate" && /* @__PURE__ */ jsx("div", {
172
184
  className: "px-4 py-2",
173
- children: /* @__PURE__ */ jsx(EmbedNavigationContent, { pipelineId: s })
174
- }), o[40] = d, o[41] = s, o[42] = X) : X = o[42];
185
+ children: /* @__PURE__ */ jsx(EmbedNavigationContent, { pipelineId: o })
186
+ }), t[41] = u, t[42] = o, t[43] = Y) : Y = t[43];
187
+ let X;
188
+ t[44] === u ? X = t[45] : (X = u === "logs" && /* @__PURE__ */ jsx(EmbedLogsContent, {}), t[44] = u, t[45] = X);
175
189
  let Z;
176
- o[43] !== G || o[44] !== K || o[45] !== q || o[46] !== J || o[47] !== Y || o[48] !== X ? (Z = /* @__PURE__ */ jsxs("div", {
190
+ t[46] !== W || t[47] !== G || t[48] !== K || t[49] !== q || t[50] !== J || t[51] !== Y || t[52] !== X ? (Z = /* @__PURE__ */ jsxs("div", {
177
191
  className: "flex-1 overflow-auto",
178
192
  children: [
193
+ W,
179
194
  G,
180
195
  K,
181
196
  q,
@@ -183,23 +198,23 @@ function PreviewWorkbenchContent(e) {
183
198
  Y,
184
199
  X
185
200
  ]
186
- }), o[43] = G, o[44] = K, o[45] = q, o[46] = J, o[47] = Y, o[48] = X, o[49] = Z) : Z = o[49];
201
+ }), t[46] = W, t[47] = G, t[48] = K, t[49] = q, t[50] = J, t[51] = Y, t[52] = X, t[53] = Z) : Z = t[53];
187
202
  let Q;
188
- o[50] !== F || o[51] !== _ ? (Q = /* @__PURE__ */ jsx(NewRunDialog, {
189
- open: _,
190
- onOpenChange: v,
191
- onSuccess: F
192
- }), o[50] = F, o[51] = _, o[52] = Q) : Q = o[52];
203
+ t[54] !== N || t[55] !== m ? (Q = /* @__PURE__ */ jsx(NewRunDialog, {
204
+ open: m,
205
+ onOpenChange: _,
206
+ onSuccess: N
207
+ }), t[54] = N, t[55] = m, t[56] = Q) : Q = t[56];
193
208
  let $;
194
- return o[53] !== W || o[54] !== Z || o[55] !== Q ? ($ = /* @__PURE__ */ jsxs("div", {
195
- ref: u,
209
+ return t[57] !== U || t[58] !== Z || t[59] !== Q ? ($ = /* @__PURE__ */ jsxs("div", {
210
+ ref: l,
196
211
  className: "flex h-screen flex-col overflow-hidden",
197
212
  children: [
198
- W,
213
+ U,
199
214
  Z,
200
215
  Q
201
216
  ]
202
- }), o[53] = W, o[54] = Z, o[55] = Q, o[56] = $) : $ = o[56], $;
217
+ }), t[57] = U, t[58] = Z, t[59] = Q, t[60] = $) : $ = t[60], $;
203
218
  }
204
219
  function _temp2() {}
205
220
  function _temp(e) {
@@ -213,31 +228,31 @@ var STATUS_DOT_COLORS = {
213
228
  canceled: "bg-orange-500",
214
229
  pending: "bg-muted-foreground"
215
230
  };
216
- function PreviewEmptyState(t) {
217
- let n = c(23), { newRunDialogOpen: r, onNewRunDialogOpenChange: i, onNewRunSuccess: o } = t, s = useNavigate(), [l, u] = useState(3), d;
218
- n[0] === Symbol.for("react.memo_cache_sentinel") ? (d = { parentId: null }, n[0] = d) : d = n[0];
219
- let f = useFilterPipelines(void 0, d, "createdAt", "DESC", 0, l), p;
220
- n[1] === f.data?.data ? p = n[2] : (p = f.data?.data ?? [], n[1] = f.data?.data, n[2] = p);
221
- let m = p, h = f.data?.total ?? 0, g = m.length < h, _;
222
- n[3] === i ? _ = n[4] : (_ = () => i(!0), n[3] = i, n[4] = _);
223
- let v;
224
- n[5] === Symbol.for("react.memo_cache_sentinel") ? (v = /* @__PURE__ */ jsx(Play, { className: "h-3.5 w-3.5" }), n[5] = v) : v = n[5];
225
- let y;
226
- n[6] === _ ? y = n[7] : (y = /* @__PURE__ */ jsx("div", {
231
+ function PreviewEmptyState(n) {
232
+ let r = c(24), { newRunDialogOpen: i, onNewRunDialogOpenChange: o, onNewRunSuccess: s } = n, l = useNavigate(), { router: u } = useStudio(), [d, f] = useState(3), p;
233
+ r[0] === Symbol.for("react.memo_cache_sentinel") ? (p = { parentId: null }, r[0] = p) : p = r[0];
234
+ let m = useFilterPipelines(void 0, p, "createdAt", "DESC", 0, d), h;
235
+ r[1] === m.data?.data ? h = r[2] : (h = m.data?.data ?? [], r[1] = m.data?.data, r[2] = h);
236
+ let g = h, _ = m.data?.total ?? 0, v = g.length < _, y;
237
+ r[3] === o ? y = r[4] : (y = () => o(!0), r[3] = o, r[4] = y);
238
+ let b;
239
+ r[5] === Symbol.for("react.memo_cache_sentinel") ? (b = /* @__PURE__ */ jsx(Play, { className: "h-3.5 w-3.5" }), r[5] = b) : b = r[5];
240
+ let x;
241
+ r[6] === y ? x = r[7] : (x = /* @__PURE__ */ jsx("div", {
227
242
  className: "flex justify-center",
228
243
  children: /* @__PURE__ */ jsxs(Button, {
229
244
  variant: "secondary",
230
245
  size: "sm",
231
246
  className: "gap-1.5",
232
- onClick: _,
233
- children: [v, "New Run"]
247
+ onClick: y,
248
+ children: [b, "New Run"]
234
249
  })
235
- }), n[6] = _, n[7] = y);
236
- let b;
237
- n[8] !== f.isLoading || n[9] !== g || n[10] !== s || n[11] !== m ? (b = f.isLoading && m.length === 0 ? /* @__PURE__ */ jsx("div", {
250
+ }), r[6] = y, r[7] = x);
251
+ let S;
252
+ r[8] !== m.isLoading || r[9] !== v || r[10] !== l || r[11] !== g || r[12] !== u ? (S = m.isLoading && g.length === 0 ? /* @__PURE__ */ jsx("div", {
238
253
  className: "flex justify-center py-4",
239
254
  children: /* @__PURE__ */ jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" })
240
- }) : m.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
255
+ }) : g.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
241
256
  /* @__PURE__ */ jsx("p", {
242
257
  className: "text-muted-foreground mb-2 text-xs font-medium",
243
258
  children: "Recent"
@@ -246,34 +261,34 @@ function PreviewEmptyState(t) {
246
261
  className: "max-h-[280px] overflow-auto",
247
262
  children: /* @__PURE__ */ jsx("div", {
248
263
  className: "divide-border divide-y",
249
- children: m.map((e) => /* @__PURE__ */ jsx(RecentRunItem, {
264
+ children: g.map((e) => /* @__PURE__ */ jsx(RecentRunItem, {
250
265
  pipeline: e,
251
- onClick: () => void s(`/embed/preview/pipelines/${e.id}`)
266
+ onClick: () => void l(u.getPreviewPipeline(e.id))
252
267
  }, e.id))
253
268
  })
254
269
  }),
255
- g && /* @__PURE__ */ jsxs("button", {
270
+ v && /* @__PURE__ */ jsxs("button", {
256
271
  className: "text-muted-foreground hover:text-foreground mt-2 flex w-full items-center justify-center gap-1 py-1 text-xs transition-colors",
257
- onClick: () => u(_temp3),
272
+ onClick: () => f(_temp3),
258
273
  children: [/* @__PURE__ */ jsx(ChevronDown, { className: "h-3 w-3" }), "Load more"]
259
274
  })
260
- ] }) : null, n[8] = f.isLoading, n[9] = g, n[10] = s, n[11] = m, n[12] = b) : b = n[12];
261
- let x;
262
- n[13] !== y || n[14] !== b ? (x = /* @__PURE__ */ jsxs("div", {
263
- className: "w-full max-w-sm space-y-6 px-4",
264
- children: [y, b]
265
- }), n[13] = y, n[14] = b, n[15] = x) : x = n[15];
266
- let S;
267
- n[16] !== r || n[17] !== i || n[18] !== o ? (S = /* @__PURE__ */ jsx(NewRunDialog, {
268
- open: r,
269
- onOpenChange: i,
270
- onSuccess: o
271
- }), n[16] = r, n[17] = i, n[18] = o, n[19] = S) : S = n[19];
275
+ ] }) : null, r[8] = m.isLoading, r[9] = v, r[10] = l, r[11] = g, r[12] = u, r[13] = S) : S = r[13];
272
276
  let C;
273
- return n[20] !== x || n[21] !== S ? (C = /* @__PURE__ */ jsxs("div", {
274
- className: "flex h-screen flex-col items-center justify-center",
277
+ r[14] !== x || r[15] !== S ? (C = /* @__PURE__ */ jsxs("div", {
278
+ className: "w-full max-w-sm space-y-6 px-4",
275
279
  children: [x, S]
276
- }), n[20] = x, n[21] = S, n[22] = C) : C = n[22], C;
280
+ }), r[14] = x, r[15] = S, r[16] = C) : C = r[16];
281
+ let w;
282
+ r[17] !== i || r[18] !== o || r[19] !== s ? (w = /* @__PURE__ */ jsx(NewRunDialog, {
283
+ open: i,
284
+ onOpenChange: o,
285
+ onSuccess: s
286
+ }), r[17] = i, r[18] = o, r[19] = s, r[20] = w) : w = r[20];
287
+ let T;
288
+ return r[21] !== C || r[22] !== w ? (T = /* @__PURE__ */ jsxs("div", {
289
+ className: "flex h-screen flex-col items-center justify-center",
290
+ children: [C, w]
291
+ }), r[21] = C, r[22] = w, r[23] = T) : T = r[23], T;
277
292
  }
278
293
  function _temp3(e) {
279
294
  return e + 5;
@@ -385,6 +400,91 @@ function EmbedWorkflowSection(e) {
385
400
  children: [h, g]
386
401
  }), t[26] = h, t[27] = g, t[28] = v) : v = t[28], v;
387
402
  }
403
+ function stripAnsi(e) {
404
+ return e.replace(/\x1b\[[0-9;]*m/g, "");
405
+ }
406
+ function LogLine(e) {
407
+ let t = c(14), { line: n, index: r } = e, i, a, o;
408
+ if (t[0] !== n) {
409
+ i = stripAnsi(n);
410
+ let e;
411
+ t[4] === Symbol.for("react.memo_cache_sentinel") ? (e = /\bERROR\b/, t[4] = e) : e = t[4], a = e.test(i), o = /\bWARN\b/.test(i) || /\b(Warning|WARNING|DeprecationWarning)\b/.test(i), t[0] = n, t[1] = i, t[2] = a, t[3] = o;
412
+ } else i = t[1], a = t[2], o = t[3];
413
+ let s = o, l = `group flex border-b border-border/30 hover:bg-accent/30 ${a ? "bg-destructive/5" : s ? "bg-yellow-500/5" : ""}`, u = r + 1, d;
414
+ t[5] === u ? d = t[6] : (d = /* @__PURE__ */ jsx("span", {
415
+ className: "w-10 shrink-0 select-none border-r border-border/30 px-2 py-0.5 text-right text-[10px] text-muted-foreground/50",
416
+ children: u
417
+ }), t[5] = u, t[6] = d);
418
+ let f = `flex-1 px-3 py-0.5 text-[11px] leading-5 font-mono ${a ? "text-destructive" : s ? "text-yellow-600 dark:text-yellow-400" : ""}`, p;
419
+ t[7] !== i || t[8] !== f ? (p = /* @__PURE__ */ jsx("span", {
420
+ className: f,
421
+ children: i
422
+ }), t[7] = i, t[8] = f, t[9] = p) : p = t[9];
423
+ let m;
424
+ return t[10] !== l || t[11] !== d || t[12] !== p ? (m = /* @__PURE__ */ jsxs("div", {
425
+ className: l,
426
+ children: [d, p]
427
+ }), t[10] = l, t[11] = d, t[12] = p, t[13] = m) : m = t[13], m;
428
+ }
429
+ function EmbedLogsContent() {
430
+ let e = useRef(null), t = useQuery({
431
+ queryKey: ["remote-agent-app-logs"],
432
+ queryFn: async () => {
433
+ let e = await fetch("http://localhost:8000/api/v1/app/logs?lines=200", { credentials: "include" });
434
+ if (!e.ok) {
435
+ let t = await e.text();
436
+ throw Error(`Failed to fetch logs (${e.status}): ${t}`);
437
+ }
438
+ return await e.json();
439
+ },
440
+ refetchInterval: 5e3
441
+ });
442
+ useEffect(() => {
443
+ e.current?.scrollIntoView({ behavior: "smooth" });
444
+ }, [t.data]);
445
+ let n = useMemo(() => {
446
+ let e = [];
447
+ return t.data?.stdout && e.push(t.data.stdout), t.data?.stderr && e.push(t.data.stderr), e.join("\n").split("\n").filter((e) => e.length > 0);
448
+ }, [t.data]);
449
+ return /* @__PURE__ */ jsxs("div", {
450
+ className: "flex h-full flex-col",
451
+ children: [/* @__PURE__ */ jsxs("div", {
452
+ className: "flex h-9 shrink-0 items-center justify-between border-b bg-muted/30 px-3",
453
+ children: [/* @__PURE__ */ jsx("span", {
454
+ className: "text-xs font-medium text-muted-foreground",
455
+ children: "Application Logs"
456
+ }), /* @__PURE__ */ jsx("button", {
457
+ onClick: () => void t.refetch(),
458
+ className: `text-muted-foreground hover:text-foreground rounded-md p-1 transition-colors hover:cursor-pointer ${t.isFetching ? "animate-spin" : ""}`,
459
+ children: /* @__PURE__ */ jsx(RefreshCw, { className: "h-3 w-3" })
460
+ })]
461
+ }), /* @__PURE__ */ jsx("div", {
462
+ className: "flex-1 overflow-auto bg-background",
463
+ children: t.isLoading && !t.data ? /* @__PURE__ */ jsx("div", {
464
+ className: "flex justify-center py-8",
465
+ children: /* @__PURE__ */ jsx(Loader2, { className: "text-muted-foreground h-4 w-4 animate-spin" })
466
+ }) : t.error ? /* @__PURE__ */ jsx("div", {
467
+ className: "px-4 py-3",
468
+ children: /* @__PURE__ */ jsxs("p", {
469
+ className: "text-sm text-destructive",
470
+ children: ["Error: ", t.error.message]
471
+ })
472
+ }) : n.length > 0 ? /* @__PURE__ */ jsxs("div", {
473
+ className: "font-mono",
474
+ children: [n.map((e, t) => /* @__PURE__ */ jsx(LogLine, {
475
+ line: e,
476
+ index: t
477
+ }, t)), /* @__PURE__ */ jsx("div", { ref: e })]
478
+ }) : /* @__PURE__ */ jsxs("div", {
479
+ className: "flex flex-col items-center justify-center gap-2 py-8 text-muted-foreground",
480
+ children: [/* @__PURE__ */ jsx(ScrollText, { className: "h-5 w-5" }), /* @__PURE__ */ jsx("span", {
481
+ className: "text-xs",
482
+ children: "No logs available"
483
+ })]
484
+ })
485
+ })]
486
+ });
487
+ }
388
488
  function EmbedNavigationContent(e) {
389
489
  let t = c(4), { pipelineId: n } = e, r = useNamespaceTree(n);
390
490
  if (!r || r.length === 0) {
@@ -1,36 +1,64 @@
1
1
  import { useStudio } from "../providers/StudioProvider.js";
2
+ import { Button } from "../components/ui/button.js";
2
3
  import MainLayout_default from "../components/layout/MainLayout.js";
4
+ import { NewRunDialog } from "../features/workbench/components/NewRunDialog.js";
3
5
  import Runs_default from "../features/runs/Runs.js";
4
6
  import { c } from "react/compiler-runtime";
7
+ import { useState } from "react";
5
8
  import { jsx, jsxs } from "react/jsx-runtime";
6
- import { Home } from "lucide-react";
9
+ import { Home, Play } from "lucide-react";
7
10
  function RunsListPage() {
8
- let s = c(12), { router: l } = useStudio(), u;
9
- s[0] === l ? u = s[1] : (u = l.getDashboard(), s[0] = l, s[1] = u);
10
- let d;
11
- s[2] === Symbol.for("react.memo_cache_sentinel") ? (d = /* @__PURE__ */ jsx(Home, { className: "h-4 w-4" }), s[2] = d) : d = s[2];
12
- let f;
13
- s[3] === u ? f = s[4] : (f = {
11
+ let f = c(19), { router: p } = useStudio(), [m, h] = useState(!1), g;
12
+ f[0] === p ? g = f[1] : (g = p.getDashboard(), f[0] = p, f[1] = g);
13
+ let _;
14
+ f[2] === Symbol.for("react.memo_cache_sentinel") ? (_ = /* @__PURE__ */ jsx(Home, { className: "h-4 w-4" }), f[2] = _) : _ = f[2];
15
+ let v;
16
+ f[3] === g ? v = f[4] : (v = {
14
17
  label: "Dashboard",
15
- href: u,
16
- icon: d
17
- }, s[3] = u, s[4] = f);
18
- let p;
19
- s[5] === Symbol.for("react.memo_cache_sentinel") ? (p = {
18
+ href: g,
19
+ icon: _
20
+ }, f[3] = g, f[4] = v);
21
+ let y;
22
+ f[5] === Symbol.for("react.memo_cache_sentinel") ? (y = {
20
23
  label: "Runs",
21
24
  current: !0
22
- }, s[5] = p) : p = s[5];
23
- let m;
24
- s[6] === f ? m = s[7] : (m = [f, p], s[6] = f, s[7] = m);
25
- let h = m, g, _;
26
- s[8] === Symbol.for("react.memo_cache_sentinel") ? (g = /* @__PURE__ */ jsx("h1", {
27
- className: "mb-4 text-3xl font-bold tracking-tight",
25
+ }, f[5] = y) : y = f[5];
26
+ let b;
27
+ f[6] === v ? b = f[7] : (b = [v, y], f[6] = v, f[7] = b);
28
+ let x = b, S;
29
+ f[8] === Symbol.for("react.memo_cache_sentinel") ? (S = /* @__PURE__ */ jsx("h1", {
30
+ className: "text-3xl font-bold tracking-tight",
28
31
  children: "Runs"
29
- }), _ = /* @__PURE__ */ jsx(Runs_default, {}), s[8] = g, s[9] = _) : (g = s[8], _ = s[9]);
30
- let v;
31
- return s[10] === h ? v = s[11] : (v = /* @__PURE__ */ jsxs(MainLayout_default, {
32
- breadcrumbsData: h,
33
- children: [g, _]
34
- }), s[10] = h, s[11] = v), v;
32
+ }), f[8] = S) : S = f[8];
33
+ let C, w;
34
+ f[9] === Symbol.for("react.memo_cache_sentinel") ? (C = /* @__PURE__ */ jsxs("div", {
35
+ className: "mb-4 flex items-center justify-between",
36
+ children: [S, /* @__PURE__ */ jsxs(Button, {
37
+ variant: "default",
38
+ size: "sm",
39
+ className: "gap-1.5",
40
+ onClick: () => h(!0),
41
+ children: [/* @__PURE__ */ jsx(Play, { className: "h-3.5 w-3.5" }), "New Run"]
42
+ })]
43
+ }), w = /* @__PURE__ */ jsx(Runs_default, {}), f[9] = C, f[10] = w) : (C = f[9], w = f[10]);
44
+ let T;
45
+ f[11] === p ? T = f[12] : (T = (r) => {
46
+ h(!1), p.navigateToPipeline(r);
47
+ }, f[11] = p, f[12] = T);
48
+ let E;
49
+ f[13] !== m || f[14] !== T ? (E = /* @__PURE__ */ jsx(NewRunDialog, {
50
+ open: m,
51
+ onOpenChange: h,
52
+ onSuccess: T
53
+ }), f[13] = m, f[14] = T, f[15] = E) : E = f[15];
54
+ let D;
55
+ return f[16] !== x || f[17] !== E ? (D = /* @__PURE__ */ jsxs(MainLayout_default, {
56
+ breadcrumbsData: x,
57
+ children: [
58
+ C,
59
+ w,
60
+ E
61
+ ]
62
+ }), f[16] = x, f[17] = E, f[18] = D) : D = f[18], D;
35
63
  }
36
64
  export { RunsListPage as default };
@@ -2,6 +2,7 @@ import { useStudio } from "../providers/StudioProvider.js";
2
2
  import { useFilterPipelines } from "../hooks/usePipelines.js";
3
3
  import { Button } from "../components/ui/button.js";
4
4
  import { NewRunDialog } from "../features/workbench/components/NewRunDialog.js";
5
+ import "../features/workbench/index.js";
5
6
  import { c } from "react/compiler-runtime";
6
7
  import { useCallback, useState } from "react";
7
8
  import { jsx, jsxs } from "react/jsx-runtime";
@@ -1,9 +1,10 @@
1
1
  import { useStudio } from "../providers/StudioProvider.js";
2
2
  import { usePipeline } from "../hooks/usePipelines.js";
3
3
  import { useWorkspace } from "../hooks/useWorkspaces.js";
4
- import ErrorSnackbar_default from "../components/snackbars/ErrorSnackbar.js";
5
- import LoadingCentered_default from "../components/LoadingCentered.js";
4
+ import LoadingCentered_default from "../components/feedback/LoadingCentered.js";
5
+ import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
6
6
  import Workbench from "../features/workbench/Workbench.js";
7
+ import "../features/workbench/index.js";
7
8
  import { requireParam } from "../lib/requireParam.js";
8
9
  import { c } from "react/compiler-runtime";
9
10
  import { useCallback, useMemo } from "react";