@loopstack/loopstack-studio 0.33.0 → 0.34.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 (33) hide show
  1. package/dist/api/index.js +4 -1
  2. package/dist/app/EnvironmentEmbedRoot.js +22 -24
  3. package/dist/components/messages/CompletionMessagePaper.js +25 -29
  4. package/dist/events/sse-client-events.js +2 -0
  5. package/dist/features/dashboard/AppLauncher.js +111 -64
  6. package/dist/features/documents/DocumentRenderer.js +42 -42
  7. package/dist/features/feature-registry/FeatureRegistryProvider.js +15 -17
  8. package/dist/features/feature-registry/available-features.js +3 -2
  9. package/dist/features/feature-registry/index.js +1 -1
  10. package/dist/features/file-explorer/api/files.js +8 -3
  11. package/dist/features/file-explorer/components/FileExplorerPanel.js +64 -43
  12. package/dist/features/file-explorer/file-explorer-feature.js +15 -7
  13. package/dist/features/file-explorer/hooks/useFileExplorer.js +31 -29
  14. package/dist/features/file-explorer/index.js +1 -1
  15. package/dist/features/file-explorer/providers/FileExplorerProvider.js +77 -77
  16. package/dist/features/git/components/WorkbenchGitPanel.js +1 -1
  17. package/dist/features/secrets/components/WorkbenchSecretsPanel.js +1 -1
  18. package/dist/features/workbench/Workbench.js +16 -16
  19. package/dist/features/workbench/components/NewRunDialog.js +1 -1
  20. package/dist/features/workbench/components/WorkbenchIconSidebar.js +1 -1
  21. package/dist/features/workbench/components/WorkbenchSidebarShell.js +3 -3
  22. package/dist/features/workbench/index.js +1 -1
  23. package/dist/features/workspaces/Workspaces.js +1 -1
  24. package/dist/hooks/useSecrets.js +9 -45
  25. package/dist/index.d.ts +27 -13
  26. package/dist/index.js +6 -6
  27. package/dist/loopstack-studio.css +1 -1
  28. package/dist/pages/EmbedWorkbenchPage.js +46 -40
  29. package/dist/pages/WorkbenchPage.js +50 -45
  30. package/dist/pages/WorkspacePage.js +39 -25
  31. package/dist/pages/WorkspaceRunsPage.js +34 -26
  32. package/dist/providers/InvalidationEventsProvider.js +22 -20
  33. package/package.json +2 -2
@@ -1,6 +1,9 @@
1
1
  import { useWorkflow } from "../hooks/useWorkflows.js";
2
+ import { useWorkspace } from "../hooks/useWorkspaces.js";
2
3
  import LoadingCentered_default from "../components/feedback/LoadingCentered.js";
3
4
  import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
5
+ import { FeatureRegistryProvider } from "../features/feature-registry/FeatureRegistryProvider.js";
6
+ import "../features/feature-registry/index.js";
4
7
  import { WorkflowState } from "../packages/contracts/dist/enums/workflow-state.enum.js";
5
8
  import "../packages/contracts/dist/enums/index.js";
6
9
  import WorkflowItem_default from "../features/workbench/WorkflowItem.js";
@@ -13,59 +16,62 @@ import { jsx, jsxs } from "react/jsx-runtime";
13
16
  import { useParams } from "react-router-dom";
14
17
  var EMBED_MESSAGE_TYPE = "loopstack:embed:workflow-completed", EMBED_RESIZE_MESSAGE_TYPE = "loopstack:embed:resize";
