@loopstack/loopstack-studio 0.36.0 → 0.37.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/features/documents/renderers/DocumentMessageRenderer.js +23 -9
- package/dist/features/documents/renderers/LlmMessage.js +90 -50
- package/dist/features/file-explorer/components/FileExplorerPanel.js +66 -73
- package/dist/features/file-explorer/hooks/useFileExplorer.js +29 -25
- package/dist/features/file-explorer/providers/FileExplorerProvider.js +53 -53
- package/dist/features/git/components/WorkbenchGitPanel.js +36 -33
- package/dist/features/git/hooks/useGit.js +36 -33
- package/dist/features/workbench/components/EnvironmentSelector.js +46 -0
- package/dist/features/workbench/providers/WorkbenchLayoutProvider.js +64 -55
- package/dist/packages/contracts/dist/types/types/ui-message.type.js +15 -2
- package/package.json +4 -4
|
@@ -2,7 +2,8 @@ import CompletionMessagePaper_default from "../../../components/messages/Complet
|
|
|
2
2
|
import MarkdownContent_default from "../../../components/dynamic-form/MarkdownContent.js";
|
|
3
3
|
import { c } from "react/compiler-runtime";
|
|
4
4
|
import React from "react";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
5
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
6
|
+
import { Info } from "lucide-react";
|
|
6
7
|
var KNOWN_ROLES = [
|
|
7
8
|
"system",
|
|
8
9
|
"user",
|
|
@@ -10,13 +11,26 @@ var KNOWN_ROLES = [
|
|
|
10
11
|
"tool",
|
|
11
12
|
"error",
|
|
12
13
|
"document"
|
|
13
|
-
], DocumentMessageRenderer_default = (
|
|
14
|
-
let
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
14
|
+
], DocumentMessageRenderer_default = (s) => {
|
|
15
|
+
let l = c(8), { document: u } = s, { role: d, text: f } = u.content, p = KNOWN_ROLES.includes(d ?? "") ? d : void 0;
|
|
16
|
+
if (p === "system") {
|
|
17
|
+
let e;
|
|
18
|
+
l[0] === Symbol.for("react.memo_cache_sentinel") ? (e = /* @__PURE__ */ jsx(Info, { className: "mt-0.5 size-3.5 shrink-0 opacity-70" }), l[0] = e) : e = l[0];
|
|
19
|
+
let o = f ?? "", s;
|
|
20
|
+
return l[1] === o ? s = l[2] : (s = /* @__PURE__ */ jsxs("div", {
|
|
21
|
+
className: "text-muted-foreground flex items-start gap-1.5 px-1 py-0.5 text-sm leading-relaxed [&_p]:m-0",
|
|
22
|
+
children: [e, /* @__PURE__ */ jsx("div", {
|
|
23
|
+
className: "min-w-0",
|
|
24
|
+
children: /* @__PURE__ */ jsx(MarkdownContent_default, { content: o })
|
|
25
|
+
})]
|
|
26
|
+
}), l[1] = o, l[2] = s), s;
|
|
27
|
+
}
|
|
28
|
+
let m = f ?? "", h;
|
|
29
|
+
l[3] === m ? h = l[4] : (h = /* @__PURE__ */ jsx(MarkdownContent_default, { content: m }), l[3] = m, l[4] = h);
|
|
30
|
+
let g;
|
|
31
|
+
return l[5] !== p || l[6] !== h ? (g = /* @__PURE__ */ jsx(CompletionMessagePaper_default, {
|
|
32
|
+
role: p,
|
|
33
|
+
children: h
|
|
34
|
+
}), l[5] = p, l[6] = h, l[7] = g) : g = l[7], g;
|
|
21
35
|
};
|
|
22
36
|
export { DocumentMessageRenderer_default as default };
|
|
@@ -8,16 +8,50 @@ import { Fragment } from "react";
|
|
|
8
8
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
9
9
|
import { CopyIcon } from "lucide-react";
|
|
10
10
|
var CopyActions = (e) => {
|
|
11
|
-
let
|
|
12
|
-
|
|
11
|
+
let g = c(5), { text: _ } = e, v;
|
|
12
|
+
g[0] === _ ? v = g[1] : (v = () => void navigator.clipboard.writeText(_), g[0] = _, g[1] = v);
|
|
13
|
+
let y;
|
|
14
|
+
g[2] === Symbol.for("react.memo_cache_sentinel") ? (y = /* @__PURE__ */ jsx(CopyIcon, { className: "size-3" }), g[2] = y) : y = g[2];
|
|
13
15
|
let b;
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
return _[3] === y ? x = _[4] : (x = /* @__PURE__ */ jsx(FadeInBlock, { children: /* @__PURE__ */ jsx(MessageActions, { children: /* @__PURE__ */ jsx(MessageAction, {
|
|
17
|
-
onClick: y,
|
|
16
|
+
return g[3] === v ? b = g[4] : (b = /* @__PURE__ */ jsx(FadeInBlock, { children: /* @__PURE__ */ jsx(MessageActions, { children: /* @__PURE__ */ jsx(MessageAction, {
|
|
17
|
+
onClick: v,
|
|
18
18
|
label: "Copy",
|
|
19
|
-
children:
|
|
20
|
-
}) }) }),
|
|
19
|
+
children: y
|
|
20
|
+
}) }) }), g[3] = v, g[4] = b), b;
|
|
21
|
+
};
|
|
22
|
+
function formatTokens(e) {
|
|
23
|
+
return e == null ? null : e >= 1e3 ? `${(e / 1e3).toFixed(1)}k` : String(e);
|
|
24
|
+
}
|
|
25
|
+
var CompletionMeta = (e) => {
|
|
26
|
+
let m = c(21), { meta: h } = e, g;
|
|
27
|
+
if (m[0] !== h.costUsd || m[1] !== h.durationMs || m[2] !== h.model || m[3] !== h.numTurns || m[4] !== h.usage?.cacheCreationInputTokens || m[5] !== h.usage?.cacheReadInputTokens || m[6] !== h.usage?.inputTokens || m[7] !== h.usage?.outputTokens) {
|
|
28
|
+
if (g = [], h.numTurns != null && g.push(`${h.numTurns} turn${h.numTurns === 1 ? "" : "s"}`), h.costUsd != null) {
|
|
29
|
+
let e;
|
|
30
|
+
m[9] === h.costUsd ? e = m[10] : (e = h.costUsd.toFixed(4), m[9] = h.costUsd, m[10] = e), g.push(`$${e}`);
|
|
31
|
+
}
|
|
32
|
+
let e = h.usage?.inputTokens, _;
|
|
33
|
+
m[11] === e ? _ = m[12] : (_ = formatTokens(e), m[11] = e, m[12] = _);
|
|
34
|
+
let v = _, y = h.usage?.outputTokens, b;
|
|
35
|
+
m[13] === y ? b = m[14] : (b = formatTokens(y), m[13] = y, m[14] = b);
|
|
36
|
+
let x = b;
|
|
37
|
+
v && x && g.push(`${v} in / ${x} out`);
|
|
38
|
+
let S = (h.usage?.cacheReadInputTokens ?? 0) + (h.usage?.cacheCreationInputTokens ?? 0);
|
|
39
|
+
if (S) {
|
|
40
|
+
let e;
|
|
41
|
+
m[15] === S ? e = m[16] : (e = formatTokens(S), m[15] = S, m[16] = e), g.push(`${e} cache`);
|
|
42
|
+
}
|
|
43
|
+
if (h.durationMs != null) {
|
|
44
|
+
let e = h.durationMs / 1e3, _;
|
|
45
|
+
m[17] === e ? _ = m[18] : (_ = e.toFixed(1), m[17] = e, m[18] = _), g.push(`${_}s`);
|
|
46
|
+
}
|
|
47
|
+
h.model && g.push(h.model), m[0] = h.costUsd, m[1] = h.durationMs, m[2] = h.model, m[3] = h.numTurns, m[4] = h.usage?.cacheCreationInputTokens, m[5] = h.usage?.cacheReadInputTokens, m[6] = h.usage?.inputTokens, m[7] = h.usage?.outputTokens, m[8] = g;
|
|
48
|
+
} else g = m[8];
|
|
49
|
+
if (!g.length) return null;
|
|
50
|
+
let _ = g.join(" · "), v;
|
|
51
|
+
return m[19] === _ ? v = m[20] : (v = /* @__PURE__ */ jsx("div", {
|
|
52
|
+
className: "text-muted-foreground mt-1 px-1 font-mono text-xs",
|
|
53
|
+
children: _
|
|
54
|
+
}), m[19] = _, m[20] = v), v;
|
|
21
55
|
};
|
|
22
56
|
function hasStructuredBlocks(e) {
|
|
23
57
|
return !!e?.some((e) => e.type !== "text");
|
|
@@ -25,81 +59,87 @@ function hasStructuredBlocks(e) {
|
|
|
25
59
|
function textFromBlocks(e) {
|
|
26
60
|
return (e ?? []).filter((e) => e.type === "text").map((e) => e.text).join("\n");
|
|
27
61
|
}
|
|
28
|
-
var LlmMessage_default = (
|
|
29
|
-
let
|
|
30
|
-
if (!hasStructuredBlocks(
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
let
|
|
34
|
-
|
|
62
|
+
var LlmMessage_default = (m) => {
|
|
63
|
+
let h = c(31), { document: w } = m, T = w.content, E = T.id ?? w.id, D = !!w.meta?.streaming;
|
|
64
|
+
if (!hasStructuredBlocks(T.blocks)) {
|
|
65
|
+
let m;
|
|
66
|
+
h[0] !== T.blocks || h[1] !== T.text ? (m = T.text ?? textFromBlocks(T.blocks), h[0] = T.blocks, h[1] = T.text, h[2] = m) : m = h[2];
|
|
67
|
+
let v = m, y;
|
|
68
|
+
h[3] !== D || h[4] !== v ? (y = /* @__PURE__ */ jsx(MessageContent, { children: D ? /* @__PURE__ */ jsx(StreamingText, { text: v }) : /* @__PURE__ */ jsx(MessageResponse, { children: v }) }), h[3] = D, h[4] = v, h[5] = y) : y = h[5];
|
|
69
|
+
let b;
|
|
70
|
+
h[6] !== D || h[7] !== T.role || h[8] !== v ? (b = T.role === "assistant" && !D && /* @__PURE__ */ jsx(CopyActions, { text: v }), h[6] = D, h[7] = T.role, h[8] = v, h[9] = b) : b = h[9];
|
|
35
71
|
let x;
|
|
36
|
-
|
|
72
|
+
h[10] !== T.role || h[11] !== y || h[12] !== b ? (x = /* @__PURE__ */ jsxs(Message, {
|
|
73
|
+
from: T.role,
|
|
74
|
+
children: [y, b]
|
|
75
|
+
}), h[10] = T.role, h[11] = y, h[12] = b, h[13] = x) : x = h[13];
|
|
37
76
|
let S;
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
}), g[10] = w.role, g[11] = b, g[12] = x, g[13] = S) : S = g[13], S;
|
|
77
|
+
h[14] === T.meta ? S = h[15] : (S = T.meta && /* @__PURE__ */ jsx(CompletionMeta, { meta: T.meta }), h[14] = T.meta, h[15] = S);
|
|
78
|
+
let C;
|
|
79
|
+
return h[16] !== x || h[17] !== S ? (C = /* @__PURE__ */ jsxs(Fragment, { children: [x, S] }), h[16] = x, h[17] = S, h[18] = C) : C = h[18], C;
|
|
42
80
|
}
|
|
43
|
-
let
|
|
44
|
-
|
|
45
|
-
let
|
|
46
|
-
|
|
47
|
-
switch (
|
|
81
|
+
let O;
|
|
82
|
+
h[19] === T.blocks ? O = h[20] : (O = T.blocks ?? [], h[19] = T.blocks, h[20] = O);
|
|
83
|
+
let k = O, A;
|
|
84
|
+
h[21] !== k || h[22] !== D || h[23] !== T.role || h[24] !== E ? (A = k.map((m, h) => {
|
|
85
|
+
switch (m.type) {
|
|
48
86
|
case "text": return /* @__PURE__ */ jsxs(Message, {
|
|
49
|
-
from:
|
|
50
|
-
children: [/* @__PURE__ */ jsx(MessageContent, { children:
|
|
51
|
-
}, `${
|
|
87
|
+
from: T.role,
|
|
88
|
+
children: [/* @__PURE__ */ jsx(MessageContent, { children: D ? /* @__PURE__ */ jsx(StreamingText, { text: m.text }) : /* @__PURE__ */ jsx(MessageResponse, { children: m.text }) }), T.role === "assistant" && !D && /* @__PURE__ */ jsx(CopyActions, { text: m.text })]
|
|
89
|
+
}, `${E}-${h}`);
|
|
52
90
|
case "thinking": return /* @__PURE__ */ jsxs(Reasoning, {
|
|
53
91
|
className: "w-full",
|
|
54
|
-
isStreaming:
|
|
55
|
-
children: [/* @__PURE__ */ jsx(ReasoningTrigger, {}), /* @__PURE__ */ jsx(ReasoningContent, { children:
|
|
56
|
-
}, `${
|
|
92
|
+
isStreaming: D,
|
|
93
|
+
children: [/* @__PURE__ */ jsx(ReasoningTrigger, {}), /* @__PURE__ */ jsx(ReasoningContent, { children: m.text })]
|
|
94
|
+
}, `${E}-${h}`);
|
|
57
95
|
case "tool_call": return /* @__PURE__ */ jsx(FadeInBlock, { children: /* @__PURE__ */ jsx(Message, {
|
|
58
96
|
from: "assistant",
|
|
59
97
|
children: /* @__PURE__ */ jsxs(Tool, { children: [/* @__PURE__ */ jsx(ToolHeader, {
|
|
60
98
|
state: "input-available",
|
|
61
|
-
title:
|
|
99
|
+
title: m.name,
|
|
62
100
|
type: "tool-call"
|
|
63
|
-
}), /* @__PURE__ */ jsx(ToolContent, { children: /* @__PURE__ */ jsx(ToolInput, { input:
|
|
64
|
-
}) }, `${
|
|
101
|
+
}), /* @__PURE__ */ jsx(ToolContent, { children: /* @__PURE__ */ jsx(ToolInput, { input: m.args }) })] })
|
|
102
|
+
}) }, `${E}-${h}`);
|
|
65
103
|
case "tool_result": {
|
|
66
|
-
let
|
|
104
|
+
let g;
|
|
67
105
|
try {
|
|
68
|
-
|
|
106
|
+
g = JSON.parse(m.content);
|
|
69
107
|
} catch {
|
|
70
|
-
|
|
108
|
+
g = m.content;
|
|
71
109
|
}
|
|
72
110
|
return /* @__PURE__ */ jsx(FadeInBlock, { children: /* @__PURE__ */ jsx(Message, {
|
|
73
111
|
from: "assistant",
|
|
74
112
|
children: /* @__PURE__ */ jsxs(Tool, { children: [/* @__PURE__ */ jsx(ToolHeader, {
|
|
75
|
-
state:
|
|
113
|
+
state: m.isError ? "output-error" : "output-available",
|
|
76
114
|
title: "Tool Result",
|
|
77
115
|
type: "tool-call"
|
|
78
116
|
}), /* @__PURE__ */ jsx(ToolContent, { children: /* @__PURE__ */ jsx(ToolOutput, {
|
|
79
|
-
output:
|
|
80
|
-
errorText:
|
|
117
|
+
output: g,
|
|
118
|
+
errorText: m.isError ? m.content : ""
|
|
81
119
|
}) })] })
|
|
82
|
-
}) }, `${
|
|
120
|
+
}) }, `${E}-${h}`);
|
|
83
121
|
}
|
|
84
122
|
case "server_tool_use": {
|
|
85
|
-
let
|
|
123
|
+
let g = k.find((e) => e.type === "server_tool_result" && e.toolUseId === m.id);
|
|
86
124
|
return /* @__PURE__ */ jsx(FadeInBlock, { children: /* @__PURE__ */ jsx(Message, {
|
|
87
125
|
from: "assistant",
|
|
88
126
|
children: /* @__PURE__ */ jsxs(Tool, { children: [/* @__PURE__ */ jsx(ToolHeader, {
|
|
89
|
-
state:
|
|
90
|
-
title:
|
|
127
|
+
state: g ? "output-available" : "input-available",
|
|
128
|
+
title: m.name,
|
|
91
129
|
type: "tool-call"
|
|
92
|
-
}), /* @__PURE__ */ jsxs(ToolContent, { children: [/* @__PURE__ */ jsx(ToolInput, { input:
|
|
93
|
-
output:
|
|
130
|
+
}), /* @__PURE__ */ jsxs(ToolContent, { children: [/* @__PURE__ */ jsx(ToolInput, { input: m.input }), g && /* @__PURE__ */ jsx(ToolOutput, {
|
|
131
|
+
output: g.content,
|
|
94
132
|
errorText: ""
|
|
95
133
|
})] })] })
|
|
96
|
-
}) }, `${
|
|
134
|
+
}) }, `${E}-${h}`);
|
|
97
135
|
}
|
|
98
136
|
case "server_tool_result": return null;
|
|
99
137
|
default: return null;
|
|
100
138
|
}
|
|
101
|
-
}),
|
|
102
|
-
let
|
|
103
|
-
|
|
139
|
+
}), h[21] = k, h[22] = D, h[23] = T.role, h[24] = E, h[25] = A) : A = h[25];
|
|
140
|
+
let j;
|
|
141
|
+
h[26] === T.meta ? j = h[27] : (j = T.meta && /* @__PURE__ */ jsx(CompletionMeta, { meta: T.meta }), h[26] = T.meta, h[27] = j);
|
|
142
|
+
let M;
|
|
143
|
+
return h[28] !== A || h[29] !== j ? (M = /* @__PURE__ */ jsxs(Fragment, { children: [A, j] }), h[28] = A, h[29] = j, h[30] = M) : M = h[30], M;
|
|
104
144
|
};
|
|
105
145
|
export { LlmMessage_default as default };
|
|
@@ -5,6 +5,7 @@ import "../../feature-registry/index.js";
|
|
|
5
5
|
import { useWorkbenchLayout } from "../../workbench/providers/WorkbenchLayoutProvider.js";
|
|
6
6
|
import { SidebarPanel } from "../../workbench/components/SidebarPanel.js";
|
|
7
7
|
import "../../workbench/index.js";
|
|
8
|
+
import { EnvironmentSelector } from "../../workbench/components/EnvironmentSelector.js";
|
|
8
9
|
import { FileExplorerProvider, useOptionalFileExplorer } from "../providers/FileExplorerProvider.js";
|
|
9
10
|
import { FileTabsBar } from "./FileTabsBar.js";
|
|
10
11
|
import { FileTree } from "./FileTree.js";
|
|
@@ -12,109 +13,101 @@ import { c } from "react/compiler-runtime";
|
|
|
12
13
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
13
14
|
import { Files } from "lucide-react";
|
|
14
15
|
function FileExplorerContent() {
|
|
15
|
-
let
|
|
16
|
-
if (!
|
|
16
|
+
let o = c(7), s = useOptionalFileExplorer();
|
|
17
|
+
if (!s) {
|
|
17
18
|
let e;
|
|
18
|
-
return
|
|
19
|
+
return o[0] === Symbol.for("react.memo_cache_sentinel") ? (e = /* @__PURE__ */ jsx("div", {
|
|
19
20
|
className: "flex flex-1 items-center justify-center p-4",
|
|
20
21
|
children: /* @__PURE__ */ jsx("p", {
|
|
21
22
|
className: "text-muted-foreground text-sm",
|
|
22
23
|
children: "File explorer is not available for this workspace."
|
|
23
24
|
})
|
|
24
|
-
}),
|
|
25
|
+
}), o[0] = e) : e = o[0], e;
|
|
25
26
|
}
|
|
26
|
-
let
|
|
27
|
-
|
|
27
|
+
let l;
|
|
28
|
+
o[1] === Symbol.for("react.memo_cache_sentinel") ? (l = /* @__PURE__ */ jsx("div", {
|
|
28
29
|
className: "w-52 shrink-0 overflow-auto border-r bg-muted/40",
|
|
29
30
|
children: /* @__PURE__ */ jsx(FileTree, {})
|
|
30
|
-
}),
|
|
31
|
-
let
|
|
32
|
-
|
|
33
|
-
let
|
|
34
|
-
return
|
|
31
|
+
}), o[1] = l) : l = o[1];
|
|
32
|
+
let u;
|
|
33
|
+
o[2] === Symbol.for("react.memo_cache_sentinel") ? (u = /* @__PURE__ */ jsx(FileTabsBar, {}), o[2] = u) : u = o[2];
|
|
34
|
+
let d;
|
|
35
|
+
return o[3] !== s.fileContent || o[4] !== s.isContentLoading || o[5] !== s.selectedFile ? (d = /* @__PURE__ */ jsxs("div", {
|
|
35
36
|
className: "flex h-full",
|
|
36
|
-
children: [
|
|
37
|
+
children: [l, /* @__PURE__ */ jsxs("div", {
|
|
37
38
|
className: "flex min-w-0 flex-1 flex-col",
|
|
38
|
-
children: [
|
|
39
|
+
children: [u, /* @__PURE__ */ jsx("div", {
|
|
39
40
|
className: "flex-1 overflow-hidden p-3 pt-2",
|
|
40
41
|
children: /* @__PURE__ */ jsx(FileContentViewer, {
|
|
41
|
-
selectedFile:
|
|
42
|
-
content:
|
|
43
|
-
isLoading:
|
|
42
|
+
selectedFile: s.selectedFile,
|
|
43
|
+
content: s.fileContent,
|
|
44
|
+
isLoading: s.isContentLoading,
|
|
44
45
|
className: "h-full"
|
|
45
46
|
})
|
|
46
47
|
})]
|
|
47
48
|
})]
|
|
48
|
-
}),
|
|
49
|
+
}), o[3] = s.fileContent, o[4] = s.isContentLoading, o[5] = s.selectedFile, o[6] = d) : d = o[6], d;
|
|
49
50
|
}
|
|
50
51
|
function FileExplorerPanel(e) {
|
|
51
|
-
let
|
|
52
|
-
|
|
53
|
-
let
|
|
54
|
-
|
|
55
|
-
let
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
icon: E,
|
|
92
|
-
title: f,
|
|
93
|
-
description: m,
|
|
94
|
-
size: _,
|
|
95
|
-
onSizeChange: v,
|
|
96
|
-
onClose: g,
|
|
97
|
-
children: O
|
|
98
|
-
}), l[19] = g, l[20] = m, l[21] = _, l[22] = v, l[23] = O, l[24] = f, l[25] = k) : k = l[25], k;
|
|
52
|
+
let f = c(24), { variant: p, featureId: m, title: h, description: g, workspaceId: _ } = e, { closePanel: v, panelSize: y, setPanelSize: b, environments: x, selectedSlotId: S } = useWorkbenchLayout(), C = useFeatureConfig(m), w;
|
|
53
|
+
f[0] === C?.config?.environments ? w = f[1] : (w = C?.config?.environments ?? [], f[0] = C?.config?.environments, f[1] = w);
|
|
54
|
+
let T = w, E;
|
|
55
|
+
f[2] !== x || f[3] !== S ? (E = x?.find((e) => e.slotId === S), f[2] = x, f[3] = S, f[4] = E) : E = f[4];
|
|
56
|
+
let D = E, O;
|
|
57
|
+
f[5] !== T || f[6] !== S ? (O = T.length === 0 || T.includes(S), f[5] = T, f[6] = S, f[7] = O) : O = f[7];
|
|
58
|
+
let k = O, A = !D || D.status === "running", j = k && A, M;
|
|
59
|
+
f[8] === Symbol.for("react.memo_cache_sentinel") ? (M = /* @__PURE__ */ jsx(Files, { className: "h-4 w-4" }), f[8] = M) : M = f[8];
|
|
60
|
+
let N;
|
|
61
|
+
f[9] === Symbol.for("react.memo_cache_sentinel") ? (N = /* @__PURE__ */ jsx(EnvironmentSelector, {}), f[9] = N) : N = f[9];
|
|
62
|
+
let P;
|
|
63
|
+
f[10] !== k || f[11] !== j || f[12] !== A || f[13] !== S || f[14] !== p || f[15] !== _ ? (P = k ? A ? /* @__PURE__ */ jsx(FileExplorerProvider, {
|
|
64
|
+
variant: p,
|
|
65
|
+
workspaceId: _,
|
|
66
|
+
slotId: S || void 0,
|
|
67
|
+
enabled: j,
|
|
68
|
+
children: /* @__PURE__ */ jsx(FileExplorerContent, {})
|
|
69
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
70
|
+
className: "flex flex-1 items-center justify-center p-4",
|
|
71
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
72
|
+
className: "text-muted-foreground text-sm",
|
|
73
|
+
children: "This environment is not available (stopped)."
|
|
74
|
+
})
|
|
75
|
+
}) : /* @__PURE__ */ jsx("div", {
|
|
76
|
+
className: "flex flex-1 items-center justify-center p-4",
|
|
77
|
+
children: /* @__PURE__ */ jsx("p", {
|
|
78
|
+
className: "text-muted-foreground text-sm",
|
|
79
|
+
children: "File explorer is not available for this environment."
|
|
80
|
+
})
|
|
81
|
+
}), f[10] = k, f[11] = j, f[12] = A, f[13] = S, f[14] = p, f[15] = _, f[16] = P) : P = f[16];
|
|
82
|
+
let F;
|
|
83
|
+
return f[17] !== v || f[18] !== g || f[19] !== y || f[20] !== b || f[21] !== P || f[22] !== h ? (F = /* @__PURE__ */ jsxs(SidebarPanel, {
|
|
84
|
+
icon: M,
|
|
85
|
+
title: h,
|
|
86
|
+
description: g,
|
|
87
|
+
size: y,
|
|
88
|
+
onSizeChange: b,
|
|
89
|
+
onClose: v,
|
|
90
|
+
children: [N, P]
|
|
91
|
+
}), f[17] = v, f[18] = g, f[19] = y, f[20] = b, f[21] = P, f[22] = h, f[23] = F) : F = f[23], F;
|
|
99
92
|
}
|
|
100
93
|
function LocalFileExplorerPanel(e) {
|
|
101
|
-
let
|
|
102
|
-
return
|
|
94
|
+
let o = c(2), { workspaceId: s } = e, l;
|
|
95
|
+
return o[0] === s ? l = o[1] : (l = /* @__PURE__ */ jsx(FileExplorerPanel, {
|
|
103
96
|
variant: "local",
|
|
104
97
|
featureId: "localFileExplorer",
|
|
105
98
|
title: "Files",
|
|
106
99
|
description: "Browse and view local project files.",
|
|
107
|
-
workspaceId:
|
|
108
|
-
}),
|
|
100
|
+
workspaceId: s
|
|
101
|
+
}), o[0] = s, o[1] = l), l;
|
|
109
102
|
}
|
|
110
103
|
function RemoteFileExplorerPanel(e) {
|
|
111
|
-
let
|
|
112
|
-
return
|
|
104
|
+
let o = c(2), { workspaceId: s } = e, l;
|
|
105
|
+
return o[0] === s ? l = o[1] : (l = /* @__PURE__ */ jsx(FileExplorerPanel, {
|
|
113
106
|
variant: "remote",
|
|
114
107
|
featureId: "remoteFileExplorer",
|
|
115
108
|
title: "Remote Files",
|
|
116
109
|
description: "Browse and view files on the remote workspace.",
|
|
117
|
-
workspaceId:
|
|
118
|
-
}),
|
|
110
|
+
workspaceId: s
|
|
111
|
+
}), o[0] = s, o[1] = l), l;
|
|
119
112
|
}
|
|
120
113
|
export { LocalFileExplorerPanel, RemoteFileExplorerPanel };
|
|
@@ -14,38 +14,42 @@ function fileTreeKey(e, n, r) {
|
|
|
14
14
|
...r ? [r] : []
|
|
15
15
|
];
|
|
16
16
|
}
|
|
17
|
-
function useFileTree(i, o, s) {
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
let
|
|
21
|
-
|
|
22
|
-
let
|
|
23
|
-
return
|
|
24
|
-
queryKey:
|
|
25
|
-
queryFn:
|
|
26
|
-
enabled:
|
|
17
|
+
function useFileTree(i, o, s, l) {
|
|
18
|
+
let u = c(14), d = l === void 0 ? !0 : l, f = useLoopstackClient(), p;
|
|
19
|
+
u[0] !== f.envKey || u[1] !== s || u[2] !== i || u[3] !== o ? (p = [...fileTreeKey(f.envKey, i, o), s ?? ""], u[0] = f.envKey, u[1] = s, u[2] = i, u[3] = o, u[4] = p) : p = u[4];
|
|
20
|
+
let m;
|
|
21
|
+
u[5] !== f.http || u[6] !== s || u[7] !== i || u[8] !== o ? (m = () => f.http.get(`${explorerPath(i, o)}/tree`, s ? { slotId: s } : void 0), u[5] = f.http, u[6] = s, u[7] = i, u[8] = o, u[9] = m) : m = u[9];
|
|
22
|
+
let h = !!o && d, g;
|
|
23
|
+
return u[10] !== p || u[11] !== m || u[12] !== h ? (g = {
|
|
24
|
+
queryKey: p,
|
|
25
|
+
queryFn: m,
|
|
26
|
+
enabled: h,
|
|
27
27
|
staleTime: 3e4,
|
|
28
28
|
retry: !1
|
|
29
|
-
},
|
|
29
|
+
}, u[10] = p, u[11] = m, u[12] = h, u[13] = g) : g = u[13], useQuery(g);
|
|
30
30
|
}
|
|
31
|
-
function useFileContent(i, a, o, s) {
|
|
32
|
-
let
|
|
33
|
-
|
|
31
|
+
function useFileContent(i, a, o, s, l) {
|
|
32
|
+
let u = c(16), d = l === void 0 ? !0 : l, f = useLoopstackClient(), p = s ?? "", m;
|
|
33
|
+
u[0] !== f.envKey || u[1] !== o || u[2] !== p || u[3] !== i || u[4] !== a ? (m = [
|
|
34
34
|
"file-explorer-content",
|
|
35
|
-
|
|
35
|
+
f.envKey,
|
|
36
36
|
i,
|
|
37
37
|
a,
|
|
38
|
-
o
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
38
|
+
o,
|
|
39
|
+
p
|
|
40
|
+
], u[0] = f.envKey, u[1] = o, u[2] = p, u[3] = i, u[4] = a, u[5] = m) : m = u[5];
|
|
41
|
+
let h;
|
|
42
|
+
u[6] !== f.http || u[7] !== o || u[8] !== s || u[9] !== i || u[10] !== a ? (h = () => f.http.get(`${explorerPath(i, a)}/read`, {
|
|
43
|
+
path: o,
|
|
44
|
+
...s ? { slotId: s } : {}
|
|
45
|
+
}), u[6] = f.http, u[7] = o, u[8] = s, u[9] = i, u[10] = a, u[11] = h) : h = u[11];
|
|
46
|
+
let g = !!a && !!o && d, _;
|
|
47
|
+
return u[12] !== m || u[13] !== h || u[14] !== g ? (_ = {
|
|
48
|
+
queryKey: m,
|
|
49
|
+
queryFn: h,
|
|
50
|
+
enabled: g,
|
|
47
51
|
staleTime: 15e3,
|
|
48
52
|
retry: !1
|
|
49
|
-
},
|
|
53
|
+
}, u[12] = m, u[13] = h, u[14] = g, u[15] = _) : _ = u[15], useQuery(_);
|
|
50
54
|
}
|
|
51
55
|
export { fileTreeKey, useFileContent, useFileTree };
|
|
@@ -6,78 +6,78 @@ import { createContext, useCallback, useContext, useMemo, useState } from "react
|
|
|
6
6
|
import { jsx } from "react/jsx-runtime";
|
|
7
7
|
import { useQueryClient } from "@tanstack/react-query";
|
|
8
8
|
var FileExplorerContext = createContext(null);
|
|
9
|
-
function FileExplorerProvider(
|
|
10
|
-
let
|
|
11
|
-
|
|
9
|
+
function FileExplorerProvider(l) {
|
|
10
|
+
let u = c(37), { variant: d, workspaceId: f, slotId: p, enabled: m, children: h } = l, g = m === void 0 ? !0 : m, _ = useLoopstackClient(), v = useQueryClient(), y;
|
|
11
|
+
u[0] === Symbol.for("react.memo_cache_sentinel") ? (y = /* @__PURE__ */ new Set(), u[0] = y) : y = u[0];
|
|
12
12
|
let [b, x] = useState(y), S;
|
|
13
|
-
|
|
14
|
-
let [C, w] = useState(S), [T, E] = useState(null), D = useFileTree(f, p, g), O = useFileContent(
|
|
15
|
-
|
|
16
|
-
x((
|
|
17
|
-
let
|
|
18
|
-
return
|
|
13
|
+
u[1] === Symbol.for("react.memo_cache_sentinel") ? (S = [], u[1] = S) : S = u[1];
|
|
14
|
+
let [C, w] = useState(S), [T, E] = useState(null), D = useFileTree(d, f, p, g), O = useFileContent(d, f, T?.type === "file" ? T.path : void 0, p, g), k;
|
|
15
|
+
u[2] === Symbol.for("react.memo_cache_sentinel") ? (k = (e) => {
|
|
16
|
+
x((a) => {
|
|
17
|
+
let o = new Set(a);
|
|
18
|
+
return o.has(e) ? o.delete(e) : o.add(e), o;
|
|
19
19
|
});
|
|
20
|
-
},
|
|
20
|
+
}, u[2] = k) : k = u[2];
|
|
21
21
|
let A = k, j;
|
|
22
|
-
|
|
23
|
-
e.type === "file" && (E(e), w((
|
|
24
|
-
},
|
|
22
|
+
u[3] === Symbol.for("react.memo_cache_sentinel") ? (j = (e) => {
|
|
23
|
+
e.type === "file" && (E(e), w((a) => a.some((a) => a.path === e.path) ? a : [...a, e]));
|
|
24
|
+
}, u[3] = j) : j = u[3];
|
|
25
25
|
let M = j, N;
|
|
26
|
-
|
|
27
|
-
w((
|
|
28
|
-
let
|
|
29
|
-
if (T?.path === e.path) if (
|
|
30
|
-
let
|
|
31
|
-
E(
|
|
26
|
+
u[4] === T?.path ? N = u[5] : (N = (e) => {
|
|
27
|
+
w((a) => {
|
|
28
|
+
let o = a.filter((a) => a.path !== e.path);
|
|
29
|
+
if (T?.path === e.path) if (o.length > 0) {
|
|
30
|
+
let s = a.findIndex((a) => a.path === e.path);
|
|
31
|
+
E(o[Math.max(0, s - 1)]);
|
|
32
32
|
} else E(null);
|
|
33
|
-
return
|
|
33
|
+
return o;
|
|
34
34
|
});
|
|
35
|
-
},
|
|
35
|
+
}, u[4] = T?.path, u[5] = N);
|
|
36
36
|
let P = N, F;
|
|
37
|
-
|
|
37
|
+
u[6] === T ? F = u[7] : (F = () => {
|
|
38
38
|
T && w((e) => {
|
|
39
|
-
let
|
|
40
|
-
if (
|
|
41
|
-
let
|
|
42
|
-
E(
|
|
39
|
+
let a = e.filter((e) => e.path !== T.path);
|
|
40
|
+
if (a.length > 0) {
|
|
41
|
+
let o = e.findIndex((e) => e.path === T.path);
|
|
42
|
+
E(a[Math.max(0, o - 1)]);
|
|
43
43
|
} else E(null);
|
|
44
|
-
return
|
|
44
|
+
return a;
|
|
45
45
|
});
|
|
46
|
-
},
|
|
46
|
+
}, u[6] = T, u[7] = F);
|
|
47
47
|
let I = F, L;
|
|
48
|
-
|
|
48
|
+
u[8] === Symbol.for("react.memo_cache_sentinel") ? (L = () => {
|
|
49
49
|
w([]), E(null);
|
|
50
|
-
},
|
|
50
|
+
}, u[8] = L) : L = u[8];
|
|
51
51
|
let R = L, z;
|
|
52
|
-
|
|
52
|
+
u[9] === Symbol.for("react.memo_cache_sentinel") ? (z = (e) => {
|
|
53
53
|
w([e]), E(e);
|
|
54
|
-
},
|
|
54
|
+
}, u[9] = z) : z = u[9];
|
|
55
55
|
let B = z, V;
|
|
56
|
-
|
|
57
|
-
w((
|
|
58
|
-
let
|
|
59
|
-
if (
|
|
60
|
-
let
|
|
61
|
-
return T &&
|
|
56
|
+
u[10] === T ? V = u[11] : (V = (e) => {
|
|
57
|
+
w((a) => {
|
|
58
|
+
let o = a.findIndex((a) => a.path === e.path);
|
|
59
|
+
if (o <= 0) return a;
|
|
60
|
+
let s = a.slice(o);
|
|
61
|
+
return T && a.findIndex((e) => e.path === T.path) < o && E(e), s;
|
|
62
62
|
});
|
|
63
|
-
},
|
|
63
|
+
}, u[10] = T, u[11] = V);
|
|
64
64
|
let H = V, U;
|
|
65
|
-
|
|
66
|
-
w((
|
|
67
|
-
let
|
|
68
|
-
if (
|
|
69
|
-
let
|
|
70
|
-
return T &&
|
|
65
|
+
u[12] === T ? U = u[13] : (U = (e) => {
|
|
66
|
+
w((a) => {
|
|
67
|
+
let o = a.findIndex((a) => a.path === e.path);
|
|
68
|
+
if (o < 0 || o >= a.length - 1) return a;
|
|
69
|
+
let s = a.slice(0, o + 1);
|
|
70
|
+
return T && a.findIndex((e) => e.path === T.path) > o && E(e), s;
|
|
71
71
|
});
|
|
72
|
-
},
|
|
72
|
+
}, u[12] = T, u[13] = U);
|
|
73
73
|
let W = U, G;
|
|
74
|
-
|
|
74
|
+
u[14] !== _.envKey || u[15] !== v ? (G = () => {
|
|
75
75
|
v.invalidateQueries({ queryKey: fileTreeKey(_.envKey) });
|
|
76
|
-
},
|
|
76
|
+
}, u[14] = _.envKey, u[15] = v, u[16] = G) : G = u[16];
|
|
77
77
|
let K = G, q;
|
|
78
|
-
|
|
78
|
+
u[17] === D.data ? q = u[18] : (q = D.data ?? [], u[17] = D.data, u[18] = q);
|
|
79
79
|
let J = D.isLoading && !D.data, Y = O.data?.content ?? null, X = O.isLoading && !!T, Z;
|
|
80
|
-
|
|
80
|
+
u[19] !== I || u[20] !== P || u[21] !== H || u[22] !== W || u[23] !== b || u[24] !== C || u[25] !== K || u[26] !== T || u[27] !== q || u[28] !== J || u[29] !== Y || u[30] !== X || u[31] !== D.error || u[32] !== D.isFetching ? (Z = {
|
|
81
81
|
nodes: q,
|
|
82
82
|
isTreeLoading: J,
|
|
83
83
|
treeError: D.error,
|
|
@@ -96,12 +96,12 @@ function FileExplorerProvider(u) {
|
|
|
96
96
|
closeToRight: W,
|
|
97
97
|
clearSelection: I,
|
|
98
98
|
refreshTree: K
|
|
99
|
-
},
|
|
99
|
+
}, u[19] = I, u[20] = P, u[21] = H, u[22] = W, u[23] = b, u[24] = C, u[25] = K, u[26] = T, u[27] = q, u[28] = J, u[29] = Y, u[30] = X, u[31] = D.error, u[32] = D.isFetching, u[33] = Z) : Z = u[33];
|
|
100
100
|
let Q = Z, $;
|
|
101
|
-
return
|
|
101
|
+
return u[34] !== h || u[35] !== Q ? ($ = /* @__PURE__ */ jsx(FileExplorerContext.Provider, {
|
|
102
102
|
value: Q,
|
|
103
103
|
children: h
|
|
104
|
-
}),
|
|
104
|
+
}), u[34] = h, u[35] = Q, u[36] = $) : $ = u[36], $;
|
|
105
105
|
}
|
|
106
106
|
function useFileExplorer() {
|
|
107
107
|
let e = useContext(FileExplorerContext);
|
|
@@ -5,6 +5,7 @@ import "../../../hooks/useProcessor.js";
|
|
|
5
5
|
import { useWorkbenchLayout } from "../../workbench/providers/WorkbenchLayoutProvider.js";
|
|
6
6
|
import { SidebarPanel } from "../../workbench/components/SidebarPanel.js";
|
|
7
7
|
import "../../workbench/index.js";
|
|
8
|
+
import { EnvironmentSelector } from "../../workbench/components/EnvironmentSelector.js";
|
|
8
9
|
import { useGitInvalidation, useGitLog, useGitRemote, useGitStatus, useRemoveGitRemote } from "../hooks/useGit.js";
|
|
9
10
|
import { GitBranchBadge } from "./GitBranchBadge.js";
|
|
10
11
|
import { GitCommitList } from "./GitCommitList.js";
|
|
@@ -12,31 +13,33 @@ import { GitRemoteStatus } from "./GitRemoteStatus.js";
|
|
|
12
13
|
import { c } from "react/compiler-runtime";
|
|
13
14
|
import { jsx, jsxs } from "react/jsx-runtime";
|
|
14
15
|
import { GitBranch, Loader2 } from "lucide-react";
|
|
15
|
-
function WorkbenchGitPanel(
|
|
16
|
-
let
|
|
17
|
-
useGitInvalidation(
|
|
18
|
-
let
|
|
19
|
-
|
|
20
|
-
|
|
16
|
+
function WorkbenchGitPanel(b) {
|
|
17
|
+
let x = c(21), { workspaceId: S } = b, { panelSize: C, setPanelSize: w, closePanel: T, selectedSlotId: E } = useWorkbenchLayout(), { router: D } = useStudio(), { data: O, isLoading: k } = useGitStatus(S, E), { data: A, isLoading: j } = useGitLog(S, 50, E), { data: M } = useGitRemote(S, E);
|
|
18
|
+
useGitInvalidation(S);
|
|
19
|
+
let N = useCreateWorkflow(), P = useRunWorkflow(), F = useRemoveGitRemote(), I = N.isPending || P.isPending, L;
|
|
20
|
+
x[0] !== N || x[1] !== D || x[2] !== P || x[3] !== S ? (L = () => {
|
|
21
|
+
S && N.mutate({
|
|
21
22
|
workflowName: "connectGitHub",
|
|
22
23
|
title: null,
|
|
23
|
-
workspaceId:
|
|
24
|
+
workspaceId: S,
|
|
24
25
|
transition: null,
|
|
25
26
|
args: {}
|
|
26
27
|
}, { onSuccess: (t) => {
|
|
27
|
-
|
|
28
|
-
|
|
28
|
+
P.mutate({ workflowId: t.id }, { onSuccess: () => {
|
|
29
|
+
D.navigateToWorkflow(t.id);
|
|
29
30
|
} });
|
|
30
31
|
} });
|
|
31
|
-
},
|
|
32
|
-
let
|
|
33
|
-
|
|
34
|
-
let
|
|
35
|
-
|
|
32
|
+
}, x[0] = N, x[1] = D, x[2] = P, x[3] = S, x[4] = L) : L = x[4];
|
|
33
|
+
let R = L, z = k || j, B;
|
|
34
|
+
x[5] === Symbol.for("react.memo_cache_sentinel") ? (B = /* @__PURE__ */ jsx(GitBranch, { className: "h-4 w-4" }), x[5] = B) : B = x[5];
|
|
35
|
+
let V;
|
|
36
|
+
x[6] === Symbol.for("react.memo_cache_sentinel") ? (V = /* @__PURE__ */ jsx(EnvironmentSelector, {}), x[6] = V) : V = x[6];
|
|
37
|
+
let H;
|
|
38
|
+
x[7] !== R || x[8] !== I || x[9] !== z || x[10] !== A?.commits || x[11] !== M || x[12] !== F || x[13] !== O || x[14] !== S ? (H = /* @__PURE__ */ jsxs("div", {
|
|
36
39
|
className: "flex h-full flex-col",
|
|
37
|
-
children: /* @__PURE__ */ jsx("div", {
|
|
40
|
+
children: [V, /* @__PURE__ */ jsx("div", {
|
|
38
41
|
className: "flex-1 overflow-y-auto px-4 py-3",
|
|
39
|
-
children:
|
|
42
|
+
children: z ? /* @__PURE__ */ jsxs("div", {
|
|
40
43
|
className: "flex items-center gap-2 py-4",
|
|
41
44
|
children: [/* @__PURE__ */ jsx(Loader2, { className: "h-4 w-4 animate-spin" }), /* @__PURE__ */ jsx("span", {
|
|
42
45
|
className: "text-muted-foreground text-sm",
|
|
@@ -45,34 +48,34 @@ function WorkbenchGitPanel(y) {
|
|
|
45
48
|
}) : /* @__PURE__ */ jsxs("div", {
|
|
46
49
|
className: "space-y-4",
|
|
47
50
|
children: [
|
|
48
|
-
|
|
51
|
+
O && /* @__PURE__ */ jsx(GitBranchBadge, { status: O }),
|
|
49
52
|
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h4", {
|
|
50
53
|
className: "mb-2 text-xs font-medium uppercase text-muted-foreground",
|
|
51
54
|
children: "Remote"
|
|
52
55
|
}), /* @__PURE__ */ jsx(GitRemoteStatus, {
|
|
53
|
-
remote:
|
|
54
|
-
onConnect:
|
|
55
|
-
isConnecting:
|
|
56
|
-
onRemove:
|
|
57
|
-
isRemoving:
|
|
56
|
+
remote: M,
|
|
57
|
+
onConnect: R,
|
|
58
|
+
isConnecting: I,
|
|
59
|
+
onRemove: S ? () => F.mutate({ workspaceId: S }) : void 0,
|
|
60
|
+
isRemoving: F.isPending
|
|
58
61
|
})] }),
|
|
59
62
|
/* @__PURE__ */ jsxs("div", { children: [/* @__PURE__ */ jsx("h4", {
|
|
60
63
|
className: "mb-2 text-xs font-medium uppercase text-muted-foreground",
|
|
61
64
|
children: "Recent Commits"
|
|
62
|
-
}), /* @__PURE__ */ jsx(GitCommitList, { commits:
|
|
65
|
+
}), /* @__PURE__ */ jsx(GitCommitList, { commits: A?.commits ?? [] })] })
|
|
63
66
|
]
|
|
64
67
|
})
|
|
65
|
-
})
|
|
66
|
-
}),
|
|
67
|
-
let
|
|
68
|
-
return
|
|
69
|
-
icon:
|
|
68
|
+
})]
|
|
69
|
+
}), x[7] = R, x[8] = I, x[9] = z, x[10] = A?.commits, x[11] = M, x[12] = F, x[13] = O, x[14] = S, x[15] = H) : H = x[15];
|
|
70
|
+
let U;
|
|
71
|
+
return x[16] !== T || x[17] !== C || x[18] !== w || x[19] !== H ? (U = /* @__PURE__ */ jsx(SidebarPanel, {
|
|
72
|
+
icon: B,
|
|
70
73
|
title: "Git",
|
|
71
74
|
description: "Source control for this workspace.",
|
|
72
|
-
size:
|
|
73
|
-
onSizeChange:
|
|
74
|
-
onClose:
|
|
75
|
-
children:
|
|
76
|
-
}),
|
|
75
|
+
size: C,
|
|
76
|
+
onSizeChange: w,
|
|
77
|
+
onClose: T,
|
|
78
|
+
children: H
|
|
79
|
+
}), x[16] = T, x[17] = C, x[18] = w, x[19] = H, x[20] = U) : U = x[20], U;
|
|
77
80
|
}
|
|
78
81
|
export { WorkbenchGitPanel };
|
|
@@ -6,47 +6,50 @@ import { c } from "react/compiler-runtime";
|
|
|
6
6
|
import { useEffect } from "react";
|
|
7
7
|
import { useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
8
8
|
var gitPath = (e) => `/api/v1/workspaces/${e}/git`;
|
|
9
|
-
function useGitStatus(r) {
|
|
10
|
-
let
|
|
11
|
-
|
|
12
|
-
let
|
|
13
|
-
|
|
14
|
-
let
|
|
15
|
-
return
|
|
16
|
-
queryKey:
|
|
17
|
-
queryFn:
|
|
18
|
-
enabled:
|
|
9
|
+
function useGitStatus(r, i) {
|
|
10
|
+
let o = c(12), l = useLoopstackClient(), u;
|
|
11
|
+
o[0] !== l.envKey || o[1] !== i || o[2] !== r ? (u = [...queryKeys.gitStatus(l.envKey, r), i ?? ""], o[0] = l.envKey, o[1] = i, o[2] = r, o[3] = u) : u = o[3];
|
|
12
|
+
let d;
|
|
13
|
+
o[4] !== l.http || o[5] !== i || o[6] !== r ? (d = () => l.http.get(`${gitPath(r)}/status`, i ? { slotId: i } : void 0), o[4] = l.http, o[5] = i, o[6] = r, o[7] = d) : d = o[7];
|
|
14
|
+
let f = !!r, p;
|
|
15
|
+
return o[8] !== u || o[9] !== d || o[10] !== f ? (p = {
|
|
16
|
+
queryKey: u,
|
|
17
|
+
queryFn: d,
|
|
18
|
+
enabled: f,
|
|
19
19
|
staleTime: 3e4,
|
|
20
20
|
retry: !1
|
|
21
|
-
},
|
|
21
|
+
}, o[8] = u, o[9] = d, o[10] = f, o[11] = p) : p = o[11], useQuery(p);
|
|
22
22
|
}
|
|
23
|
-
function useGitLog(r, i) {
|
|
24
|
-
let
|
|
25
|
-
|
|
26
|
-
let
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
23
|
+
function useGitLog(r, i, o) {
|
|
24
|
+
let l = c(13), u = i === void 0 ? 50 : i, d = useLoopstackClient(), f;
|
|
25
|
+
l[0] !== d.envKey || l[1] !== o || l[2] !== r ? (f = [...queryKeys.gitLog(d.envKey, r), o ?? ""], l[0] = d.envKey, l[1] = o, l[2] = r, l[3] = f) : f = l[3];
|
|
26
|
+
let p;
|
|
27
|
+
l[4] !== d.http || l[5] !== u || l[6] !== o || l[7] !== r ? (p = () => d.http.get(`${gitPath(r)}/log`, {
|
|
28
|
+
limit: u,
|
|
29
|
+
...o ? { slotId: o } : {}
|
|
30
|
+
}), l[4] = d.http, l[5] = u, l[6] = o, l[7] = r, l[8] = p) : p = l[8];
|
|
31
|
+
let m = !!r, h;
|
|
32
|
+
return l[9] !== f || l[10] !== p || l[11] !== m ? (h = {
|
|
33
|
+
queryKey: f,
|
|
34
|
+
queryFn: p,
|
|
35
|
+
enabled: m,
|
|
33
36
|
staleTime: 3e4,
|
|
34
37
|
retry: !1
|
|
35
|
-
},
|
|
38
|
+
}, l[9] = f, l[10] = p, l[11] = m, l[12] = h) : h = l[12], useQuery(h);
|
|
36
39
|
}
|
|
37
|
-
function useGitRemote(r) {
|
|
38
|
-
let
|
|
39
|
-
|
|
40
|
-
let
|
|
41
|
-
|
|
42
|
-
let
|
|
43
|
-
return
|
|
44
|
-
queryKey:
|
|
45
|
-
queryFn:
|
|
46
|
-
enabled:
|
|
40
|
+
function useGitRemote(r, i) {
|
|
41
|
+
let o = c(12), l = useLoopstackClient(), u;
|
|
42
|
+
o[0] !== l.envKey || o[1] !== i || o[2] !== r ? (u = [...queryKeys.gitRemote(l.envKey, r), i ?? ""], o[0] = l.envKey, o[1] = i, o[2] = r, o[3] = u) : u = o[3];
|
|
43
|
+
let d;
|
|
44
|
+
o[4] !== l.http || o[5] !== i || o[6] !== r ? (d = () => l.http.get(`${gitPath(r)}/remote`, i ? { slotId: i } : void 0), o[4] = l.http, o[5] = i, o[6] = r, o[7] = d) : d = o[7];
|
|
45
|
+
let f = !!r, p;
|
|
46
|
+
return o[8] !== u || o[9] !== d || o[10] !== f ? (p = {
|
|
47
|
+
queryKey: u,
|
|
48
|
+
queryFn: d,
|
|
49
|
+
enabled: f,
|
|
47
50
|
staleTime: 6e4,
|
|
48
51
|
retry: !1
|
|
49
|
-
},
|
|
52
|
+
}, o[8] = u, o[9] = d, o[10] = f, o[11] = p) : p = o[11], useQuery(p);
|
|
50
53
|
}
|
|
51
54
|
function useGitInvalidation(i) {
|
|
52
55
|
let a = c(5), s = useLoopstackClient(), l = useQueryClient(), u, d;
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "../../../components/ui/select.js";
|
|
2
|
+
import { useWorkbenchLayout } from "../providers/WorkbenchLayoutProvider.js";
|
|
3
|
+
import { c } from "react/compiler-runtime";
|
|
4
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
5
|
+
function EnvironmentSelector() {
|
|
6
|
+
let u = c(11), { environments: d, selectedSlotId: f, setSelectedSlotId: p } = useWorkbenchLayout(), m;
|
|
7
|
+
u[0] === d ? m = u[1] : (m = d ?? [], u[0] = d, u[1] = m);
|
|
8
|
+
let h = m;
|
|
9
|
+
if (h.length <= 1) return null;
|
|
10
|
+
let g;
|
|
11
|
+
u[2] === Symbol.for("react.memo_cache_sentinel") ? (g = /* @__PURE__ */ jsx(SelectTrigger, {
|
|
12
|
+
className: "h-7 text-xs",
|
|
13
|
+
children: /* @__PURE__ */ jsx(SelectValue, { placeholder: "Select environment" })
|
|
14
|
+
}), u[2] = g) : g = u[2];
|
|
15
|
+
let _;
|
|
16
|
+
u[3] === h ? _ = u[4] : (_ = h.map(_temp), u[3] = h, u[4] = _);
|
|
17
|
+
let v;
|
|
18
|
+
u[5] === _ ? v = u[6] : (v = /* @__PURE__ */ jsx(SelectContent, { children: _ }), u[5] = _, u[6] = v);
|
|
19
|
+
let y;
|
|
20
|
+
return u[7] !== f || u[8] !== p || u[9] !== v ? (y = /* @__PURE__ */ jsx("div", {
|
|
21
|
+
className: "border-b px-3 py-2",
|
|
22
|
+
children: /* @__PURE__ */ jsxs(Select, {
|
|
23
|
+
value: f,
|
|
24
|
+
onValueChange: p,
|
|
25
|
+
children: [g, v]
|
|
26
|
+
})
|
|
27
|
+
}), u[7] = f, u[8] = p, u[9] = v, u[10] = y) : y = u[10], y;
|
|
28
|
+
}
|
|
29
|
+
function _temp(e) {
|
|
30
|
+
return /* @__PURE__ */ jsx(SelectItem, {
|
|
31
|
+
value: e.slotId,
|
|
32
|
+
className: "text-xs",
|
|
33
|
+
children: /* @__PURE__ */ jsxs("span", {
|
|
34
|
+
className: "flex items-center gap-2",
|
|
35
|
+
children: [
|
|
36
|
+
/* @__PURE__ */ jsx("span", { className: `h-1.5 w-1.5 rounded-full ${e.status === "running" ? "bg-green-500" : "bg-muted-foreground/40"}` }),
|
|
37
|
+
e.envName || e.slotId,
|
|
38
|
+
e.status !== "running" && /* @__PURE__ */ jsx("span", {
|
|
39
|
+
className: "text-muted-foreground",
|
|
40
|
+
children: "(stopped)"
|
|
41
|
+
})
|
|
42
|
+
]
|
|
43
|
+
})
|
|
44
|
+
}, e.slotId);
|
|
45
|
+
}
|
|
46
|
+
export { EnvironmentSelector };
|
|
@@ -1,74 +1,83 @@
|
|
|
1
1
|
import { useWorkspaceEnvironments } from "../../../hooks/useEnvironments.js";
|
|
2
2
|
import { useOptionalStudioPreferences } from "../../../providers/StudioPreferencesProvider.js";
|
|
3
3
|
import { c } from "react/compiler-runtime";
|
|
4
|
-
import { createContext, useCallback, useContext, useMemo, useState } from "react";
|
|
4
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
5
5
|
import { jsx } from "react/jsx-runtime";
|
|
6
6
|
var WorkbenchLayoutContext = createContext(null);
|
|
7
|
-
function WorkbenchLayoutProvider(
|
|
8
|
-
let
|
|
9
|
-
|
|
10
|
-
let [
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
7
|
+
function WorkbenchLayoutProvider(u) {
|
|
8
|
+
let d = c(39), { children: f, workspaceId: p, workflow: m, getPreviewUrl: h, getEnvironmentPreviewUrl: g } = u, _ = useOptionalStudioPreferences(), { data: v } = useWorkspaceEnvironments(p), [y, b] = useState(null), x;
|
|
9
|
+
d[0] === Symbol.for("react.memo_cache_sentinel") ? (x = {}, d[0] = x) : x = d[0];
|
|
10
|
+
let [S, C] = useState(x), w = _ ? _.preferences.activePanel : y, T = _ ? _.preferences.panelSizes : S, [E, D] = useState(null), [O, k] = useState(""), A, j;
|
|
11
|
+
d[1] !== v || d[2] !== O ? (A = () => {
|
|
12
|
+
if (!v?.length) return;
|
|
13
|
+
let e = v.find((e) => e.slotId === O);
|
|
14
|
+
e?.status !== "running" && k((v.find(_temp) ?? e ?? v[0]).slotId);
|
|
15
|
+
}, j = [v, O], d[1] = v, d[2] = O, d[3] = A, d[4] = j) : (A = d[3], j = d[4]), useEffect(A, j);
|
|
16
|
+
let M;
|
|
17
|
+
d[5] === v ? M = d[6] : (M = v === void 0 || v.some(_temp2), d[5] = v, d[6] = M);
|
|
18
|
+
let N = M, P;
|
|
19
|
+
d[7] === Symbol.for("react.memo_cache_sentinel") ? (P = {
|
|
14
20
|
runs: "medium",
|
|
15
21
|
preview: "medium",
|
|
16
22
|
files: "medium",
|
|
17
23
|
environment: "small"
|
|
18
|
-
},
|
|
19
|
-
let
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
},
|
|
23
|
-
let P = N, F;
|
|
24
|
-
l[6] !== S || l[7] !== P ? (F = (e) => {
|
|
25
|
-
P(S === e ? null : e);
|
|
26
|
-
}, l[6] = S, l[7] = P, l[8] = F) : F = l[8];
|
|
27
|
-
let I = F, L;
|
|
28
|
-
l[9] === P ? L = l[10] : (L = () => {
|
|
29
|
-
P(null);
|
|
30
|
-
}, l[9] = P, l[10] = L);
|
|
24
|
+
}, d[7] = P) : P = d[7];
|
|
25
|
+
let F = P, I = w ? T[w] ?? F[w] ?? "small" : "small", L;
|
|
26
|
+
d[8] === _ ? L = d[9] : (L = (e) => {
|
|
27
|
+
_ ? _.setPreference("activePanel", e) : b(e);
|
|
28
|
+
}, d[8] = _, d[9] = L);
|
|
31
29
|
let R = L, z;
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
...C,
|
|
36
|
-
[S]: e
|
|
37
|
-
};
|
|
38
|
-
h ? h.setPreference("panelSizes", o) : x(o);
|
|
39
|
-
}, l[11] = S, l[12] = C, l[13] = h, l[14] = z) : z = l[14];
|
|
30
|
+
d[10] !== w || d[11] !== R ? (z = (e) => {
|
|
31
|
+
R(w === e ? null : e);
|
|
32
|
+
}, d[10] = w, d[11] = R, d[12] = z) : z = d[12];
|
|
40
33
|
let B = z, V;
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
},
|
|
34
|
+
d[13] === R ? V = d[14] : (V = () => {
|
|
35
|
+
R(null);
|
|
36
|
+
}, d[13] = R, d[14] = V);
|
|
44
37
|
let H = V, U;
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
panelSize: M,
|
|
54
|
-
togglePanel: I,
|
|
55
|
-
closePanel: R,
|
|
56
|
-
setPanelSize: B,
|
|
57
|
-
selectedSlotId: E,
|
|
58
|
-
setSelectedSlotId: D,
|
|
59
|
-
openPreviewWithEnvironment: H,
|
|
60
|
-
activeSectionId: w,
|
|
61
|
-
setActiveSectionId: T
|
|
62
|
-
}, l[17] = S, l[18] = w, l[19] = R, l[20] = g, l[21] = m, l[22] = p, l[23] = H, l[24] = M, l[25] = k, l[26] = E, l[27] = B, l[28] = I, l[29] = f, l[30] = d, l[31] = U) : U = l[31];
|
|
38
|
+
d[15] !== w || d[16] !== T || d[17] !== _ ? (U = (e) => {
|
|
39
|
+
if (!w) return;
|
|
40
|
+
let l = {
|
|
41
|
+
...T,
|
|
42
|
+
[w]: e
|
|
43
|
+
};
|
|
44
|
+
_ ? _.setPreference("panelSizes", l) : C(l);
|
|
45
|
+
}, d[15] = w, d[16] = T, d[17] = _, d[18] = U) : U = d[18];
|
|
63
46
|
let W = U, G;
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
47
|
+
d[19] === R ? G = d[20] : (G = (e) => {
|
|
48
|
+
k(e), R("preview");
|
|
49
|
+
}, d[19] = R, d[20] = G);
|
|
50
|
+
let K = G, q;
|
|
51
|
+
d[21] !== w || d[22] !== E || d[23] !== H || d[24] !== v || d[25] !== g || d[26] !== h || d[27] !== K || d[28] !== I || d[29] !== N || d[30] !== O || d[31] !== W || d[32] !== B || d[33] !== m || d[34] !== p ? (q = {
|
|
52
|
+
workspaceId: p,
|
|
53
|
+
workflow: m,
|
|
54
|
+
previewPanelEnabled: N,
|
|
55
|
+
getPreviewUrl: h,
|
|
56
|
+
getEnvironmentPreviewUrl: g,
|
|
57
|
+
environments: v,
|
|
58
|
+
activePanel: w,
|
|
59
|
+
panelSize: I,
|
|
60
|
+
togglePanel: B,
|
|
61
|
+
closePanel: H,
|
|
62
|
+
setPanelSize: W,
|
|
63
|
+
selectedSlotId: O,
|
|
64
|
+
setSelectedSlotId: k,
|
|
65
|
+
openPreviewWithEnvironment: K,
|
|
66
|
+
activeSectionId: E,
|
|
67
|
+
setActiveSectionId: D
|
|
68
|
+
}, d[21] = w, d[22] = E, d[23] = H, d[24] = v, d[25] = g, d[26] = h, d[27] = K, d[28] = I, d[29] = N, d[30] = O, d[31] = W, d[32] = B, d[33] = m, d[34] = p, d[35] = q) : q = d[35];
|
|
69
|
+
let J = q, Y;
|
|
70
|
+
return d[36] !== f || d[37] !== J ? (Y = /* @__PURE__ */ jsx(WorkbenchLayoutContext.Provider, {
|
|
71
|
+
value: J,
|
|
72
|
+
children: f
|
|
73
|
+
}), d[36] = f, d[37] = J, d[38] = Y) : Y = d[38], Y;
|
|
68
74
|
}
|
|
69
|
-
function
|
|
75
|
+
function _temp2(e) {
|
|
70
76
|
return !!e.connectionUrl && (!!e.workerId || e.local);
|
|
71
77
|
}
|
|
78
|
+
function _temp(e) {
|
|
79
|
+
return e.status === "running";
|
|
80
|
+
}
|
|
72
81
|
function useWorkbenchLayout() {
|
|
73
82
|
let e = useContext(WorkbenchLayoutContext);
|
|
74
83
|
if (!e) throw Error("useWorkbenchLayout must be used within a WorkbenchLayoutProvider");
|
|
@@ -31,9 +31,22 @@ const UITextBlockSchema = z.object({
|
|
|
31
31
|
UIServerToolUseBlockSchema,
|
|
32
32
|
UIServerToolResultBlockSchema,
|
|
33
33
|
UIToolResultBlockSchema
|
|
34
|
-
]),
|
|
34
|
+
]), UIUsageSchema = z.object({
|
|
35
|
+
inputTokens: z.number(),
|
|
36
|
+
outputTokens: z.number(),
|
|
37
|
+
cacheCreationInputTokens: z.number().optional(),
|
|
38
|
+
cacheReadInputTokens: z.number().optional(),
|
|
39
|
+
reasoningTokens: z.number().optional()
|
|
40
|
+
}), UIMessageMetaSchema = z.object({
|
|
41
|
+
model: z.string().optional(),
|
|
42
|
+
usage: UIUsageSchema.optional(),
|
|
43
|
+
costUsd: z.number().optional(),
|
|
44
|
+
numTurns: z.number().optional(),
|
|
45
|
+
durationMs: z.number().optional()
|
|
46
|
+
}), UIMessageSchema = z.object({
|
|
35
47
|
role: z.enum(["user", "assistant"]),
|
|
36
48
|
text: z.string().optional(),
|
|
37
|
-
blocks: z.array(UIContentBlockSchema).optional()
|
|
49
|
+
blocks: z.array(UIContentBlockSchema).optional(),
|
|
50
|
+
meta: UIMessageMetaSchema.optional()
|
|
38
51
|
});
|
|
39
52
|
export { UIMessageSchema };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@loopstack/loopstack-studio",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.0",
|
|
4
4
|
"repository": "loopstack-ai/loopstack-studio",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -26,9 +26,9 @@
|
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@fontsource/roboto": "^5.2.10",
|
|
28
28
|
"@hookform/resolvers": "^5.2.2",
|
|
29
|
-
"@loopstack/client": "^0.
|
|
30
|
-
"@loopstack/contracts": "^0.
|
|
31
|
-
"@loopstack/react": "^
|
|
29
|
+
"@loopstack/client": "^0.39.0",
|
|
30
|
+
"@loopstack/contracts": "^0.39.0",
|
|
31
|
+
"@loopstack/react": "^3.0.0",
|
|
32
32
|
"@radix-ui/react-accordion": "^1.2.12",
|
|
33
33
|
"@radix-ui/react-alert-dialog": "^1.1.15",
|
|
34
34
|
"@radix-ui/react-avatar": "^1.1.11",
|