@tangle-network/sandbox-ui 0.3.7 → 0.3.10
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/active-sessions-store-CeOmXgv5.d.ts +85 -0
- package/dist/artifact-pane-Bh45Ssco.d.ts +24 -0
- package/dist/{chat-container-B34uj-J1.d.ts → chat-container-Dn1jWtWo.d.ts} +15 -3
- package/dist/chat.d.ts +16 -4
- package/dist/chat.js +2 -2
- package/dist/{chunk-PXRPYAMM.js → chunk-6H3EFUUC.js} +96 -74
- package/dist/{chunk-WUR652Y3.js → chunk-72UEKFZ2.js} +113 -89
- package/dist/{chunk-5LV6DZZF.js → chunk-FOQTE67I.js} +278 -21
- package/dist/chunk-MGCVTFKB.js +10910 -0
- package/dist/chunk-OEX7NZE3.js +321 -0
- package/dist/chunk-Q56BYXQF.js +61 -0
- package/dist/{chunk-ZSNOGOUX.js → chunk-RQOX5JRR.js} +541 -76
- package/dist/{chunk-PDV7W4NY.js → chunk-SULQQJPB.js} +1 -56
- package/dist/chunk-W4LM3QYZ.js +54 -0
- package/dist/{chunk-JF6E2DS5.js → chunk-ZYGWTIWO.js} +171 -155
- package/dist/document-editor-pane-Bk-9MQmw.d.ts +116 -0
- package/dist/document-editor-pane-GRIQOJHB.js +11 -0
- package/dist/editor.d.ts +7 -84
- package/dist/editor.js +18 -699
- package/dist/{expanded-tool-detail-BDi_h_dZ.d.ts → expanded-tool-detail-DM5M_T9h.d.ts} +10 -2
- package/dist/{file-tabs-CmaoDVBI.d.ts → file-tabs-BLfxfmAH.d.ts} +1 -22
- package/dist/files.d.ts +25 -3
- package/dist/files.js +2 -1
- package/dist/hooks.d.ts +3 -1
- package/dist/hooks.js +6 -1
- package/dist/index.d.ts +12 -6
- package/dist/index.js +21 -8
- package/dist/pages.js +4 -2
- package/dist/primitives.js +4 -2
- package/dist/run.d.ts +1 -1
- package/dist/run.js +1 -1
- package/dist/sdk-hooks.d.ts +32 -1
- package/dist/sdk-hooks.js +6 -1
- package/dist/stores.d.ts +1 -0
- package/dist/stores.js +60 -1
- package/dist/types.d.ts +2 -0
- package/dist/workspace.d.ts +84 -6
- package/dist/workspace.js +10 -4
- package/package.json +17 -6
|
@@ -1,25 +1,36 @@
|
|
|
1
|
+
import {
|
|
2
|
+
useActiveSessions,
|
|
3
|
+
useNavbarSessions,
|
|
4
|
+
useProjectActivity,
|
|
5
|
+
useTotalRunningSessions
|
|
6
|
+
} from "./chunk-OEX7NZE3.js";
|
|
1
7
|
import {
|
|
2
8
|
EmptyState,
|
|
3
9
|
Input
|
|
4
10
|
} from "./chunk-MUOL44AE.js";
|
|
5
11
|
import {
|
|
6
12
|
ChatContainer
|
|
7
|
-
} from "./chunk-
|
|
13
|
+
} from "./chunk-6H3EFUUC.js";
|
|
8
14
|
import {
|
|
9
15
|
OpenUIArtifactRenderer
|
|
10
16
|
} from "./chunk-YDBXQQLC.js";
|
|
11
17
|
import {
|
|
12
|
-
ArtifactPane,
|
|
13
18
|
FileArtifactPane,
|
|
14
19
|
FileTree,
|
|
15
20
|
filterFileTree
|
|
16
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ZYGWTIWO.js";
|
|
22
|
+
import {
|
|
23
|
+
ArtifactPane
|
|
24
|
+
} from "./chunk-W4LM3QYZ.js";
|
|
17
25
|
import {
|
|
18
26
|
Markdown
|
|
19
27
|
} from "./chunk-LTFK464G.js";
|
|
20
28
|
import {
|
|
21
29
|
Badge
|
|
22
30
|
} from "./chunk-MXCSSOGH.js";
|
|
31
|
+
import {
|
|
32
|
+
Button
|
|
33
|
+
} from "./chunk-HWLX5NME.js";
|
|
23
34
|
import {
|
|
24
35
|
cn
|
|
25
36
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -157,6 +168,7 @@ function WorkspaceLayout({
|
|
|
157
168
|
right,
|
|
158
169
|
rightHeader,
|
|
159
170
|
bottom,
|
|
171
|
+
bottomHeader,
|
|
160
172
|
defaultLeftOpen = true,
|
|
161
173
|
defaultRightOpen = false,
|
|
162
174
|
defaultBottomOpen = false,
|
|
@@ -329,7 +341,7 @@ function WorkspaceLayout({
|
|
|
329
341
|
className: "border-t border-[var(--border-subtle)] bg-[var(--bg-card)]",
|
|
330
342
|
children: [
|
|
331
343
|
/* @__PURE__ */ jsxs("div", { className: "flex items-center justify-between gap-2 border-b border-[var(--border-subtle)] px-3 py-2", children: [
|
|
332
|
-
/* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-[0.12em] text-[var(--text-muted)]", children: "Runtime" }),
|
|
344
|
+
/* @__PURE__ */ jsx("div", { className: "min-w-0 flex-1", children: bottomHeader ?? /* @__PURE__ */ jsx("span", { className: "text-xs font-semibold uppercase tracking-[0.12em] text-[var(--text-muted)]", children: "Runtime" }) }),
|
|
333
345
|
/* @__PURE__ */ jsx(
|
|
334
346
|
"button",
|
|
335
347
|
{
|
|
@@ -749,18 +761,406 @@ function RuntimePane({
|
|
|
749
761
|
);
|
|
750
762
|
}
|
|
751
763
|
|
|
764
|
+
// src/workspace/session-sidebar.tsx
|
|
765
|
+
import { useMemo as useMemo3, useState as useState4 } from "react";
|
|
766
|
+
import { ArrowLeft, FolderTree, MessageSquareText, Plus, Search as Search2, Settings, Sparkles } from "lucide-react";
|
|
767
|
+
import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
|
|
768
|
+
function statusClasses(status) {
|
|
769
|
+
switch (status) {
|
|
770
|
+
case "running":
|
|
771
|
+
return "bg-[var(--brand-cool)] shadow-[0_0_0_4px_color-mix(in_srgb,var(--brand-cool)_18%,transparent)]";
|
|
772
|
+
case "error":
|
|
773
|
+
return "bg-[var(--status-danger)]";
|
|
774
|
+
case "attention-needed":
|
|
775
|
+
return "bg-[var(--status-warning)]";
|
|
776
|
+
default:
|
|
777
|
+
return "bg-[var(--text-dim)]";
|
|
778
|
+
}
|
|
779
|
+
}
|
|
780
|
+
function iconForLink(icon) {
|
|
781
|
+
switch (icon) {
|
|
782
|
+
case "vault":
|
|
783
|
+
return FolderTree;
|
|
784
|
+
case "settings":
|
|
785
|
+
return Settings;
|
|
786
|
+
case "back":
|
|
787
|
+
return ArrowLeft;
|
|
788
|
+
default:
|
|
789
|
+
return Sparkles;
|
|
790
|
+
}
|
|
791
|
+
}
|
|
792
|
+
function sortItems(items, sessionStatusById) {
|
|
793
|
+
return [...items].sort((left, right) => {
|
|
794
|
+
if (Boolean(left.isPinned) !== Boolean(right.isPinned)) {
|
|
795
|
+
return left.isPinned ? -1 : 1;
|
|
796
|
+
}
|
|
797
|
+
const leftSession = sessionStatusById.get(left.id);
|
|
798
|
+
const rightSession = sessionStatusById.get(right.id);
|
|
799
|
+
if (Boolean(leftSession) !== Boolean(rightSession)) {
|
|
800
|
+
return leftSession ? -1 : 1;
|
|
801
|
+
}
|
|
802
|
+
if (leftSession && rightSession) {
|
|
803
|
+
if (leftSession.isForeground !== rightSession.isForeground) {
|
|
804
|
+
return Number(rightSession.isForeground) - Number(leftSession.isForeground);
|
|
805
|
+
}
|
|
806
|
+
const leftRunning = Number(leftSession.status === "running");
|
|
807
|
+
const rightRunning = Number(rightSession.status === "running");
|
|
808
|
+
if (leftRunning !== rightRunning) {
|
|
809
|
+
return rightRunning - leftRunning;
|
|
810
|
+
}
|
|
811
|
+
if (leftSession.lastActivityAt !== rightSession.lastActivityAt) {
|
|
812
|
+
return rightSession.lastActivityAt - leftSession.lastActivityAt;
|
|
813
|
+
}
|
|
814
|
+
}
|
|
815
|
+
const leftUpdated = left.updatedAt ? new Date(left.updatedAt).getTime() : 0;
|
|
816
|
+
const rightUpdated = right.updatedAt ? new Date(right.updatedAt).getTime() : 0;
|
|
817
|
+
return rightUpdated - leftUpdated;
|
|
818
|
+
});
|
|
819
|
+
}
|
|
820
|
+
function badgeClasses(tone = "neutral") {
|
|
821
|
+
switch (tone) {
|
|
822
|
+
case "accent":
|
|
823
|
+
return "border-[var(--border-accent)] bg-[var(--accent-surface-soft)] text-[var(--accent-text)]";
|
|
824
|
+
case "success":
|
|
825
|
+
return "border-emerald-500/30 bg-emerald-500/10 text-emerald-200";
|
|
826
|
+
case "warning":
|
|
827
|
+
return "border-amber-500/30 bg-amber-500/10 text-amber-100";
|
|
828
|
+
case "danger":
|
|
829
|
+
return "border-red-500/30 bg-red-500/10 text-red-200";
|
|
830
|
+
default:
|
|
831
|
+
return "border-[var(--border-subtle)] bg-[var(--bg-section)] text-[var(--text-secondary)]";
|
|
832
|
+
}
|
|
833
|
+
}
|
|
834
|
+
function navigateToHref(href) {
|
|
835
|
+
if (!href || typeof window === "undefined") return;
|
|
836
|
+
window.location.assign(href);
|
|
837
|
+
}
|
|
838
|
+
function SessionSidebar({
|
|
839
|
+
title,
|
|
840
|
+
subtitle,
|
|
841
|
+
projectId = null,
|
|
842
|
+
items,
|
|
843
|
+
currentItemId,
|
|
844
|
+
createLabel = "New Session",
|
|
845
|
+
onCreate,
|
|
846
|
+
onSelectItem,
|
|
847
|
+
onSelectLink,
|
|
848
|
+
links = [],
|
|
849
|
+
className,
|
|
850
|
+
emptyMessage = "No sessions yet. Start a conversation.",
|
|
851
|
+
searchPlaceholder = "Search sessions",
|
|
852
|
+
enableSearch = true,
|
|
853
|
+
activityMonitor,
|
|
854
|
+
filters = [],
|
|
855
|
+
defaultFilterId,
|
|
856
|
+
renderItemActions
|
|
857
|
+
}) {
|
|
858
|
+
const [query, setQuery] = useState4("");
|
|
859
|
+
const [activeFilterId, setActiveFilterId] = useState4(defaultFilterId ?? filters[0]?.id ?? "all");
|
|
860
|
+
const activeSessions = useNavbarSessions(projectId);
|
|
861
|
+
const sessionsById = useMemo3(
|
|
862
|
+
() => new Map(activeSessions.map((session) => [session.sessionId, session])),
|
|
863
|
+
[activeSessions]
|
|
864
|
+
);
|
|
865
|
+
const orderedItems = useMemo3(
|
|
866
|
+
() => sortItems(items, sessionsById),
|
|
867
|
+
[items, sessionsById]
|
|
868
|
+
);
|
|
869
|
+
const visibleItems = useMemo3(() => {
|
|
870
|
+
const normalizedQuery = query.trim().toLowerCase();
|
|
871
|
+
const selectedFilter = filters.find((filter) => filter.id === activeFilterId) ?? null;
|
|
872
|
+
return orderedItems.filter((item) => {
|
|
873
|
+
const session = sessionsById.get(item.id) ?? null;
|
|
874
|
+
const isActive = currentItemId === item.id;
|
|
875
|
+
if (selectedFilter && !selectedFilter.matches(item, { session, isActive })) {
|
|
876
|
+
return false;
|
|
877
|
+
}
|
|
878
|
+
if (!normalizedQuery) return true;
|
|
879
|
+
const haystack = `${item.title} ${item.subtitle ?? ""} ${item.category ?? ""} ${(item.badges ?? []).map((badge) => badge.label).join(" ")}`.toLowerCase();
|
|
880
|
+
return haystack.includes(normalizedQuery);
|
|
881
|
+
});
|
|
882
|
+
}, [activeFilterId, currentItemId, filters, orderedItems, query, sessionsById]);
|
|
883
|
+
const runningCount = activeSessions.filter((session) => session.status === "running").length;
|
|
884
|
+
const filterCounts = useMemo3(() => Object.fromEntries(filters.map((filter) => [
|
|
885
|
+
filter.id,
|
|
886
|
+
orderedItems.filter((item) => filter.matches(item, {
|
|
887
|
+
session: sessionsById.get(item.id) ?? null,
|
|
888
|
+
isActive: currentItemId === item.id
|
|
889
|
+
})).length
|
|
890
|
+
])), [currentItemId, filters, orderedItems, sessionsById]);
|
|
891
|
+
return /* @__PURE__ */ jsxs7("aside", { className: cn("flex w-72 shrink-0 flex-col border-r border-[var(--border-subtle)] bg-[radial-gradient(circle_at_top,rgba(96,165,250,0.12),transparent_26%),var(--bg-card)]/94 backdrop-blur-xl", className), children: [
|
|
892
|
+
/* @__PURE__ */ jsxs7("div", { className: "border-b border-[var(--border-subtle)] px-4 py-4", children: [
|
|
893
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
|
|
894
|
+
/* @__PURE__ */ jsx7("div", { className: "flex h-11 w-11 items-center justify-center rounded-2xl border border-[var(--border-subtle)] bg-[linear-gradient(135deg,rgba(82,164,255,0.22),rgba(82,164,255,0.08))] text-[var(--accent-text)] shadow-[var(--shadow-accent)]", children: /* @__PURE__ */ jsx7(MessageSquareText, { className: "h-4 w-4" }) }),
|
|
895
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0", children: [
|
|
896
|
+
/* @__PURE__ */ jsx7("div", { className: "truncate text-sm font-semibold tracking-[0.01em] text-[var(--text-primary)]", children: title }),
|
|
897
|
+
subtitle && /* @__PURE__ */ jsx7("div", { className: "truncate text-xs text-[var(--text-muted)]", children: subtitle })
|
|
898
|
+
] })
|
|
899
|
+
] }),
|
|
900
|
+
/* @__PURE__ */ jsxs7("div", { className: "mt-4 grid grid-cols-2 gap-2", children: [
|
|
901
|
+
/* @__PURE__ */ jsxs7("div", { className: "rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[linear-gradient(180deg,rgba(255,255,255,0.04),transparent)] px-3 py-2", children: [
|
|
902
|
+
/* @__PURE__ */ jsx7("div", { className: "text-[10px] font-semibold uppercase tracking-[0.16em] text-[var(--text-muted)]", children: "Tracked" }),
|
|
903
|
+
/* @__PURE__ */ jsx7("div", { className: "mt-1 text-sm font-semibold text-[var(--text-primary)]", children: items.length })
|
|
904
|
+
] }),
|
|
905
|
+
/* @__PURE__ */ jsxs7("div", { className: "rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[linear-gradient(180deg,rgba(255,255,255,0.04),transparent)] px-3 py-2", children: [
|
|
906
|
+
/* @__PURE__ */ jsx7("div", { className: "text-[10px] font-semibold uppercase tracking-[0.16em] text-[var(--text-muted)]", children: "Running" }),
|
|
907
|
+
/* @__PURE__ */ jsx7("div", { className: "mt-1 text-sm font-semibold text-[var(--text-primary)]", children: runningCount })
|
|
908
|
+
] })
|
|
909
|
+
] }),
|
|
910
|
+
/* @__PURE__ */ jsxs7(
|
|
911
|
+
Button,
|
|
912
|
+
{
|
|
913
|
+
type: "button",
|
|
914
|
+
onClick: onCreate,
|
|
915
|
+
className: "mt-4 w-full justify-center gap-2 rounded-xl bg-[linear-gradient(135deg,var(--brand-cool),var(--brand-glow))] text-white shadow-[var(--shadow-accent)] hover:translate-y-[-1px] hover:brightness-105",
|
|
916
|
+
children: [
|
|
917
|
+
/* @__PURE__ */ jsx7(Plus, { className: "h-4 w-4" }),
|
|
918
|
+
createLabel
|
|
919
|
+
]
|
|
920
|
+
}
|
|
921
|
+
),
|
|
922
|
+
enableSearch && items.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "relative mt-3", children: [
|
|
923
|
+
/* @__PURE__ */ jsx7(Search2, { className: "pointer-events-none absolute left-3 top-1/2 h-4 w-4 -translate-y-1/2 text-[var(--text-dim)]" }),
|
|
924
|
+
/* @__PURE__ */ jsx7(
|
|
925
|
+
"input",
|
|
926
|
+
{
|
|
927
|
+
value: query,
|
|
928
|
+
onChange: (event) => setQuery(event.target.value),
|
|
929
|
+
placeholder: searchPlaceholder,
|
|
930
|
+
"aria-label": searchPlaceholder,
|
|
931
|
+
className: "h-10 w-full rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[linear-gradient(180deg,rgba(255,255,255,0.04),transparent)] pl-9 pr-3 text-sm text-[var(--text-primary)] placeholder:text-[var(--text-dim)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--brand-cool)]/45"
|
|
932
|
+
}
|
|
933
|
+
)
|
|
934
|
+
] }),
|
|
935
|
+
filters.length > 0 && /* @__PURE__ */ jsx7("div", { className: "mt-3 flex flex-wrap gap-2", children: filters.map((filter) => {
|
|
936
|
+
const isSelected = activeFilterId === filter.id;
|
|
937
|
+
return /* @__PURE__ */ jsxs7(
|
|
938
|
+
"button",
|
|
939
|
+
{
|
|
940
|
+
type: "button",
|
|
941
|
+
onClick: () => setActiveFilterId(filter.id),
|
|
942
|
+
className: cn(
|
|
943
|
+
"inline-flex items-center gap-1.5 rounded-full border px-2.5 py-1 text-[11px] font-medium transition-colors",
|
|
944
|
+
isSelected ? "border-[var(--border-accent)] bg-[var(--accent-surface-soft)] text-[var(--accent-text)]" : "border-[var(--border-subtle)] bg-[var(--bg-section)] text-[var(--text-muted)] hover:text-[var(--text-primary)]"
|
|
945
|
+
),
|
|
946
|
+
children: [
|
|
947
|
+
/* @__PURE__ */ jsx7("span", { children: filter.label }),
|
|
948
|
+
/* @__PURE__ */ jsx7("span", { className: "rounded-full bg-[var(--bg-card)] px-1.5 py-0.5 text-[10px] text-[var(--text-secondary)]", children: filterCounts[filter.id] ?? 0 })
|
|
949
|
+
]
|
|
950
|
+
},
|
|
951
|
+
filter.id
|
|
952
|
+
);
|
|
953
|
+
}) })
|
|
954
|
+
] }),
|
|
955
|
+
/* @__PURE__ */ jsx7("nav", { "aria-label": "Sessions", className: "flex-1 overflow-y-auto px-3 py-3", children: visibleItems.length === 0 ? /* @__PURE__ */ jsx7("div", { className: "rounded-[var(--radius-lg)] border border-dashed border-[var(--border-subtle)] bg-[var(--bg-section)] px-4 py-5 text-sm text-[var(--text-muted)]", children: query.trim() ? `No sessions match "${query.trim()}".` : emptyMessage }) : /* @__PURE__ */ jsx7("ul", { className: "space-y-1.5", children: visibleItems.map((item) => {
|
|
956
|
+
const session = sessionsById.get(item.id) ?? null;
|
|
957
|
+
const isActive = currentItemId === item.id;
|
|
958
|
+
const status = session?.status ?? item.status;
|
|
959
|
+
const visibleBadges = [
|
|
960
|
+
...item.isPinned ? [{ id: `${item.id}-pinned`, label: "Pinned", tone: "accent" }] : [],
|
|
961
|
+
...item.badges ?? []
|
|
962
|
+
];
|
|
963
|
+
return /* @__PURE__ */ jsx7("li", { children: /* @__PURE__ */ jsxs7(
|
|
964
|
+
"div",
|
|
965
|
+
{
|
|
966
|
+
className: cn(
|
|
967
|
+
"group flex items-start gap-2 rounded-[calc(var(--radius-lg)+2px)] border px-2 py-2 transition-colors backdrop-blur-sm",
|
|
968
|
+
isActive ? "border-[var(--border-accent)] bg-[radial-gradient(circle_at_top_left,rgba(96,165,250,0.16),transparent_40%),var(--accent-surface-soft)] shadow-[var(--shadow-card)]" : "border-transparent bg-transparent hover:border-[var(--border-subtle)] hover:bg-[linear-gradient(180deg,rgba(255,255,255,0.03),transparent)]"
|
|
969
|
+
),
|
|
970
|
+
children: [
|
|
971
|
+
/* @__PURE__ */ jsxs7(
|
|
972
|
+
"button",
|
|
973
|
+
{
|
|
974
|
+
type: "button",
|
|
975
|
+
onClick: () => {
|
|
976
|
+
if (onSelectItem) {
|
|
977
|
+
onSelectItem(item);
|
|
978
|
+
return;
|
|
979
|
+
}
|
|
980
|
+
navigateToHref(item.href);
|
|
981
|
+
},
|
|
982
|
+
"aria-current": isActive ? "page" : void 0,
|
|
983
|
+
className: "min-w-0 flex flex-1 items-start gap-3 rounded-[var(--radius-lg)] px-1 py-1 text-left",
|
|
984
|
+
children: [
|
|
985
|
+
/* @__PURE__ */ jsx7("span", { className: cn("mt-1 h-2.5 w-2.5 shrink-0 rounded-full", statusClasses(status)) }),
|
|
986
|
+
/* @__PURE__ */ jsxs7("div", { className: "min-w-0 flex-1", children: [
|
|
987
|
+
/* @__PURE__ */ jsx7("div", { className: "truncate text-sm font-medium text-[var(--text-primary)]", children: item.title }),
|
|
988
|
+
item.subtitle && /* @__PURE__ */ jsx7("div", { className: "mt-0.5 truncate text-xs text-[var(--text-muted)]", children: item.subtitle }),
|
|
989
|
+
visibleBadges.length > 0 && /* @__PURE__ */ jsx7("div", { className: "mt-2 flex flex-wrap items-center gap-1.5", children: visibleBadges.map((badge) => /* @__PURE__ */ jsx7(
|
|
990
|
+
"span",
|
|
991
|
+
{
|
|
992
|
+
className: cn(
|
|
993
|
+
"inline-flex items-center rounded-full border px-2 py-0.5 text-[10px] font-medium uppercase tracking-[0.08em]",
|
|
994
|
+
badgeClasses(badge.tone)
|
|
995
|
+
),
|
|
996
|
+
children: badge.label
|
|
997
|
+
},
|
|
998
|
+
badge.id
|
|
999
|
+
)) })
|
|
1000
|
+
] })
|
|
1001
|
+
]
|
|
1002
|
+
}
|
|
1003
|
+
),
|
|
1004
|
+
/* @__PURE__ */ jsxs7("div", { className: "flex shrink-0 items-center gap-2", children: [
|
|
1005
|
+
session?.isForeground && /* @__PURE__ */ jsx7(Badge, { className: "rounded-full border-[var(--border-subtle)] bg-[var(--bg-section)] text-[10px] uppercase tracking-[0.14em] text-[var(--text-secondary)]", children: "Live" }),
|
|
1006
|
+
renderItemActions ? /* @__PURE__ */ jsx7(
|
|
1007
|
+
"div",
|
|
1008
|
+
{
|
|
1009
|
+
className: "opacity-70 transition-opacity hover:opacity-100 group-hover:opacity-100",
|
|
1010
|
+
onClick: (event) => event.stopPropagation(),
|
|
1011
|
+
children: renderItemActions(item, {
|
|
1012
|
+
session,
|
|
1013
|
+
isActive
|
|
1014
|
+
})
|
|
1015
|
+
}
|
|
1016
|
+
) : null
|
|
1017
|
+
] })
|
|
1018
|
+
]
|
|
1019
|
+
}
|
|
1020
|
+
) }, item.id);
|
|
1021
|
+
}) }) }),
|
|
1022
|
+
activityMonitor && /* @__PURE__ */ jsx7("div", { className: "border-t border-[var(--border-subtle)] px-3 py-3", children: activityMonitor }),
|
|
1023
|
+
links.length > 0 && /* @__PURE__ */ jsx7("nav", { "aria-label": "Workspace sections", className: "border-t border-[var(--border-subtle)] px-3 py-3", children: /* @__PURE__ */ jsx7("div", { className: "space-y-1", children: links.map((link) => {
|
|
1024
|
+
const Icon = iconForLink(link.icon);
|
|
1025
|
+
return /* @__PURE__ */ jsxs7(
|
|
1026
|
+
"button",
|
|
1027
|
+
{
|
|
1028
|
+
type: "button",
|
|
1029
|
+
onClick: () => {
|
|
1030
|
+
if (onSelectLink) {
|
|
1031
|
+
onSelectLink(link);
|
|
1032
|
+
return;
|
|
1033
|
+
}
|
|
1034
|
+
navigateToHref(link.href);
|
|
1035
|
+
},
|
|
1036
|
+
className: "flex w-full items-center gap-2 rounded-[var(--radius-md)] px-3 py-2 text-left text-sm text-[var(--text-secondary)] transition-colors hover:bg-[var(--bg-section)] hover:text-[var(--text-primary)]",
|
|
1037
|
+
children: [
|
|
1038
|
+
/* @__PURE__ */ jsx7(Icon, { className: "h-4 w-4 shrink-0" }),
|
|
1039
|
+
/* @__PURE__ */ jsx7("span", { className: "truncate", children: link.label })
|
|
1040
|
+
]
|
|
1041
|
+
},
|
|
1042
|
+
link.id
|
|
1043
|
+
);
|
|
1044
|
+
}) }) })
|
|
1045
|
+
] });
|
|
1046
|
+
}
|
|
1047
|
+
|
|
1048
|
+
// src/workspace/session-activity-monitor.tsx
|
|
1049
|
+
import { Activity, AlertCircle as AlertCircle2, LoaderCircle, MessageSquareText as MessageSquareText2 } from "lucide-react";
|
|
1050
|
+
import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
|
|
1051
|
+
function SessionStatusDot({ session }) {
|
|
1052
|
+
if (session.status === "error") {
|
|
1053
|
+
return /* @__PURE__ */ jsx8(AlertCircle2, { className: "h-3.5 w-3.5 text-[var(--status-danger)]" });
|
|
1054
|
+
}
|
|
1055
|
+
if (session.status === "running") {
|
|
1056
|
+
return /* @__PURE__ */ jsx8(LoaderCircle, { className: "h-3.5 w-3.5 animate-spin text-[var(--brand-cool)]" });
|
|
1057
|
+
}
|
|
1058
|
+
if (session.status === "attention-needed") {
|
|
1059
|
+
return /* @__PURE__ */ jsx8(Activity, { className: "h-3.5 w-3.5 text-[var(--status-warning)]" });
|
|
1060
|
+
}
|
|
1061
|
+
return /* @__PURE__ */ jsx8("span", { className: "h-2 w-2 rounded-full bg-[var(--text-dim)]" });
|
|
1062
|
+
}
|
|
1063
|
+
function navigateToSession(session) {
|
|
1064
|
+
if (!session.href || typeof window === "undefined") return;
|
|
1065
|
+
window.location.assign(session.href);
|
|
1066
|
+
}
|
|
1067
|
+
function SessionActivityMonitor({
|
|
1068
|
+
className,
|
|
1069
|
+
compact = false,
|
|
1070
|
+
sessionsById = {},
|
|
1071
|
+
emptyMessage = "No active sessions",
|
|
1072
|
+
resolveProjectLabel,
|
|
1073
|
+
onSelectSession
|
|
1074
|
+
}) {
|
|
1075
|
+
const trackedSessions = useActiveSessions();
|
|
1076
|
+
const projectActivity = useProjectActivity();
|
|
1077
|
+
const totalRunning = useTotalRunningSessions();
|
|
1078
|
+
const sessionLookup = Object.keys(sessionsById).length > 0 ? sessionsById : Object.fromEntries(trackedSessions.map((session) => [session.sessionId, session]));
|
|
1079
|
+
if (projectActivity.length === 0) {
|
|
1080
|
+
if (compact) return null;
|
|
1081
|
+
return /* @__PURE__ */ jsx8("div", { className: cn("rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[linear-gradient(180deg,rgba(255,255,255,0.04),transparent)] p-3 text-sm text-[var(--text-muted)]", className), children: emptyMessage });
|
|
1082
|
+
}
|
|
1083
|
+
return /* @__PURE__ */ jsxs8("div", { className: cn("space-y-3", className), children: [
|
|
1084
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between px-1", children: [
|
|
1085
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 text-[11px] font-semibold uppercase tracking-[0.16em] text-[var(--text-muted)]", children: [
|
|
1086
|
+
/* @__PURE__ */ jsx8(Activity, { className: "h-3.5 w-3.5" }),
|
|
1087
|
+
"Active Sessions"
|
|
1088
|
+
] }),
|
|
1089
|
+
totalRunning > 0 && /* @__PURE__ */ jsxs8("span", { className: "rounded-full border border-[var(--border-accent)] bg-[var(--accent-surface-soft)] px-2 py-0.5 text-[11px] font-medium text-[var(--accent-text)]", children: [
|
|
1090
|
+
totalRunning,
|
|
1091
|
+
" running"
|
|
1092
|
+
] })
|
|
1093
|
+
] }),
|
|
1094
|
+
/* @__PURE__ */ jsx8("div", { className: "space-y-2", children: projectActivity.map((project) => {
|
|
1095
|
+
const label = resolveProjectLabel?.(project.projectId, project.projectLabel) ?? project.projectLabel ?? String(project.projectId);
|
|
1096
|
+
return /* @__PURE__ */ jsxs8(
|
|
1097
|
+
"div",
|
|
1098
|
+
{
|
|
1099
|
+
className: "rounded-[calc(var(--radius-lg)+2px)] border border-[var(--border-subtle)] bg-[radial-gradient(circle_at_top_left,rgba(96,165,250,0.12),transparent_34%),linear-gradient(180deg,rgba(255,255,255,0.04),transparent),var(--bg-card)]/96 p-3 shadow-[var(--shadow-card)]",
|
|
1100
|
+
children: [
|
|
1101
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between gap-3", children: [
|
|
1102
|
+
/* @__PURE__ */ jsxs8("div", { children: [
|
|
1103
|
+
/* @__PURE__ */ jsx8("div", { className: "text-sm font-semibold text-[var(--text-primary)]", children: label }),
|
|
1104
|
+
/* @__PURE__ */ jsxs8("div", { className: "text-xs text-[var(--text-muted)]", children: [
|
|
1105
|
+
project.activeSessionCount,
|
|
1106
|
+
" tracked session",
|
|
1107
|
+
project.activeSessionCount === 1 ? "" : "s"
|
|
1108
|
+
] })
|
|
1109
|
+
] }),
|
|
1110
|
+
project.runningSessionIds.length > 0 && /* @__PURE__ */ jsxs8("span", { className: "rounded-full border border-[var(--border-subtle)] bg-[var(--bg-section)] px-2 py-0.5 text-[11px] text-[var(--text-secondary)]", children: [
|
|
1111
|
+
project.runningSessionIds.length,
|
|
1112
|
+
" live"
|
|
1113
|
+
] })
|
|
1114
|
+
] }),
|
|
1115
|
+
!compact && project.runningSessionIds.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-3 space-y-2", children: project.runningSessionIds.map((sessionId) => {
|
|
1116
|
+
const session = sessionLookup[sessionId];
|
|
1117
|
+
if (!session) return null;
|
|
1118
|
+
return /* @__PURE__ */ jsxs8(
|
|
1119
|
+
"button",
|
|
1120
|
+
{
|
|
1121
|
+
type: "button",
|
|
1122
|
+
onClick: () => {
|
|
1123
|
+
if (onSelectSession) {
|
|
1124
|
+
onSelectSession(session);
|
|
1125
|
+
return;
|
|
1126
|
+
}
|
|
1127
|
+
navigateToSession(session);
|
|
1128
|
+
},
|
|
1129
|
+
className: "flex w-full items-center justify-between rounded-[var(--radius-md)] border border-[var(--border-subtle)] bg-[var(--bg-section)] px-3 py-2 text-left transition-colors hover:border-[var(--border-accent)] hover:bg-[var(--bg-elevated)]",
|
|
1130
|
+
children: [
|
|
1131
|
+
/* @__PURE__ */ jsxs8("div", { className: "flex min-w-0 items-center gap-2", children: [
|
|
1132
|
+
/* @__PURE__ */ jsx8(SessionStatusDot, { session }),
|
|
1133
|
+
/* @__PURE__ */ jsxs8("div", { className: "min-w-0", children: [
|
|
1134
|
+
/* @__PURE__ */ jsx8("div", { className: "truncate text-sm font-medium text-[var(--text-primary)]", children: session.title ?? "Untitled Session" }),
|
|
1135
|
+
/* @__PURE__ */ jsx8("div", { className: "truncate text-xs text-[var(--text-muted)]", children: session.href ?? session.sessionId })
|
|
1136
|
+
] })
|
|
1137
|
+
] }),
|
|
1138
|
+
/* @__PURE__ */ jsx8(MessageSquareText2, { className: "h-4 w-4 shrink-0 text-[var(--text-dim)]" })
|
|
1139
|
+
]
|
|
1140
|
+
},
|
|
1141
|
+
sessionId
|
|
1142
|
+
);
|
|
1143
|
+
}) })
|
|
1144
|
+
]
|
|
1145
|
+
},
|
|
1146
|
+
String(project.projectId)
|
|
1147
|
+
);
|
|
1148
|
+
}) })
|
|
1149
|
+
] });
|
|
1150
|
+
}
|
|
1151
|
+
|
|
752
1152
|
// src/workspace/sandbox-workbench.tsx
|
|
753
|
-
import { useEffect as useEffect3, useMemo as
|
|
1153
|
+
import { useEffect as useEffect3, useMemo as useMemo4, useState as useState5 } from "react";
|
|
754
1154
|
import {
|
|
755
1155
|
Bot,
|
|
756
1156
|
Boxes,
|
|
757
1157
|
FileCode2,
|
|
758
1158
|
FileText as FileText2,
|
|
759
|
-
FolderTree,
|
|
1159
|
+
FolderTree as FolderTree2,
|
|
760
1160
|
LayoutPanelTop,
|
|
761
1161
|
X as X4
|
|
762
1162
|
} from "lucide-react";
|
|
763
|
-
import { jsx as
|
|
1163
|
+
import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
|
|
764
1164
|
function getArtifactTabIcon(kind) {
|
|
765
1165
|
switch (kind) {
|
|
766
1166
|
case "file":
|
|
@@ -785,10 +1185,10 @@ function ArtifactTabs({
|
|
|
785
1185
|
onClose
|
|
786
1186
|
}) {
|
|
787
1187
|
if (artifacts.length === 0) return null;
|
|
788
|
-
return /* @__PURE__ */
|
|
1188
|
+
return /* @__PURE__ */ jsx9("div", { className: "flex items-center overflow-x-auto border-b border-[var(--border-subtle)] bg-[var(--bg-dark)]", children: artifacts.map((artifact) => {
|
|
789
1189
|
const Icon = getArtifactTabIcon(artifact.kind);
|
|
790
1190
|
const isActive = artifact.id === activeArtifactId;
|
|
791
|
-
return /* @__PURE__ */
|
|
1191
|
+
return /* @__PURE__ */ jsxs9(
|
|
792
1192
|
"div",
|
|
793
1193
|
{
|
|
794
1194
|
className: cn(
|
|
@@ -796,26 +1196,26 @@ function ArtifactTabs({
|
|
|
796
1196
|
isActive ? "border-b-2 border-b-[var(--brand-cool)] bg-[var(--bg-card)] text-[var(--text-primary)]" : "text-[var(--text-muted)] hover:bg-[var(--bg-elevated)]"
|
|
797
1197
|
),
|
|
798
1198
|
children: [
|
|
799
|
-
/* @__PURE__ */
|
|
1199
|
+
/* @__PURE__ */ jsxs9(
|
|
800
1200
|
"button",
|
|
801
1201
|
{
|
|
802
1202
|
type: "button",
|
|
803
1203
|
onClick: () => onSelect(artifact.id),
|
|
804
1204
|
className: "flex min-w-0 items-center gap-2 px-3 py-2 text-xs transition-colors hover:text-[var(--text-secondary)] focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-inset focus-visible:ring-[var(--brand-cool)]/60",
|
|
805
1205
|
children: [
|
|
806
|
-
/* @__PURE__ */
|
|
807
|
-
/* @__PURE__ */
|
|
1206
|
+
/* @__PURE__ */ jsx9(Icon, { className: "h-3.5 w-3.5 shrink-0" }),
|
|
1207
|
+
/* @__PURE__ */ jsx9("span", { className: "max-w-[14rem] truncate", children: artifactTabLabel(artifact) })
|
|
808
1208
|
]
|
|
809
1209
|
}
|
|
810
1210
|
),
|
|
811
|
-
onClose && /* @__PURE__ */
|
|
1211
|
+
onClose && /* @__PURE__ */ jsx9(
|
|
812
1212
|
"button",
|
|
813
1213
|
{
|
|
814
1214
|
type: "button",
|
|
815
1215
|
"aria-label": `Close ${artifactTabLabel(artifact)}`,
|
|
816
1216
|
onClick: () => onClose(artifact.id),
|
|
817
1217
|
className: "mr-1 rounded p-1 opacity-0 transition-opacity hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)] focus-visible:opacity-100 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-[var(--brand-cool)]/60 group-hover:opacity-100",
|
|
818
|
-
children: /* @__PURE__ */
|
|
1218
|
+
children: /* @__PURE__ */ jsx9(X4, { className: "h-3 w-3" })
|
|
819
1219
|
}
|
|
820
1220
|
)
|
|
821
1221
|
]
|
|
@@ -827,7 +1227,7 @@ function ArtifactTabs({
|
|
|
827
1227
|
function renderArtifact(artifact) {
|
|
828
1228
|
switch (artifact.kind) {
|
|
829
1229
|
case "file":
|
|
830
|
-
return /* @__PURE__ */
|
|
1230
|
+
return /* @__PURE__ */ jsx9(
|
|
831
1231
|
FileArtifactPane,
|
|
832
1232
|
{
|
|
833
1233
|
path: artifact.path,
|
|
@@ -847,7 +1247,7 @@ function renderArtifact(artifact) {
|
|
|
847
1247
|
}
|
|
848
1248
|
);
|
|
849
1249
|
case "markdown":
|
|
850
|
-
return /* @__PURE__ */
|
|
1250
|
+
return /* @__PURE__ */ jsx9(
|
|
851
1251
|
ArtifactPane,
|
|
852
1252
|
{
|
|
853
1253
|
eyebrow: artifact.eyebrow ?? "Document",
|
|
@@ -857,11 +1257,11 @@ function renderArtifact(artifact) {
|
|
|
857
1257
|
headerActions: artifact.headerActions,
|
|
858
1258
|
toolbar: artifact.toolbar,
|
|
859
1259
|
footer: artifact.footer,
|
|
860
|
-
children: /* @__PURE__ */
|
|
1260
|
+
children: /* @__PURE__ */ jsx9("div", { className: "p-5", children: /* @__PURE__ */ jsx9(Markdown, { className: "prose-sm max-w-none", children: artifact.content }) })
|
|
861
1261
|
}
|
|
862
1262
|
);
|
|
863
1263
|
case "openui":
|
|
864
|
-
return /* @__PURE__ */
|
|
1264
|
+
return /* @__PURE__ */ jsx9(
|
|
865
1265
|
ArtifactPane,
|
|
866
1266
|
{
|
|
867
1267
|
eyebrow: artifact.eyebrow ?? "Structured Artifact",
|
|
@@ -871,11 +1271,11 @@ function renderArtifact(artifact) {
|
|
|
871
1271
|
headerActions: artifact.headerActions,
|
|
872
1272
|
toolbar: artifact.toolbar,
|
|
873
1273
|
footer: artifact.footer,
|
|
874
|
-
children: /* @__PURE__ */
|
|
1274
|
+
children: /* @__PURE__ */ jsx9(OpenUIArtifactRenderer, { schema: artifact.schema, onAction: artifact.onAction })
|
|
875
1275
|
}
|
|
876
1276
|
);
|
|
877
1277
|
case "custom":
|
|
878
|
-
return /* @__PURE__ */
|
|
1278
|
+
return /* @__PURE__ */ jsx9(
|
|
879
1279
|
ArtifactPane,
|
|
880
1280
|
{
|
|
881
1281
|
eyebrow: artifact.eyebrow ?? "Artifact",
|
|
@@ -890,6 +1290,44 @@ function renderArtifact(artifact) {
|
|
|
890
1290
|
);
|
|
891
1291
|
}
|
|
892
1292
|
}
|
|
1293
|
+
function regionHeader(sections, fallback) {
|
|
1294
|
+
if (sections.length !== 1) {
|
|
1295
|
+
return fallback;
|
|
1296
|
+
}
|
|
1297
|
+
switch (sections[0]?.key) {
|
|
1298
|
+
case "directory":
|
|
1299
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.12em] text-[var(--text-muted)]", children: [
|
|
1300
|
+
/* @__PURE__ */ jsx9(FolderTree2, { className: "h-3.5 w-3.5" }),
|
|
1301
|
+
"Directory"
|
|
1302
|
+
] });
|
|
1303
|
+
case "artifacts":
|
|
1304
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.12em] text-[var(--text-muted)]", children: [
|
|
1305
|
+
/* @__PURE__ */ jsx9(LayoutPanelTop, { className: "h-3.5 w-3.5" }),
|
|
1306
|
+
"Artifacts"
|
|
1307
|
+
] });
|
|
1308
|
+
case "runtime":
|
|
1309
|
+
return /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 text-xs font-semibold uppercase tracking-[0.12em] text-[var(--text-muted)]", children: [
|
|
1310
|
+
/* @__PURE__ */ jsx9(Bot, { className: "h-3.5 w-3.5" }),
|
|
1311
|
+
"Runtime"
|
|
1312
|
+
] });
|
|
1313
|
+
default:
|
|
1314
|
+
return fallback;
|
|
1315
|
+
}
|
|
1316
|
+
}
|
|
1317
|
+
function renderRegion(sections, region) {
|
|
1318
|
+
if (sections.length === 0) return void 0;
|
|
1319
|
+
if (sections.length === 1) return sections[0]?.content;
|
|
1320
|
+
return /* @__PURE__ */ jsx9(
|
|
1321
|
+
"div",
|
|
1322
|
+
{
|
|
1323
|
+
className: cn(
|
|
1324
|
+
"flex min-h-0 h-full gap-3 p-3",
|
|
1325
|
+
region === "bottom" ? "flex-col" : "flex-col"
|
|
1326
|
+
),
|
|
1327
|
+
children: sections.map((section) => /* @__PURE__ */ jsx9("div", { className: "min-h-0 flex-1 overflow-hidden", children: section.content }, section.key))
|
|
1328
|
+
}
|
|
1329
|
+
);
|
|
1330
|
+
}
|
|
893
1331
|
function SandboxWorkbench({
|
|
894
1332
|
title = "Sandbox session",
|
|
895
1333
|
subtitle,
|
|
@@ -905,7 +1343,7 @@ function SandboxWorkbench({
|
|
|
905
1343
|
emptyArtifactState,
|
|
906
1344
|
className
|
|
907
1345
|
}) {
|
|
908
|
-
const [uncontrolledArtifactId, setUncontrolledArtifactId] =
|
|
1346
|
+
const [uncontrolledArtifactId, setUncontrolledArtifactId] = useState5(
|
|
909
1347
|
activeArtifactId ?? artifacts[0]?.id
|
|
910
1348
|
);
|
|
911
1349
|
useEffect3(() => {
|
|
@@ -917,7 +1355,7 @@ function SandboxWorkbench({
|
|
|
917
1355
|
});
|
|
918
1356
|
}, [activeArtifactId, artifacts]);
|
|
919
1357
|
const resolvedArtifactId = activeArtifactId ?? uncontrolledArtifactId;
|
|
920
|
-
const activeArtifact =
|
|
1358
|
+
const activeArtifact = useMemo4(
|
|
921
1359
|
() => artifacts.find((artifact) => artifact.id === resolvedArtifactId),
|
|
922
1360
|
[artifacts, resolvedArtifactId]
|
|
923
1361
|
);
|
|
@@ -927,21 +1365,21 @@ function SandboxWorkbench({
|
|
|
927
1365
|
}
|
|
928
1366
|
onArtifactChange?.(artifactId);
|
|
929
1367
|
};
|
|
930
|
-
const centerHeader = /* @__PURE__ */
|
|
931
|
-
/* @__PURE__ */
|
|
932
|
-
/* @__PURE__ */
|
|
933
|
-
/* @__PURE__ */
|
|
934
|
-
subtitle && /* @__PURE__ */
|
|
1368
|
+
const centerHeader = /* @__PURE__ */ jsxs9("div", { className: "flex min-w-0 items-start justify-between gap-4 rounded-[calc(var(--radius-xl)+2px)] border border-[var(--border-subtle)] bg-[radial-gradient(circle_at_top_left,rgba(96,165,250,0.16),transparent_34%),linear-gradient(135deg,rgba(98,114,243,0.14),rgba(255,255,255,0.03)_42%,transparent_76%)] px-4 py-3.5 shadow-[var(--shadow-accent)] backdrop-blur-sm", children: [
|
|
1369
|
+
/* @__PURE__ */ jsxs9("div", { className: "min-w-0", children: [
|
|
1370
|
+
/* @__PURE__ */ jsx9("div", { className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-[var(--brand-cool)]", children: "Tangle Sandbox" }),
|
|
1371
|
+
/* @__PURE__ */ jsx9("div", { className: "truncate text-[17px] font-semibold tracking-[0.01em] text-[var(--text-primary)]", children: title }),
|
|
1372
|
+
subtitle && /* @__PURE__ */ jsx9("div", { className: "truncate text-sm text-[var(--text-muted)]", children: subtitle })
|
|
935
1373
|
] }),
|
|
936
|
-
/* @__PURE__ */
|
|
1374
|
+
/* @__PURE__ */ jsxs9("div", { className: "flex shrink-0 flex-wrap items-center justify-end gap-2", children: [
|
|
937
1375
|
status,
|
|
938
|
-
artifacts.length > 0 && /* @__PURE__ */
|
|
1376
|
+
artifacts.length > 0 && /* @__PURE__ */ jsxs9(Badge, { variant: "outline", children: [
|
|
939
1377
|
artifacts.length,
|
|
940
1378
|
" artifacts"
|
|
941
1379
|
] })
|
|
942
1380
|
] })
|
|
943
1381
|
] });
|
|
944
|
-
const center = /* @__PURE__ */
|
|
1382
|
+
const center = /* @__PURE__ */ jsx9(
|
|
945
1383
|
ArtifactPane,
|
|
946
1384
|
{
|
|
947
1385
|
eyebrow: session.eyebrow ?? "Agent Session",
|
|
@@ -951,7 +1389,7 @@ function SandboxWorkbench({
|
|
|
951
1389
|
headerActions: session.headerActions,
|
|
952
1390
|
className: "h-full",
|
|
953
1391
|
contentClassName: "bg-[radial-gradient(circle_at_top,rgba(82,164,255,0.1),transparent_34%),linear-gradient(180deg,rgba(255,255,255,0.02),transparent_22%)]",
|
|
954
|
-
children: /* @__PURE__ */
|
|
1392
|
+
children: /* @__PURE__ */ jsx9(
|
|
955
1393
|
ChatContainer,
|
|
956
1394
|
{
|
|
957
1395
|
...session,
|
|
@@ -961,8 +1399,8 @@ function SandboxWorkbench({
|
|
|
961
1399
|
)
|
|
962
1400
|
}
|
|
963
1401
|
);
|
|
964
|
-
const
|
|
965
|
-
/* @__PURE__ */
|
|
1402
|
+
const artifactPanel = artifacts.length > 0 ? /* @__PURE__ */ jsxs9("section", { className: "flex h-full min-h-0 flex-col bg-[var(--bg-dark)]", children: [
|
|
1403
|
+
/* @__PURE__ */ jsx9(
|
|
966
1404
|
ArtifactTabs,
|
|
967
1405
|
{
|
|
968
1406
|
artifacts,
|
|
@@ -971,37 +1409,62 @@ function SandboxWorkbench({
|
|
|
971
1409
|
onClose: onArtifactClose
|
|
972
1410
|
}
|
|
973
1411
|
),
|
|
974
|
-
/* @__PURE__ */
|
|
1412
|
+
/* @__PURE__ */ jsx9("div", { className: "min-h-0 flex-1 overflow-auto bg-[linear-gradient(180deg,rgba(255,255,255,0.02),transparent)]", children: activeArtifact ? renderArtifact(activeArtifact) : /* @__PURE__ */ jsx9("div", { className: "flex h-full items-center justify-center p-6", children: emptyArtifactState ?? /* @__PURE__ */ jsx9(
|
|
975
1413
|
EmptyState,
|
|
976
1414
|
{
|
|
977
|
-
icon: /* @__PURE__ */
|
|
1415
|
+
icon: /* @__PURE__ */ jsx9(Boxes, { className: "h-8 w-8" }),
|
|
978
1416
|
title: "No artifact selected",
|
|
979
1417
|
description: "Select a generated artifact, file preview, or OpenUI panel to inspect it here."
|
|
980
1418
|
}
|
|
981
1419
|
) }) })
|
|
982
1420
|
] }) : null;
|
|
983
|
-
|
|
1421
|
+
const directoryPlacement = layout?.directoryPlacement ?? (directory ? "left" : "hidden");
|
|
1422
|
+
const artifactPlacement = layout?.artifactPlacement ?? (artifacts.length > 0 ? "right" : "hidden");
|
|
1423
|
+
const runtimePlacement = layout?.runtimePlacement ?? (runtime ? "bottom" : "hidden");
|
|
1424
|
+
const regionSections = {
|
|
1425
|
+
left: [],
|
|
1426
|
+
right: [],
|
|
1427
|
+
bottom: []
|
|
1428
|
+
};
|
|
1429
|
+
if (directory && directoryPlacement !== "hidden") {
|
|
1430
|
+
regionSections[directoryPlacement].push({
|
|
1431
|
+
key: "directory",
|
|
1432
|
+
content: /* @__PURE__ */ jsx9(DirectoryPane, { ...directory, className: "h-full" })
|
|
1433
|
+
});
|
|
1434
|
+
}
|
|
1435
|
+
if (artifactPanel && artifactPlacement !== "hidden") {
|
|
1436
|
+
regionSections[artifactPlacement].push({
|
|
1437
|
+
key: "artifacts",
|
|
1438
|
+
content: artifactPanel
|
|
1439
|
+
});
|
|
1440
|
+
}
|
|
1441
|
+
if (runtime && runtimePlacement !== "hidden") {
|
|
1442
|
+
regionSections[runtimePlacement].push({
|
|
1443
|
+
key: "runtime",
|
|
1444
|
+
content: /* @__PURE__ */ jsx9(RuntimePane, { ...runtime, className: "h-full" })
|
|
1445
|
+
});
|
|
1446
|
+
}
|
|
1447
|
+
const left = renderRegion(regionSections.left, "left");
|
|
1448
|
+
const right = renderRegion(regionSections.right, "right");
|
|
1449
|
+
const bottom = renderRegion(regionSections.bottom, "bottom");
|
|
1450
|
+
const genericPanelsHeader = /* @__PURE__ */ jsx9("span", { className: "text-xs font-semibold uppercase tracking-[0.12em] text-[var(--text-muted)]", children: "Workspace Panels" });
|
|
1451
|
+
return /* @__PURE__ */ jsx9(
|
|
984
1452
|
WorkspaceLayout,
|
|
985
1453
|
{
|
|
986
|
-
left
|
|
987
|
-
leftHeader:
|
|
988
|
-
/* @__PURE__ */ jsx7(FolderTree, { className: "h-3.5 w-3.5" }),
|
|
989
|
-
"Directory"
|
|
990
|
-
] }) : void 0,
|
|
1454
|
+
left,
|
|
1455
|
+
leftHeader: left ? regionHeader(regionSections.left, genericPanelsHeader) : void 0,
|
|
991
1456
|
center,
|
|
992
1457
|
centerHeader,
|
|
993
1458
|
right,
|
|
994
|
-
rightHeader: right ?
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
] }) : void 0,
|
|
998
|
-
bottom: runtime ? /* @__PURE__ */ jsx7(RuntimePane, { ...runtime, className: "h-full" }) : void 0,
|
|
1459
|
+
rightHeader: right ? regionHeader(regionSections.right, genericPanelsHeader) : void 0,
|
|
1460
|
+
bottom,
|
|
1461
|
+
bottomHeader: bottom ? regionHeader(regionSections.bottom, genericPanelsHeader) : void 0,
|
|
999
1462
|
theme: layout?.theme ?? "operator",
|
|
1000
1463
|
density: layout?.density ?? "comfortable",
|
|
1001
1464
|
persistenceKey: layout?.persistenceKey,
|
|
1002
|
-
defaultLeftOpen: layout?.defaultLeftOpen ?? Boolean(
|
|
1003
|
-
defaultRightOpen: layout?.defaultRightOpen ??
|
|
1004
|
-
defaultBottomOpen: layout?.defaultBottomOpen ?? Boolean(
|
|
1465
|
+
defaultLeftOpen: layout?.defaultLeftOpen ?? Boolean(left),
|
|
1466
|
+
defaultRightOpen: layout?.defaultRightOpen ?? Boolean(right),
|
|
1467
|
+
defaultBottomOpen: layout?.defaultBottomOpen ?? Boolean(bottom),
|
|
1005
1468
|
defaultLeftWidth: layout?.defaultLeftWidth,
|
|
1006
1469
|
defaultRightWidth: layout?.defaultRightWidth,
|
|
1007
1470
|
minLeftWidth: layout?.minLeftWidth,
|
|
@@ -1014,15 +1477,15 @@ function SandboxWorkbench({
|
|
|
1014
1477
|
);
|
|
1015
1478
|
}
|
|
1016
1479
|
function AgentWorkbench(props) {
|
|
1017
|
-
return /* @__PURE__ */
|
|
1480
|
+
return /* @__PURE__ */ jsx9(
|
|
1018
1481
|
SandboxWorkbench,
|
|
1019
1482
|
{
|
|
1020
1483
|
...props,
|
|
1021
1484
|
session: {
|
|
1022
1485
|
...props.session,
|
|
1023
1486
|
eyebrow: props.session.eyebrow ?? "Agent Session",
|
|
1024
|
-
title: props.session.title ?? /* @__PURE__ */
|
|
1025
|
-
/* @__PURE__ */
|
|
1487
|
+
title: props.session.title ?? /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center gap-2", children: [
|
|
1488
|
+
/* @__PURE__ */ jsx9(Bot, { className: "h-4 w-4 text-[var(--brand-cool)]" }),
|
|
1026
1489
|
"Execution timeline"
|
|
1027
1490
|
] })
|
|
1028
1491
|
}
|
|
@@ -1031,65 +1494,65 @@ function AgentWorkbench(props) {
|
|
|
1031
1494
|
}
|
|
1032
1495
|
|
|
1033
1496
|
// src/workspace/audit-results.tsx
|
|
1034
|
-
import { useState as
|
|
1497
|
+
import { useState as useState6 } from "react";
|
|
1035
1498
|
import { CheckCircle as CheckCircle2, XCircle, ChevronRight, Shield } from "lucide-react";
|
|
1036
|
-
import { jsx as
|
|
1499
|
+
import { jsx as jsx10, jsxs as jsxs10 } from "react/jsx-runtime";
|
|
1037
1500
|
function AuditResults({ forms, crossFormChecks = [], overallScore, className }) {
|
|
1038
1501
|
const totalPassed = forms.reduce((s, f) => s + f.passed, 0);
|
|
1039
1502
|
const totalChecks = forms.reduce((s, f) => s + f.passed + f.failed, 0);
|
|
1040
|
-
return /* @__PURE__ */
|
|
1041
|
-
/* @__PURE__ */
|
|
1042
|
-
/* @__PURE__ */
|
|
1043
|
-
/* @__PURE__ */
|
|
1044
|
-
/* @__PURE__ */
|
|
1503
|
+
return /* @__PURE__ */ jsxs10("div", { className: cn("space-y-3 p-3", className), children: [
|
|
1504
|
+
/* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-3 px-3 py-2 rounded-[var(--radius-md)] bg-[var(--bg-input)] border border-[var(--border-subtle)]", children: [
|
|
1505
|
+
/* @__PURE__ */ jsx10(Shield, { className: cn("h-5 w-5", totalChecks === totalPassed ? "text-[var(--code-success)]" : "text-[var(--code-number)]") }),
|
|
1506
|
+
/* @__PURE__ */ jsxs10("div", { children: [
|
|
1507
|
+
/* @__PURE__ */ jsxs10("div", { className: "text-sm font-semibold text-[var(--text-primary)]", children: [
|
|
1045
1508
|
totalPassed,
|
|
1046
1509
|
"/",
|
|
1047
1510
|
totalChecks,
|
|
1048
1511
|
" checks passed"
|
|
1049
1512
|
] }),
|
|
1050
|
-
overallScore !== void 0 && /* @__PURE__ */
|
|
1513
|
+
overallScore !== void 0 && /* @__PURE__ */ jsxs10("div", { className: "text-xs text-[var(--text-muted)]", children: [
|
|
1051
1514
|
"Score: ",
|
|
1052
1515
|
overallScore,
|
|
1053
1516
|
"/100"
|
|
1054
1517
|
] })
|
|
1055
1518
|
] })
|
|
1056
1519
|
] }),
|
|
1057
|
-
forms.map((form) => /* @__PURE__ */
|
|
1058
|
-
crossFormChecks.length > 0 && /* @__PURE__ */
|
|
1059
|
-
/* @__PURE__ */
|
|
1060
|
-
crossFormChecks.map((check, i) => /* @__PURE__ */
|
|
1520
|
+
forms.map((form) => /* @__PURE__ */ jsx10(FormAuditCard, { form }, form.formId)),
|
|
1521
|
+
crossFormChecks.length > 0 && /* @__PURE__ */ jsxs10("div", { children: [
|
|
1522
|
+
/* @__PURE__ */ jsx10("div", { className: "text-xs font-semibold text-[var(--text-muted)] uppercase tracking-wider mb-1", children: "Cross-Form Checks" }),
|
|
1523
|
+
crossFormChecks.map((check, i) => /* @__PURE__ */ jsx10(CheckRow, { check }, i))
|
|
1061
1524
|
] })
|
|
1062
1525
|
] });
|
|
1063
1526
|
}
|
|
1064
1527
|
function FormAuditCard({ form }) {
|
|
1065
|
-
const [expanded, setExpanded] =
|
|
1528
|
+
const [expanded, setExpanded] = useState6(form.failed > 0);
|
|
1066
1529
|
const allPassed = form.failed === 0 && form.found;
|
|
1067
|
-
return /* @__PURE__ */
|
|
1068
|
-
/* @__PURE__ */
|
|
1530
|
+
return /* @__PURE__ */ jsxs10("div", { className: "rounded-[var(--radius-md)] border border-[var(--border-subtle)] overflow-hidden", children: [
|
|
1531
|
+
/* @__PURE__ */ jsxs10(
|
|
1069
1532
|
"button",
|
|
1070
1533
|
{
|
|
1071
1534
|
onClick: () => setExpanded(!expanded),
|
|
1072
1535
|
className: "flex items-center gap-2 w-full px-3 py-2 text-left hover:bg-[var(--bg-hover)] transition-colors",
|
|
1073
1536
|
children: [
|
|
1074
|
-
allPassed ? /* @__PURE__ */
|
|
1075
|
-
/* @__PURE__ */
|
|
1076
|
-
/* @__PURE__ */
|
|
1537
|
+
allPassed ? /* @__PURE__ */ jsx10(CheckCircle2, { className: "h-4 w-4 text-[var(--code-success)] shrink-0" }) : !form.found ? /* @__PURE__ */ jsx10(XCircle, { className: "h-4 w-4 text-[var(--code-error)] shrink-0" }) : /* @__PURE__ */ jsx10(XCircle, { className: "h-4 w-4 text-[var(--code-number)] shrink-0" }),
|
|
1538
|
+
/* @__PURE__ */ jsx10("span", { className: "text-sm font-medium text-[var(--text-primary)] flex-1", children: form.formName || form.formId }),
|
|
1539
|
+
/* @__PURE__ */ jsxs10("span", { className: cn("text-xs tabular-nums", allPassed ? "text-[var(--code-success)]" : "text-[var(--text-muted)]"), children: [
|
|
1077
1540
|
form.passed,
|
|
1078
1541
|
"/",
|
|
1079
1542
|
form.passed + form.failed
|
|
1080
1543
|
] }),
|
|
1081
|
-
/* @__PURE__ */
|
|
1544
|
+
/* @__PURE__ */ jsx10(ChevronRight, { className: cn("h-3 w-3 text-[var(--text-muted)] transition-transform", expanded && "rotate-90") })
|
|
1082
1545
|
]
|
|
1083
1546
|
}
|
|
1084
1547
|
),
|
|
1085
|
-
expanded && /* @__PURE__ */
|
|
1548
|
+
expanded && /* @__PURE__ */ jsx10("div", { className: "border-t border-[var(--border-subtle)] px-3 py-1.5 space-y-0.5", children: form.checks.map((check, i) => /* @__PURE__ */ jsx10(CheckRow, { check }, i)) })
|
|
1086
1549
|
] });
|
|
1087
1550
|
}
|
|
1088
1551
|
function CheckRow({ check }) {
|
|
1089
|
-
return /* @__PURE__ */
|
|
1090
|
-
check.passed ? /* @__PURE__ */
|
|
1091
|
-
/* @__PURE__ */
|
|
1092
|
-
/* @__PURE__ */
|
|
1552
|
+
return /* @__PURE__ */ jsxs10("div", { className: "flex items-center gap-2 py-1 text-xs", children: [
|
|
1553
|
+
check.passed ? /* @__PURE__ */ jsx10(CheckCircle2, { className: "h-3 w-3 text-[var(--code-success)] shrink-0" }) : /* @__PURE__ */ jsx10(XCircle, { className: "h-3 w-3 text-[var(--code-error)] shrink-0" }),
|
|
1554
|
+
/* @__PURE__ */ jsx10("span", { className: "text-[var(--text-secondary)] flex-1 truncate", children: check.label }),
|
|
1555
|
+
/* @__PURE__ */ jsx10("span", { className: "text-[var(--text-muted)] tabular-nums shrink-0", children: check.passed ? String(check.actual ?? check.expected) : `${check.actual ?? "missing"} \u2260 ${check.expected}` })
|
|
1093
1556
|
] });
|
|
1094
1557
|
}
|
|
1095
1558
|
|
|
@@ -1100,6 +1563,8 @@ export {
|
|
|
1100
1563
|
StatusBar,
|
|
1101
1564
|
TerminalPanel,
|
|
1102
1565
|
RuntimePane,
|
|
1566
|
+
SessionSidebar,
|
|
1567
|
+
SessionActivityMonitor,
|
|
1103
1568
|
SandboxWorkbench,
|
|
1104
1569
|
AgentWorkbench,
|
|
1105
1570
|
AuditResults
|