15
18
  function EmbedWorkbenchPage() {
16
- let _ = c(20), v = useParams(), y;
17
- _[0] === v ? y = _[1] : (y = requireParam(v, "workflowId"), _[0] = v, _[1] = y);
18
- let b = y, x = useRef(null), S = useWorkflow(b), C = useRef(!1), w, T;
19
- _[2] !== S.data || _[3] !== b ? (w = () => {
20
- !S.data || C.current || S.data.status === WorkflowState.Completed && window.parent !== window && (C.current = !0, window.parent.postMessage({
19
+ let y = c(21), b = useParams(), x;
20
+ y[0] === b ? x = y[1] : (x = requireParam(b, "workflowId"), y[0] = b, y[1] = x);
21
+ let S = x, C = useRef(null), w = useWorkflow(S), T = useWorkspace(w.data?.workspaceId), E = useRef(!1), D, O;
22
+ y[2] !== w.data || y[3] !== S ? (D = () => {
23
+ !w.data || E.current || w.data.status === WorkflowState.Completed && window.parent !== window && (E.current = !0, window.parent.postMessage({
21
24
  type: EMBED_MESSAGE_TYPE,
22
- workflowId: b
25
+ workflowId: S
23
26
  }, window.location.origin));
24
- }, T = [S.data, b], _[2] = S.data, _[3] = b, _[4] = w, _[5] = T) : (w = _[4], T = _[5]), useEffect(w, T);
25
- let E, D;
26
- _[6] === b ? (E = _[7], D = _[8]) : (E = () => {
27
- if (window.parent === window || !x.current) return;
27
+ }, O = [w.data, S], y[2] = w.data, y[3] = S, y[4] = D, y[5] = O) : (D = y[4], O = y[5]), useEffect(D, O);
28
+ let k, A;
29
+ y[6] === S ? (k = y[7], A = y[8]) : (k = () => {
30
+ if (window.parent === window || !C.current) return;
28
31
  let t = new ResizeObserver(() => {
29
- if (!x.current) return;
32
+ if (!C.current) return;
30
33
  let t = Math.max(document.body.scrollHeight, document.body.offsetHeight, document.documentElement.scrollHeight, document.documentElement.offsetHeight);
31
34
  window.parent.postMessage({
32
35
  type: EMBED_RESIZE_MESSAGE_TYPE,
33
- workflowId: b,
36
+ workflowId: S,
34
37
  height: t
35
38
  }, window.location.origin);
36
39
  });
37
- return t.observe(x.current), () => t.disconnect();
38
- }, D = [b], _[6] = b, _[7] = E, _[8] = D), useEffect(E, D);
39
- let O = _temp, k;
40
- _[9] === Symbol.for("react.memo_cache_sentinel") ? (k = {
40
+ return t.observe(C.current), () => t.disconnect();
41
+ }, A = [S], y[6] = S, y[7] = k, y[8] = A), useEffect(k, A);
42
+ let j = _temp, M;
43
+ y[9] === Symbol.for("react.memo_cache_sentinel") ? (M = {
41
44
  enableDebugMode: !1,
42
45
  showFullMessageHistory: !1
43
- }, _[9] = k) : k = _[9];
44
- let A = k, j;
45
- _[10] === S.error ? j = _[11] : (j = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: S.error }), _[10] = S.error, _[11] = j);
46
- let M;
47
- _[12] === S.data ? M = _[13] : (M = S.data ? /* @__PURE__ */ jsx(WorkbenchLayoutProvider, {
48
- workspaceId: S.data.workspaceId,
49
- workflow: S.data,
50
- children: /* @__PURE__ */ jsx(WorkflowItem_default, {
51
- workflow: S.data,
52
- workflowId: S.data.id,
53
- scrollTo: O,
54
- settings: A,
55
- embed: !0
46
+ }, y[9] = M) : M = y[9];
47
+ let N = M, P;
48
+ y[10] === w.error ? P = y[11] : (P = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: w.error }), y[10] = w.error, y[11] = P);
49
+ let F = w.isLoading || T.isLoading, I;
50
+ y[12] !== w.data || y[13] !== T ? (I = w.data && T.data ? /* @__PURE__ */ jsx(FeatureRegistryProvider, {
51
+ appName: T.data.appName,
52
+ children: /* @__PURE__ */ jsx(WorkbenchLayoutProvider, {
53
+ workspaceId: w.data.workspaceId,
54
+ workflow: w.data,
55
+ children: /* @__PURE__ */ jsx(WorkflowItem_default, {
56
+ workflow: w.data,
57
+ workflowId: w.data.id,
58
+ scrollTo: j,
59
+ settings: N,
60
+ embed: !0
61
+ })
56
62
  })
57
- }) : null, _[12] = S.data, _[13] = M);
58
- let N;
59
- _[14] !== S.isLoading || _[15] !== M ? (N = /* @__PURE__ */ jsx(LoadingCentered_default, {
60
- loading: S.isLoading,
61
- children: M
62
- }), _[14] = S.isLoading, _[15] = M, _[16] = N) : N = _[16];
63
- let P;
64
- return _[17] !== j || _[18] !== N ? (P = /* @__PURE__ */ jsxs("div", {
65
- ref: x,
63
+ }) : null, y[12] = w.data, y[13] = T, y[14] = I) : I = y[14];
64
+ let L;
65
+ y[15] !== F || y[16] !== I ? (L = /* @__PURE__ */ jsx(LoadingCentered_default, {
66
+ loading: F,
67
+ children: I
68
+ }), y[15] = F, y[16] = I, y[17] = L) : L = y[17];
69
+ let R;
70
+ return y[18] !== P || y[19] !== L ? (R = /* @__PURE__ */ jsxs("div", {
71
+ ref: C,
66
72
  className: "overflow-hidden pl-3 py-4",
67
- children: [j, N]
68
- }), _[17] = j, _[18] = N, _[19] = P) : P = _[19], P;
73
+ children: [P, L]
74
+ }), y[18] = P, y[19] = L, y[20] = R) : R = y[20], R;
69
75
  }
70
76
  function _temp() {}
71
77
  export { EmbedWorkbenchPage as default };
@@ -3,6 +3,8 @@ import { useWorkflow } from "../hooks/useWorkflows.js";
3
3
  import { useWorkspace } from "../hooks/useWorkspaces.js";
4
4
  import LoadingCentered_default from "../components/feedback/LoadingCentered.js";
5
5
  import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
6
+ import { FeatureRegistryProvider } from "../features/feature-registry/FeatureRegistryProvider.js";
7
+ import "../features/feature-registry/index.js";
6
8
  import Workbench from "../features/workbench/Workbench.js";
7
9
  import "../features/workbench/index.js";
8
10
  import { useDefaultEnvironmentPreviewUrl } from "../hooks/useEnvironmentPreviewUrl.js";
@@ -10,57 +12,60 @@ import { requireParam } from "../lib/requireParam.js";
10
12
  import { c } from "react/compiler-runtime";
11
13
  import { jsx, jsxs } from "react/jsx-runtime";
12
14
  import { useParams } from "react-router-dom";
13
- function WorkbenchPage(p) {
14
- let m = c(35), h;
15
- m[0] === p ? h = m[1] : (h = p === void 0 ? {} : p, m[0] = p, m[1] = h);
16
- let { getPreviewUrl: g, getEnvironmentPreviewUrl: _ } = h, { router: v } = useStudio(), y = useParams(), b;
17
- m[2] === y ? b = m[3] : (b = requireParam(y, "workflowId"), m[2] = y, m[3] = b);
18
- let x = useWorkflow(b), S = x.data?.workspaceId, C = useWorkspace(S), w = useDefaultEnvironmentPreviewUrl(), T = _ ?? w, E;
19
- m[4] === v ? E = m[5] : (E = v.getWorkspaces(), m[4] = v, m[5] = E);
20
- let D;
21
- m[6] === E ? D = m[7] : (D = {
15
+ function WorkbenchPage(m) {
16
+ let h = c(36), g;
17
+ h[0] === m ? g = h[1] : (g = m === void 0 ? {} : m, h[0] = m, h[1] = g);
18
+ let { getPreviewUrl: _, getEnvironmentPreviewUrl: v } = g, { router: y } = useStudio(), b = useParams(), x;
19
+ h[2] === b ? x = h[3] : (x = requireParam(b, "workflowId"), h[2] = b, h[3] = x);
20
+ let S = useWorkflow(x), C = S.data?.workspaceId, w = useWorkspace(C), T = useDefaultEnvironmentPreviewUrl(), E = v ?? T, D;
21
+ h[4] === y ? D = h[5] : (D = y.getWorkspaces(), h[4] = y, h[5] = D);
22
+ let O;
23
+ h[6] === D ? O = h[7] : (O = {
22
24
  label: "Workspaces",
23
- href: E
24
- }, m[6] = E, m[7] = D);
25
- let O = C.data?.title ?? "", k;
26
- m[8] !== v || m[9] !== S ? (k = S ? v.getWorkspace(S) : void 0, m[8] = v, m[9] = S, m[10] = k) : k = m[10];
27
- let A;
28
- m[11] !== O || m[12] !== k ? (A = {
29
- label: O,
30
- href: k
31
- }, m[11] = O, m[12] = k, m[13] = A) : A = m[13];
32
- let j = `Run #${x.data?.run}${x.data?.title ? ` (${x.data.title})` : ""}`, M;
33
- m[14] === j ? M = m[15] : (M = { label: j }, m[14] = j, m[15] = M);
34
- let N;
35
- m[16] !== D || m[17] !== A || m[18] !== M ? (N = [
36
- D,
37
- A,
38
- M
39
- ], m[16] = D, m[17] = A, m[18] = M, m[19] = N) : N = m[19];
40
- let P = N, F;
41
- m[20] === x.error ? F = m[21] : (F = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: x.error }), m[20] = x.error, m[21] = F);
42
- let I;
43
- m[22] !== P || m[23] !== x.data || m[24] !== x.error || m[25] !== x.isLoading || m[26] !== g || m[27] !== T ? (I = x.data ? /* @__PURE__ */ jsx(Workbench, {
44
- workflow: x.data,
45
- breadcrumbData: P,
46
- getPreviewUrl: g,
47
- getEnvironmentPreviewUrl: T
48
- }) : !x.isLoading && !x.error ? /* @__PURE__ */ jsx("p", {
25
+ href: D
26
+ }, h[6] = D, h[7] = O);
27
+ let k = w.data?.title ?? "", A;
28
+ h[8] !== y || h[9] !== C ? (A = C ? y.getWorkspace(C) : void 0, h[8] = y, h[9] = C, h[10] = A) : A = h[10];
29
+ let j;
30
+ h[11] !== k || h[12] !== A ? (j = {
31
+ label: k,
32
+ href: A
33
+ }, h[11] = k, h[12] = A, h[13] = j) : j = h[13];
34
+ let M = `Run #${S.data?.run}${S.data?.title ? ` (${S.data.title})` : ""}`, N;
35
+ h[14] === M ? N = h[15] : (N = { label: M }, h[14] = M, h[15] = N);
36
+ let P;
37
+ h[16] !== O || h[17] !== j || h[18] !== N ? (P = [
38
+ O,
39
+ j,
40
+ N
41
+ ], h[16] = O, h[17] = j, h[18] = N, h[19] = P) : P = h[19];
42
+ let F = P, I;
43
+ h[20] === S.error ? I = h[21] : (I = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: S.error }), h[20] = S.error, h[21] = I);
44
+ let L = S.isLoading || w.isLoading, R;
45
+ h[22] !== F || h[23] !== S.data || h[24] !== S.error || h[25] !== S.isLoading || h[26] !== w.data || h[27] !== _ || h[28] !== E ? (R = S.data && w.data ? /* @__PURE__ */ jsx(FeatureRegistryProvider, {
46
+ appName: w.data.appName,
47
+ children: /* @__PURE__ */ jsx(Workbench, {
48
+ workflow: S.data,
49
+ breadcrumbData: F,
50
+ getPreviewUrl: _,
51
+ getEnvironmentPreviewUrl: E
52
+ })
53
+ }) : !S.isLoading && !S.error ? /* @__PURE__ */ jsx("p", {
49
54
  className: "text-muted-foreground py-8 text-center text-sm",
50
55
  children: "Workflow not found."
51
- }) : null, m[22] = P, m[23] = x.data, m[24] = x.error, m[25] = x.isLoading, m[26] = g, m[27] = T, m[28] = I) : I = m[28];
52
- let L;
53
- m[29] !== x.isLoading || m[30] !== I ? (L = /* @__PURE__ */ jsx(LoadingCentered_default, {
54
- loading: x.isLoading,
55
- children: I
56
- }), m[29] = x.isLoading, m[30] = I, m[31] = L) : L = m[31];
57
- let R;
58
- return m[32] !== F || m[33] !== L ? (R = /* @__PURE__ */ jsx("div", {
56
+ }) : null, h[22] = F, h[23] = S.data, h[24] = S.error, h[25] = S.isLoading, h[26] = w.data, h[27] = _, h[28] = E, h[29] = R) : R = h[29];
57
+ let z;
58
+ h[30] !== L || h[31] !== R ? (z = /* @__PURE__ */ jsx(LoadingCentered_default, {
59
+ loading: L,
60
+ children: R
61
+ }), h[30] = L, h[31] = R, h[32] = z) : z = h[32];
62
+ let B;
63
+ return h[33] !== I || h[34] !== z ? (B = /* @__PURE__ */ jsx("div", {
59
64
  className: "flex h-svh flex-col",
60
65
  children: /* @__PURE__ */ jsxs("div", {
61
66
  className: "flex-1 overflow-hidden",
62
- children: [F, L]
67
+ children: [I, z]
63
68
  })
64
- }), m[32] = F, m[33] = L, m[34] = R) : R = m[34], R;
69
+ }), h[33] = I, h[34] = z, h[35] = B) : B = h[35], B;
65
70
  }
66
71
  export { WorkbenchPage as default };
@@ -3,16 +3,18 @@ import { useAppsConfig } from "../hooks/useConfig.js";
3
3
  import { useWorkspace } from "../hooks/useWorkspaces.js";
4
4
  import MainLayout_default from "../components/layout/MainLayout.js";
5
5
  import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
6
+ import { FeatureRegistryProvider } from "../features/feature-registry/FeatureRegistryProvider.js";
7
+ import "../features/feature-registry/index.js";
6
8
  import { WorkbenchLayoutProvider } from "../features/workbench/providers/WorkbenchLayoutProvider.js";
7
9
  import { WorkbenchSidebarShell } from "../features/workbench/components/WorkbenchSidebarShell.js";
8
10
  import "../features/workspaces/components/WorkspaceHomePage.js";
9
11
  import { useDefaultEnvironmentPreviewUrl } from "../hooks/useEnvironmentPreviewUrl.js";
10
12
  import { c } from "react/compiler-runtime";
11
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
13
+ import { jsx, jsxs } from "react/jsx-runtime";
12
14
  import { useParams } from "react-router-dom";
13
15
  import { Loader2 } from "lucide-react";
14
16
  var WorkspacePage_default = () => {
15
- let h = c(30), { router: g } = useStudio(), { workspaceId: _ } = useParams(), v = useWorkspace(_), y = useAppsConfig(), b = useDefaultEnvironmentPreviewUrl(), x = v.data, S;
17
+ let h = c(35), { router: g } = useStudio(), { workspaceId: _ } = useParams(), v = useWorkspace(_), y = useAppsConfig(), b = useDefaultEnvironmentPreviewUrl(), x = v.data, S;
16
18
  h[0] === g ? S = h[1] : (S = g.getWorkspaces(), h[0] = g, h[1] = S);
17
19
  let C;
18
20
  h[2] === S ? C = h[3] : (C = {
@@ -26,37 +28,49 @@ var WorkspacePage_default = () => {
26
28
  }, h[4] = w, h[5] = T);
27
29
  let E;
28
30
  h[6] !== C || h[7] !== T ? (E = [C, T], h[6] = C, h[7] = T, h[8] = E) : E = h[8];
29
- let D = E, O = v.isLoading || y.isLoading, k;
30
- h[9] === O ? k = h[10] : (k = O ? /* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin" }) : "", h[9] = O, h[10] = k);
31
+ let D = E, O = v.isLoading || y.isLoading;
32
+ if (!x) {
33
+ let t;
34
+ h[9] === O ? t = h[10] : (t = O ? /* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin" }) : null, h[9] = O, h[10] = t);
35
+ let f;
36
+ h[11] === v.error ? f = h[12] : (f = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: v.error }), h[11] = v.error, h[12] = f);
37
+ let p;
38
+ h[13] === y.error ? p = h[14] : (p = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: y.error }), h[13] = y.error, h[14] = p);
39
+ let m;
40
+ return h[15] !== D || h[16] !== t || h[17] !== f || h[18] !== p ? (m = /* @__PURE__ */ jsxs(MainLayout_default, {
41
+ breadcrumbsData: D,
42
+ children: [
43
+ t,
44
+ f,
45
+ p
46
+ ]
47
+ }), h[15] = D, h[16] = t, h[17] = f, h[18] = p, h[19] = m) : m = h[19], m;
48
+ }
49
+ let k;
50
+ h[20] === y.error ? k = h[21] : (k = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: y.error }), h[20] = y.error, h[21] = k);
31
51
  let A;
32
- h[11] === v.error ? A = h[12] : (A = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: v.error }), h[11] = v.error, h[12] = A);
33
- let j;
34
- h[13] === y.error ? j = h[14] : (j = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: y.error }), h[13] = y.error, h[14] = j);
35
- let M;
36
- h[15] !== O || h[16] !== x ? (M = x && !O ? /* @__PURE__ */ jsx("div", {
52
+ h[22] === x ? A = h[23] : (A = /* @__PURE__ */ jsx("div", {
37
53
  className: "flex flex-col items-center justify-center py-16",
38
54
  children: /* @__PURE__ */ jsx("p", {
39
55
  className: "text-muted-foreground",
40
56
  children: "No home page configured for this workspace."
41
57
  })
42
- }) : null, h[15] = O, h[16] = x, h[17] = M) : M = h[17];
43
- let N;
44
- h[18] !== k || h[19] !== A || h[20] !== j || h[21] !== M ? (N = /* @__PURE__ */ jsxs(Fragment, { children: [
45
- k,
46
- A,
47
- j,
48
- M
49
- ] }), h[18] = k, h[19] = A, h[20] = j, h[21] = M, h[22] = N) : N = h[22];
50
- let P;
51
- h[23] !== D || h[24] !== N ? (P = /* @__PURE__ */ jsx(WorkbenchSidebarShell, { children: /* @__PURE__ */ jsx(MainLayout_default, {
58
+ }), h[22] = x, h[23] = A);
59
+ let j;
60
+ h[24] !== D || h[25] !== k || h[26] !== A ? (j = /* @__PURE__ */ jsx(WorkbenchSidebarShell, { children: /* @__PURE__ */ jsxs(MainLayout_default, {
52
61
  breadcrumbsData: D,
53
- children: N
54
- }) }), h[23] = D, h[24] = N, h[25] = P) : P = h[25];
55
- let F;
56
- return h[26] !== b || h[27] !== P || h[28] !== _ ? (F = /* @__PURE__ */ jsx(WorkbenchLayoutProvider, {
62
+ children: [k, A]
63
+ }) }), h[24] = D, h[25] = k, h[26] = A, h[27] = j) : j = h[27];
64
+ let M;
65
+ h[28] !== b || h[29] !== j || h[30] !== _ ? (M = /* @__PURE__ */ jsx(WorkbenchLayoutProvider, {
57
66
  workspaceId: _,
58
67
  getEnvironmentPreviewUrl: b,
59
- children: P
60
- }), h[26] = b, h[27] = P, h[28] = _, h[29] = F) : F = h[29], F;
68
+ children: j
69
+ }), h[28] = b, h[29] = j, h[30] = _, h[31] = M) : M = h[31];
70
+ let N;
71
+ return h[32] !== M || h[33] !== x.appName ? (N = /* @__PURE__ */ jsx(FeatureRegistryProvider, {
72
+ appName: x.appName,
73
+ children: M
74
+ }), h[32] = M, h[33] = x.appName, h[34] = N) : N = h[34], N;
61
75
  };
62
76
  export { WorkspacePage_default as default };
@@ -2,16 +2,18 @@ import { useStudio } from "../providers/StudioProvider.js";
2
2
  import { useWorkspace } from "../hooks/useWorkspaces.js";
3
3
  import MainLayout_default from "../components/layout/MainLayout.js";
4
4
  import ErrorSnackbar_default from "../components/feedback/ErrorSnackbar.js";
5
+ import { FeatureRegistryProvider } from "../features/feature-registry/FeatureRegistryProvider.js";
6
+ import "../features/feature-registry/index.js";
5
7
  import { WorkbenchLayoutProvider } from "../features/workbench/providers/WorkbenchLayoutProvider.js";
6
8
  import ExecutionTimeline_default from "../features/workspaces/components/ExecutionTimeline.js";
7
9
  import { WorkbenchSidebarShell } from "../features/workbench/components/WorkbenchSidebarShell.js";
8
10
  import { useDefaultEnvironmentPreviewUrl } from "../hooks/useEnvironmentPreviewUrl.js";
9
11
  import { c } from "react/compiler-runtime";
10
- import { Fragment, jsx, jsxs } from "react/jsx-runtime";
12
+ import { jsx, jsxs } from "react/jsx-runtime";
11
13
  import { useParams } from "react-router-dom";
12
14
  import { Loader2 } from "lucide-react";
13
15
  var WorkspaceRunsPage_default = () => {
14
- let h = c(34), { router: g } = useStudio(), { workspaceId: _ } = useParams(), v = useWorkspace(_), y = useDefaultEnvironmentPreviewUrl(), b = v.data, x;
16
+ let h = c(37), { router: g } = useStudio(), { workspaceId: _ } = useParams(), v = useWorkspace(_), y = useDefaultEnvironmentPreviewUrl(), b = v.data, x;
15
17
  h[0] === g ? x = h[1] : (x = g.getWorkspaces(), h[0] = g, h[1] = x);
16
18
  let S;
17
19
  h[2] === x ? S = h[3] : (S = {
@@ -36,34 +38,40 @@ var WorkspaceRunsPage_default = () => {
36
38
  T,
37
39
  E
38
40
  ], h[11] = S, h[12] = T, h[13] = D) : D = h[13];
39
- let O = D, k = b?.title ?? "", A;
40
- h[14] === k ? A = h[15] : (A = /* @__PURE__ */ jsxs("h1", {
41
+ let O = D;
42
+ if (!b) {
43
+ let n;
44
+ h[14] === v.isLoading ? n = h[15] : (n = v.isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin" }) : null, h[14] = v.isLoading, h[15] = n);
45
+ let p;
46
+ h[16] === v.error ? p = h[17] : (p = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: v.error }), h[16] = v.error, h[17] = p);
47
+ let m;
48
+ return h[18] !== O || h[19] !== n || h[20] !== p ? (m = /* @__PURE__ */ jsxs(MainLayout_default, {
49
+ breadcrumbsData: O,
50
+ children: [n, p]
51
+ }), h[18] = O, h[19] = n, h[20] = p, h[21] = m) : m = h[21], m;
52
+ }
53
+ let k;
54
+ h[22] === b.title ? k = h[23] : (k = /* @__PURE__ */ jsxs("h1", {
41
55
  className: "mb-4 text-3xl font-bold tracking-tight",
42
- children: [k, " — Runs"]
43
- }), h[14] = k, h[15] = A);
56
+ children: [b.title, " — Runs"]
57
+ }), h[22] = b.title, h[23] = k);
58
+ let A;
59
+ h[24] === b ? A = h[25] : (A = /* @__PURE__ */ jsx(ExecutionTimeline_default, { workspace: b }), h[24] = b, h[25] = A);
44
60
  let j;
45
- h[16] === v.isLoading ? j = h[17] : (j = v.isLoading ? /* @__PURE__ */ jsx(Loader2, { className: "h-6 w-6 animate-spin" }) : "", h[16] = v.isLoading, h[17] = j);
46
- let M;
47
- h[18] === v.error ? M = h[19] : (M = /* @__PURE__ */ jsx(ErrorSnackbar_default, { error: v.error }), h[18] = v.error, h[19] = M);
48
- let N;
49
- h[20] === b ? N = h[21] : (N = b ? /* @__PURE__ */ jsx(ExecutionTimeline_default, { workspace: b }) : "", h[20] = b, h[21] = N);
50
- let P;
51
- h[22] !== M || h[23] !== N || h[24] !== A || h[25] !== j ? (P = /* @__PURE__ */ jsxs(Fragment, { children: [
52
- A,
53
- j,
54
- M,
55
- N
56
- ] }), h[22] = M, h[23] = N, h[24] = A, h[25] = j, h[26] = P) : P = h[26];
57
- let F;
58
- h[27] !== O || h[28] !== P ? (F = /* @__PURE__ */ jsx(WorkbenchSidebarShell, { children: /* @__PURE__ */ jsx(MainLayout_default, {
61
+ h[26] !== O || h[27] !== k || h[28] !== A ? (j = /* @__PURE__ */ jsx(WorkbenchSidebarShell, { children: /* @__PURE__ */ jsxs(MainLayout_default, {
59
62
  breadcrumbsData: O,
60
- children: P
61
- }) }), h[27] = O, h[28] = P, h[29] = F) : F = h[29];
62
- let I;
63
- return h[30] !== y || h[31] !== F || h[32] !== _ ? (I = /* @__PURE__ */ jsx(WorkbenchLayoutProvider, {
63
+ children: [k, A]
64
+ }) }), h[26] = O, h[27] = k, h[28] = A, h[29] = j) : j = h[29];
65
+ let M;
66
+ h[30] !== y || h[31] !== j || h[32] !== _ ? (M = /* @__PURE__ */ jsx(WorkbenchLayoutProvider, {
64
67
  workspaceId: _,
65
68
  getEnvironmentPreviewUrl: y,
66
- children: F
67
- }), h[30] = y, h[31] = F, h[32] = _, h[33] = I) : I = h[33], I;
69
+ children: j
70
+ }), h[30] = y, h[31] = j, h[32] = _, h[33] = M) : M = h[33];
71
+ let N;
72
+ return h[34] !== M || h[35] !== b.appName ? (N = /* @__PURE__ */ jsx(FeatureRegistryProvider, {
73
+ appName: b.appName,
74
+ children: M
75
+ }), h[34] = M, h[35] = b.appName, h[36] = N) : N = h[36], N;
68
76
  };
69
77
  export { WorkspaceRunsPage_default as default };
@@ -1,5 +1,5 @@
1
1
  import { __toESM } from "../_virtual/rolldown_runtime.js";
2
- import { getChildWorkflowsCacheKey, getDocumentsCacheKey, getWorkflowCacheKey, getWorkflowStatusCacheKey } from "../hooks/query-keys.js";
2
+ import { getChildWorkflowsCacheKey, getDocumentsCacheKey, getSecretsCacheKey, getWorkflowCacheKey, getWorkflowStatusCacheKey } from "../hooks/query-keys.js";
3
3
  import { SseClientEvents } from "../events/sse-client-events.js";
4
4
  import { eventBus } from "../services/eventEmitter.js";
5
5
  import "../services/index.js";
@@ -9,31 +9,33 @@ import { c } from "react/compiler-runtime";
9
9
  import { useEffect, useRef } from "react";
10
10
  import { QueryClient, useQueryClient } from "@tanstack/react-query";
11
11
  var import_debounce = /* @__PURE__ */ __toESM(require_debounce(), 1), DEBOUNCE_MS = 300;
12
- function createDebouncedInvalidator(e, s) {
12
+ function createDebouncedInvalidator(e, l) {
13
13
  return (0, import_debounce.default)(() => {
14
- e.invalidateQueries({ queryKey: s });
14
+ e.invalidateQueries({ queryKey: l });
15
15
  }, DEBOUNCE_MS);
16
16
  }
17
17
  function InvalidationEventsProvider() {
18
- let e = c(5), { environment: d } = useStudio(), h = useQueryClient(), _;
19
- e[0] === Symbol.for("react.memo_cache_sentinel") ? (_ = /* @__PURE__ */ new Map(), e[0] = _) : _ = e[0];
20
- let v = useRef(_), y, b;
21
- return e[1] !== d.id || e[2] !== h ? (y = () => {
22
- if (!d.id) return;
23
- let e = d.id, u = v.current, f = function(e) {
24
- let s = JSON.stringify(e);
25
- u.has(s) || u.set(s, createDebouncedInvalidator(h, e)), u.get(s)();
26
- }, p = eventBus.on(SseClientEvents.WORKFLOW_CREATED, (l) => {
27
- l.parentId && f(getChildWorkflowsCacheKey(e, l.parentId));
28
- }), m = eventBus.on(SseClientEvents.WORKFLOW_UPDATED, (l) => {
29
- l.id && (f(getWorkflowCacheKey(e, l.id)), f(getWorkflowStatusCacheKey(e, l.id))), l.parentId && f(getChildWorkflowsCacheKey(e, l.parentId));
30
- }), g = eventBus.on(SseClientEvents.DOCUMENT_CREATED, (s) => {
31
- s.workflowId && f(getDocumentsCacheKey(e, s.workflowId));
32
- });
18
+ let e = c(5), { environment: f } = useStudio(), g = useQueryClient(), v;
19
+ e[0] === Symbol.for("react.memo_cache_sentinel") ? (v = /* @__PURE__ */ new Map(), e[0] = v) : v = e[0];
20
+ let y = useRef(v), b, x;
21
+ return e[1] !== f.id || e[2] !== g ? (b = () => {
22
+ if (!f.id) return;
23
+ let e = f.id, d = y.current, p = function(e) {
24
+ let l = JSON.stringify(e);
25
+ d.has(l) || d.set(l, createDebouncedInvalidator(g, e)), d.get(l)();
26
+ }, m = eventBus.on(SseClientEvents.WORKFLOW_CREATED, (u) => {
27
+ u.parentId && p(getChildWorkflowsCacheKey(e, u.parentId));
28
+ }), h = eventBus.on(SseClientEvents.WORKFLOW_UPDATED, (u) => {
29
+ u.id && (p(getWorkflowCacheKey(e, u.id)), p(getWorkflowStatusCacheKey(e, u.id))), u.parentId && p(getChildWorkflowsCacheKey(e, u.parentId));
30
+ }), _ = eventBus.on(SseClientEvents.DOCUMENT_CREATED, (l) => {
31
+ l.workflowId && p(getDocumentsCacheKey(e, l.workflowId));
32
+ }), v = (l) => {
33
+ l.workspaceId && p(getSecretsCacheKey(e, l.workspaceId));
34
+ }, b = eventBus.on(SseClientEvents.SECRET_UPSERTED, v), x = eventBus.on(SseClientEvents.SECRET_DELETED, v);
33
35
  return () => {
34
- p(), m(), g(), u.forEach(_temp), u.clear();
36
+ m(), h(), _(), b(), x(), d.forEach(_temp), d.clear();
35
37
  };
36
- }, b = [h, d.id], e[1] = d.id, e[2] = h, e[3] = y, e[4] = b) : (y = e[3], b = e[4]), useEffect(y, b), null;
38
+ }, x = [g, f.id], e[1] = f.id, e[2] = g, e[3] = b, e[4] = x) : (b = e[3], x = e[4]), useEffect(b, x), null;
37
39
  }
38
40
  function _temp(e) {
39
41
  return e.cancel();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@loopstack/loopstack-studio",
3
- "version": "0.33.0",
3
+ "version": "0.34.0",
4
4
  "repository": "loopstack-ai/loopstack-studio",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -26,7 +26,7 @@
26
26
  "dependencies": {
27
27
  "@fontsource/roboto": "^5.2.10",
28
28
  "@hookform/resolvers": "^5.2.2",
29
- "@loopstack/contracts": "^0.35.0",
29
+ "@loopstack/contracts": "^0.36.0",
30
30
  "@radix-ui/react-accordion": "^1.2.12",
31
31
  "@radix-ui/react-alert-dialog": "^1.1.15",
32
32
  "@radix-ui/react-avatar": "^1.1.11",