@tangle-network/sandbox-ui 0.22.1 → 0.23.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.
@@ -7,6 +7,7 @@ import {
7
7
  } from "./chunk-EI44GEQ5.js";
8
8
 
9
9
  // src/dashboard/app-sidebar.tsx
10
+ import * as React2 from "react";
10
11
  import { Avatar, AvatarFallback, AvatarImage } from "@tangle-network/ui/primitives";
11
12
  import {
12
13
  DropdownMenu,
@@ -27,6 +28,7 @@ var SIDEBAR_RAIL_WIDTH = 64;
27
28
  var SIDEBAR_PANEL_WIDTH = 260;
28
29
  var SIDEBAR_TOTAL_WIDTH = SIDEBAR_RAIL_WIDTH + SIDEBAR_PANEL_WIDTH;
29
30
  var SIDEBAR_MOBILE_WIDTH = 256;
31
+ var SIDEBAR_RAIL_LABELED_WIDTH = 224;
30
32
  var SidebarContext = React.createContext(null);
31
33
  function readStorage(key, fallback) {
32
34
  if (typeof window === "undefined") return fallback;
@@ -47,49 +49,44 @@ function SidebarProvider({
47
49
  defaultPanelOpen = true,
48
50
  defaultMode = "projects",
49
51
  hasPanels = true,
52
+ railWidth = SIDEBAR_RAIL_WIDTH,
53
+ panelOpen: controlledPanelOpen,
54
+ onPanelOpenChange,
50
55
  children
51
56
  }) {
52
- const [panelOpen, setPanelOpenState] = React.useState(
53
- () => readStorage(PANEL_OPEN_KEY, String(defaultPanelOpen)) === "true"
57
+ const isControlled = controlledPanelOpen !== void 0;
58
+ const [uncontrolledPanelOpen, setUncontrolledPanelOpen] = React.useState(
59
+ () => isControlled ? controlledPanelOpen : readStorage(PANEL_OPEN_KEY, String(defaultPanelOpen)) === "true"
54
60
  );
61
+ const panelOpen = isControlled ? controlledPanelOpen : uncontrolledPanelOpen;
55
62
  const [mode, setModeState] = React.useState(
56
- () => readStorage(SIDEBAR_MODE_KEY, defaultMode)
63
+ () => isControlled ? defaultMode : readStorage(SIDEBAR_MODE_KEY, defaultMode)
57
64
  );
58
65
  const [hidden, setHidden] = React.useState(false);
59
66
  const setPanelOpen = React.useCallback((open) => {
60
- setPanelOpenState(open);
61
- writeStorage(PANEL_OPEN_KEY, String(open));
62
- }, []);
67
+ if (!isControlled) {
68
+ setUncontrolledPanelOpen(open);
69
+ writeStorage(PANEL_OPEN_KEY, String(open));
70
+ }
71
+ onPanelOpenChange?.(open);
72
+ }, [isControlled, onPanelOpenChange]);
63
73
  const togglePanel = React.useCallback(() => {
64
- setPanelOpenState((prev) => {
65
- const next = !prev;
66
- writeStorage(PANEL_OPEN_KEY, String(next));
67
- return next;
68
- });
69
- }, []);
74
+ setPanelOpen(!panelOpen);
75
+ }, [setPanelOpen, panelOpen]);
70
76
  const setMode = React.useCallback((m) => {
71
77
  setModeState(m);
72
- writeStorage(SIDEBAR_MODE_KEY, m);
73
- }, []);
74
- const switchModeStable = React.useCallback((m) => {
75
- setModeState((prevMode) => {
76
- if (prevMode === m) {
77
- setPanelOpenState((prevOpen) => {
78
- const next = !prevOpen;
79
- writeStorage(PANEL_OPEN_KEY, String(next));
80
- return next;
81
- });
82
- return prevMode;
83
- }
84
- setPanelOpenState(() => {
85
- writeStorage(PANEL_OPEN_KEY, "true");
86
- return true;
87
- });
88
- writeStorage(SIDEBAR_MODE_KEY, m);
89
- return m;
90
- });
91
- }, []);
92
- const contentMargin = hidden ? 0 : panelOpen && hasPanels ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH;
78
+ if (!isControlled) writeStorage(SIDEBAR_MODE_KEY, m);
79
+ }, [isControlled]);
80
+ const switchMode = React.useCallback((m) => {
81
+ if (mode === m) {
82
+ setPanelOpen(!panelOpen);
83
+ return;
84
+ }
85
+ setModeState(m);
86
+ if (!isControlled) writeStorage(SIDEBAR_MODE_KEY, m);
87
+ setPanelOpen(true);
88
+ }, [mode, panelOpen, isControlled, setPanelOpen]);
89
+ const contentMargin = hidden ? 0 : panelOpen && hasPanels ? railWidth + SIDEBAR_PANEL_WIDTH : railWidth;
93
90
  const value = React.useMemo(
94
91
  () => ({
95
92
  panelOpen,
@@ -97,13 +94,14 @@ function SidebarProvider({
97
94
  togglePanel,
98
95
  mode,
99
96
  setMode,
100
- switchMode: switchModeStable,
97
+ switchMode,
101
98
  hidden,
102
99
  setHidden,
103
100
  contentMargin,
104
- hasPanels
101
+ hasPanels,
102
+ railWidth
105
103
  }),
106
- [panelOpen, setPanelOpen, togglePanel, mode, setMode, switchModeStable, hidden, setHidden, contentMargin, hasPanels]
104
+ [panelOpen, setPanelOpen, togglePanel, mode, setMode, switchMode, hidden, setHidden, contentMargin, hasPanels, railWidth]
107
105
  );
108
106
  return /* @__PURE__ */ jsx(SidebarContext.Provider, { value, children });
109
107
  }
@@ -145,7 +143,7 @@ function LogOutIcon({ className }) {
145
143
  ] });
146
144
  }
147
145
  function Sidebar({ children, className, style }) {
148
- const { panelOpen, hidden, hasPanels } = useSidebar();
146
+ const { panelOpen, hidden, hasPanels, railWidth } = useSidebar();
149
147
  return /* @__PURE__ */ jsx2(
150
148
  "div",
151
149
  {
@@ -155,20 +153,22 @@ function Sidebar({ children, className, style }) {
155
153
  hidden && "-translate-x-full",
156
154
  className
157
155
  ),
158
- style: { width: panelOpen && hasPanels ? SIDEBAR_TOTAL_WIDTH : SIDEBAR_RAIL_WIDTH, ...style },
156
+ style: { width: panelOpen && hasPanels ? railWidth + SIDEBAR_PANEL_WIDTH : railWidth, ...style },
159
157
  children
160
158
  }
161
159
  );
162
160
  }
163
161
  function SidebarRail({ children, className, wide = false }) {
162
+ const { railWidth } = useSidebar();
164
163
  return /* @__PURE__ */ jsx2(
165
164
  "div",
166
165
  {
167
166
  className: cn(
168
167
  "flex flex-col h-full shrink-0 bg-transparent",
169
- wide ? "w-full" : "w-16",
168
+ wide && "w-full",
170
169
  className
171
170
  ),
171
+ style: wide ? void 0 : { width: railWidth },
172
172
  children
173
173
  }
174
174
  );
@@ -185,30 +185,31 @@ function SidebarRailFooter({ children, className }) {
185
185
  function RailSeparator({ className }) {
186
186
  return /* @__PURE__ */ jsx2("div", { className: cn("my-2 h-px w-10 bg-[var(--md3-outline-variant)]", className) });
187
187
  }
188
- function RailButton({ icon: Icon, label, isActive, badge, onClick, className, showLabel }) {
189
- return /* @__PURE__ */ jsxs(
190
- "button",
191
- {
192
- type: "button",
193
- onClick,
194
- title: label,
195
- className: cn(
196
- "group relative flex items-center justify-center rounded-xl transition-all duration-200",
197
- showLabel ? "w-full justify-start px-3 h-11 gap-3" : "w-11 h-11 justify-center",
198
- "hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]",
199
- "active:scale-95",
200
- "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
201
- isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]",
202
- !isActive && "text-muted-foreground",
203
- className
204
- ),
205
- children: [
206
- /* @__PURE__ */ jsx2(Icon, { className: "h-5 w-5 shrink-0" }),
207
- showLabel && /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium", children: label }),
208
- badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-[var(--md3-on-primary)] px-1 shadow-sm", children: badge > 99 ? "99+" : badge })
209
- ]
210
- }
188
+ function RailButton({ icon: Icon, label, isActive, badge, onClick, className, showLabel, asChild, children }) {
189
+ const classes = cn(
190
+ "group relative flex items-center justify-center rounded-xl transition-all duration-200",
191
+ showLabel ? "w-full justify-start px-3 h-11 gap-3" : "w-11 h-11 justify-center",
192
+ "hover:bg-[var(--accent-surface-soft)] hover:text-[var(--accent-text)]",
193
+ "active:scale-95",
194
+ "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
195
+ isActive && "bg-[var(--accent-surface-strong)] text-[var(--accent-text)]",
196
+ !isActive && "text-muted-foreground",
197
+ className
211
198
  );
199
+ const content = /* @__PURE__ */ jsxs(Fragment, { children: [
200
+ /* @__PURE__ */ jsx2(Icon, { className: "h-5 w-5 shrink-0" }),
201
+ showLabel && /* @__PURE__ */ jsx2("span", { className: "text-sm font-medium", children: label }),
202
+ badge !== void 0 && badge > 0 && /* @__PURE__ */ jsx2("span", { className: "absolute -top-1 -right-1 flex h-4 min-w-4 items-center justify-center rounded-full bg-primary text-[9px] font-bold text-[var(--md3-on-primary)] px-1 shadow-sm", children: badge > 99 ? "99+" : badge })
203
+ ] });
204
+ if (asChild && React2.isValidElement(children)) {
205
+ const child = children;
206
+ return React2.cloneElement(
207
+ child,
208
+ { className: cn(classes, child.props.className), title: child.props.title ?? label },
209
+ content
210
+ );
211
+ }
212
+ return /* @__PURE__ */ jsx2("button", { type: "button", onClick, title: label, className: classes, children: content });
212
213
  }
213
214
  function RailModeButton({ mode, icon, label, badge, className, showLabel }) {
214
215
  const { panelOpen, mode: currentMode, switchMode } = useSidebar();
@@ -267,24 +268,35 @@ function ProfileAvatar({
267
268
  settingsHref = "/dashboard/settings",
268
269
  children,
269
270
  className,
271
+ showDetails = false,
270
272
  LinkComponent
271
273
  }) {
272
274
  const Link = LinkComponent ?? DefaultLink;
273
275
  return /* @__PURE__ */ jsxs(DropdownMenu, { children: [
274
- /* @__PURE__ */ jsx2(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsx2(
276
+ /* @__PURE__ */ jsx2(DropdownMenuTrigger, { asChild: true, children: /* @__PURE__ */ jsxs(
275
277
  "button",
276
278
  {
277
279
  type: "button",
278
280
  className: cn(
279
- "flex items-center justify-center w-12 h-12 rounded-lg transition-colors hover:bg-[var(--accent-surface-soft)]",
281
+ "flex items-center rounded-lg transition-colors hover:bg-[var(--accent-surface-soft)]",
280
282
  "focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-primary",
283
+ showDetails ? "w-full gap-2.5 px-3 py-2 text-left" : "justify-center w-12 h-12",
281
284
  className
282
285
  ),
283
286
  "aria-label": "User menu",
284
- children: isLoading ? /* @__PURE__ */ jsx2(Skeleton, { className: "h-7 w-7 rounded-full" }) : /* @__PURE__ */ jsxs(Avatar, { className: "h-7 w-7", children: [
285
- user?.avatarUrl && /* @__PURE__ */ jsx2(AvatarImage, { src: user.avatarUrl, alt: "" }),
286
- /* @__PURE__ */ jsx2(AvatarFallback, { className: "text-[10px] bg-violet-500/20 text-violet-300", children: getInitials(user?.name, user?.email) })
287
- ] })
287
+ children: [
288
+ isLoading ? /* @__PURE__ */ jsx2(Skeleton, { className: "h-7 w-7 shrink-0 rounded-full" }) : /* @__PURE__ */ jsxs(Avatar, { className: "h-7 w-7 shrink-0", children: [
289
+ user?.avatarUrl && /* @__PURE__ */ jsx2(AvatarImage, { src: user.avatarUrl, alt: "" }),
290
+ /* @__PURE__ */ jsx2(AvatarFallback, { className: "text-[10px] bg-violet-500/20 text-violet-300", children: getInitials(user?.name, user?.email) })
291
+ ] }),
292
+ showDetails && /* @__PURE__ */ jsx2("div", { className: "min-w-0 flex-1", children: isLoading ? /* @__PURE__ */ jsxs(Fragment, { children: [
293
+ /* @__PURE__ */ jsx2(Skeleton, { className: "mb-1 h-3.5 w-20" }),
294
+ /* @__PURE__ */ jsx2(Skeleton, { className: "h-3 w-28" })
295
+ ] }) : /* @__PURE__ */ jsxs(Fragment, { children: [
296
+ /* @__PURE__ */ jsx2("p", { className: "truncate text-sm font-medium text-foreground", children: user?.name ?? user?.email ?? "Not signed in" }),
297
+ user?.email && user?.name && /* @__PURE__ */ jsx2("p", { className: "truncate text-xs text-muted-foreground", children: user.email })
298
+ ] }) })
299
+ ]
288
300
  }
289
301
  ) }),
290
302
  /* @__PURE__ */ jsxs(DropdownMenuContent, { side: "right", align: "end", sideOffset: 8, className: "w-72", children: [
@@ -326,7 +338,7 @@ function ProfileAvatar({
326
338
  }
327
339
 
328
340
  // src/dashboard/credit-balance.tsx
329
- import * as React2 from "react";
341
+ import * as React3 from "react";
330
342
  import { jsx as jsx3, jsxs as jsxs2 } from "react/jsx-runtime";
331
343
  function CreditBalance({
332
344
  amount,
@@ -335,7 +347,7 @@ function CreditBalance({
335
347
  quickAmounts = [10, 25, 100],
336
348
  className
337
349
  }) {
338
- const [topUpValue, setTopUpValue] = React2.useState("50.00");
350
+ const [topUpValue, setTopUpValue] = React3.useState("50.00");
339
351
  return /* @__PURE__ */ jsxs2(
340
352
  "div",
341
353
  {
@@ -558,7 +570,7 @@ function ResourceSnapshot({
558
570
  }
559
571
 
560
572
  // src/dashboard/activity-feed.tsx
561
- import * as React3 from "react";
573
+ import * as React4 from "react";
562
574
  import { Skeleton as Skeleton3 } from "@tangle-network/ui/primitives";
563
575
  import { timeAgo } from "@tangle-network/ui/utils";
564
576
  import { jsx as jsx8, jsxs as jsxs7 } from "react/jsx-runtime";
@@ -571,7 +583,7 @@ function ActivityFeed({
571
583
  emptyLabel = "No recent activity",
572
584
  className
573
585
  }) {
574
- const sorted = React3.useMemo(
586
+ const sorted = React4.useMemo(
575
587
  () => [...items].sort((a, b) => (b.timestamp ?? 0) - (a.timestamp ?? 0)).slice(0, maxItems),
576
588
  [items, maxItems]
577
589
  );
@@ -813,7 +825,7 @@ function NewSandboxCard({ onClick, className }) {
813
825
  }
814
826
 
815
827
  // src/dashboard/sandbox-table.tsx
816
- import * as React4 from "react";
828
+ import * as React5 from "react";
817
829
  import {
818
830
  Activity as Activity2,
819
831
  BarChart2 as BarChart22,
@@ -1088,7 +1100,7 @@ function SandboxTable({
1088
1100
  children: /* @__PURE__ */ jsx10(MoreVertical2, { className: "h-4 w-4" })
1089
1101
  }
1090
1102
  ) }),
1091
- /* @__PURE__ */ jsx10(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs9(React4.Fragment, { children: [
1103
+ /* @__PURE__ */ jsx10(DropdownMenuContent3, { align: "end", className: "min-w-[180px]", children: overflowSections.map((section, sectionIdx) => /* @__PURE__ */ jsxs9(React5.Fragment, { children: [
1092
1104
  sectionIdx > 0 && /* @__PURE__ */ jsx10(DropdownMenuSeparator3, {}),
1093
1105
  section
1094
1106
  ] }, sectionIdx)) })
@@ -1225,7 +1237,7 @@ function PlanCards({ plans, className }) {
1225
1237
  }
1226
1238
 
1227
1239
  // src/dashboard/dashboard-layout.tsx
1228
- import * as React5 from "react";
1240
+ import * as React6 from "react";
1229
1241
  import { Plus as Plus2, Bell } from "lucide-react";
1230
1242
  import { Fragment as Fragment7, jsx as jsx13, jsxs as jsxs12 } from "react/jsx-runtime";
1231
1243
  function SettingsIconSmall({ className }) {
@@ -1288,10 +1300,10 @@ function DashboardLayoutInner({
1288
1300
  notifications: notifData
1289
1301
  }) {
1290
1302
  const Link = LinkComponent;
1291
- const [mobileMenuOpen, setMobileMenuOpen] = React5.useState(false);
1292
- const [notificationsOpen, setNotificationsOpen] = React5.useState(false);
1293
- const notifRef = React5.useRef(null);
1294
- React5.useEffect(() => {
1303
+ const [mobileMenuOpen, setMobileMenuOpen] = React6.useState(false);
1304
+ const [notificationsOpen, setNotificationsOpen] = React6.useState(false);
1305
+ const notifRef = React6.useRef(null);
1306
+ React6.useEffect(() => {
1295
1307
  if (!notificationsOpen) return;
1296
1308
  const handler = (e) => {
1297
1309
  if (notifRef.current && !notifRef.current.contains(e.target)) {
@@ -1309,13 +1321,13 @@ function DashboardLayoutInner({
1309
1321
  };
1310
1322
  }, [notificationsOpen]);
1311
1323
  const { contentMargin, hidden, mode, hasPanels, panelOpen } = useSidebar();
1312
- const modeSet = React5.useMemo(() => new Set(modeItems), [modeItems]);
1313
- const sidebarUser = React5.useMemo(
1324
+ const modeSet = React6.useMemo(() => new Set(modeItems), [modeItems]);
1325
+ const sidebarUser = React6.useMemo(
1314
1326
  () => user ? { email: user.email, name: user.name, tier: user.tier, avatarUrl: user.avatarUrl } : void 0,
1315
1327
  [user?.email, user?.name, user?.tier, user?.avatarUrl]
1316
1328
  );
1317
1329
  const activePanel = panels.find((p) => p.mode === mode);
1318
- const buildSidebarContent = React5.useCallback(
1330
+ const buildSidebarContent = React6.useCallback(
1319
1331
  (showLabels) => /* @__PURE__ */ jsxs12(Fragment7, { children: [
1320
1332
  /* @__PURE__ */ jsxs12(SidebarRail, { wide: showLabels, children: [
1321
1333
  /* @__PURE__ */ jsx13(SidebarRailHeader, { children: /* @__PURE__ */ jsx13(Link, { href: "/", to: "/", className: "p-1 rounded-md transition-colors hover:bg-muted/50", children: /* @__PURE__ */ jsx13(Logo, { variant, size: "sm", iconOnly: true }) }) }),
@@ -1323,7 +1335,7 @@ function DashboardLayoutInner({
1323
1335
  const isMode = modeSet.has(item.id);
1324
1336
  const prevIsMode = i > 0 && modeSet.has(navItems[i - 1].id);
1325
1337
  const showSep = i > 0 && isMode && !prevIsMode;
1326
- return /* @__PURE__ */ jsxs12(React5.Fragment, { children: [
1338
+ return /* @__PURE__ */ jsxs12(React6.Fragment, { children: [
1327
1339
  showSep && /* @__PURE__ */ jsx13(RailSeparator, {}),
1328
1340
  isMode ? /* @__PURE__ */ jsx13(
1329
1341
  RailModeButton,
@@ -1388,8 +1400,8 @@ function DashboardLayoutInner({
1388
1400
  mode
1389
1401
  ]
1390
1402
  );
1391
- const sidebarContent = React5.useMemo(() => buildSidebarContent(false), [buildSidebarContent]);
1392
- const mobileSidebarContent = React5.useMemo(() => buildSidebarContent(true), [buildSidebarContent]);
1403
+ const sidebarContent = React6.useMemo(() => buildSidebarContent(false), [buildSidebarContent]);
1404
+ const mobileSidebarContent = React6.useMemo(() => buildSidebarContent(true), [buildSidebarContent]);
1393
1405
  return /* @__PURE__ */ jsxs12("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
1394
1406
  /* @__PURE__ */ jsxs12(
1395
1407
  "nav",
@@ -1522,6 +1534,114 @@ function DashboardLayout({ defaultPanelOpen, defaultMode, ...props }) {
1522
1534
  return /* @__PURE__ */ jsx13(SidebarProvider, { defaultPanelOpen, defaultMode, hasPanels: (props.panels?.length ?? 0) > 0, children: /* @__PURE__ */ jsx13(DashboardLayoutInner, { defaultPanelOpen, defaultMode, ...props }) });
1523
1535
  }
1524
1536
 
1537
+ // src/dashboard/sidebar-layout.tsx
1538
+ import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1539
+ var HIDE_BELOW_CLASS = {
1540
+ md: "max-md:hidden",
1541
+ lg: "max-lg:hidden"
1542
+ };
1543
+ function DefaultLink3({
1544
+ href,
1545
+ to,
1546
+ className,
1547
+ children,
1548
+ ...rest
1549
+ }) {
1550
+ return /* @__PURE__ */ jsx14("a", { href: href ?? to, className, ...rest, children });
1551
+ }
1552
+ function SidebarLayoutInner({
1553
+ children,
1554
+ navItems,
1555
+ activeId,
1556
+ panel,
1557
+ logo,
1558
+ logoHref,
1559
+ user,
1560
+ isLoading = false,
1561
+ onLogout,
1562
+ onSettingsClick,
1563
+ settingsHref,
1564
+ profileMenuItems,
1565
+ railFooter,
1566
+ LinkComponent,
1567
+ hideBelow,
1568
+ railLabels = false,
1569
+ closePanelOnNavigate = false,
1570
+ className,
1571
+ sidebarClassName,
1572
+ contentClassName
1573
+ }) {
1574
+ const Link = LinkComponent ?? DefaultLink3;
1575
+ const { panelOpen, togglePanel, setPanelOpen } = useSidebar();
1576
+ const handleNavClick = closePanelOnNavigate && panelOpen ? () => setPanelOpen(false) : void 0;
1577
+ const hasProfile = user !== void 0 || onLogout !== void 0 || onSettingsClick !== void 0;
1578
+ return /* @__PURE__ */ jsxs13("div", { className: cn("min-h-screen bg-background text-foreground", className), children: [
1579
+ /* @__PURE__ */ jsx14("div", { className: cn(hideBelow && HIDE_BELOW_CLASS[hideBelow]), children: /* @__PURE__ */ jsxs13(Sidebar, { className: sidebarClassName, children: [
1580
+ /* @__PURE__ */ jsxs13(SidebarRail, { children: [
1581
+ logo !== void 0 && /* @__PURE__ */ jsx14(SidebarRailHeader, { className: railLabels ? "justify-start px-4" : void 0, children: /* @__PURE__ */ jsx14(
1582
+ Link,
1583
+ {
1584
+ href: logoHref,
1585
+ to: logoHref,
1586
+ className: "flex items-center justify-center rounded-lg p-1 transition-colors hover:bg-muted/50",
1587
+ children: logo
1588
+ }
1589
+ ) }),
1590
+ /* @__PURE__ */ jsx14(SidebarRailNav, { className: railLabels ? "px-2" : void 0, children: navItems.map(
1591
+ (item) => item.togglesPanel ? /* @__PURE__ */ jsx14(
1592
+ RailButton,
1593
+ {
1594
+ icon: item.icon,
1595
+ label: item.label,
1596
+ badge: item.badge,
1597
+ isActive: panelOpen,
1598
+ onClick: togglePanel,
1599
+ showLabel: railLabels
1600
+ },
1601
+ item.id
1602
+ ) : /* @__PURE__ */ jsx14(RailButton, { icon: item.icon, label: item.label, badge: item.badge, isActive: activeId === item.id, showLabel: railLabels, asChild: true, children: /* @__PURE__ */ jsx14(Link, { href: item.href, to: item.href, onClick: handleNavClick }) }, item.id)
1603
+ ) }),
1604
+ (railFooter !== void 0 || hasProfile) && /* @__PURE__ */ jsxs13(SidebarRailFooter, { className: cn("border-t border-border pt-2", railLabels && "items-stretch px-2"), children: [
1605
+ railFooter,
1606
+ hasProfile && /* @__PURE__ */ jsx14(
1607
+ ProfileAvatar,
1608
+ {
1609
+ user: user ?? void 0,
1610
+ isLoading,
1611
+ onLogout,
1612
+ onSettingsClick,
1613
+ settingsHref,
1614
+ showDetails: railLabels,
1615
+ LinkComponent: Link,
1616
+ children: profileMenuItems
1617
+ }
1618
+ )
1619
+ ] })
1620
+ ] }),
1621
+ panel != null && /* @__PURE__ */ jsx14(SidebarPanel, { children: panel })
1622
+ ] }) }),
1623
+ /* @__PURE__ */ jsx14(SidebarContent, { className: contentClassName, children })
1624
+ ] });
1625
+ }
1626
+ function SidebarLayout({
1627
+ panelOpen,
1628
+ onPanelOpenChange,
1629
+ defaultPanelOpen,
1630
+ ...props
1631
+ }) {
1632
+ return /* @__PURE__ */ jsx14(
1633
+ SidebarProvider,
1634
+ {
1635
+ panelOpen,
1636
+ onPanelOpenChange,
1637
+ defaultPanelOpen,
1638
+ hasPanels: props.panel != null,
1639
+ railWidth: props.railLabels ? SIDEBAR_RAIL_LABELED_WIDTH : void 0,
1640
+ children: /* @__PURE__ */ jsx14(SidebarLayoutInner, { ...props })
1641
+ }
1642
+ );
1643
+ }
1644
+
1525
1645
  // src/dashboard/profile-selector.tsx
1526
1646
  import { Check as Check2, ChevronDown, Plus as Plus3, Settings } from "lucide-react";
1527
1647
  import { Button as Button2 } from "@tangle-network/ui/primitives";
@@ -1534,7 +1654,7 @@ import {
1534
1654
  DropdownMenuSeparator as DropdownMenuSeparator4,
1535
1655
  DropdownMenuTrigger as DropdownMenuTrigger4
1536
1656
  } from "@tangle-network/ui/primitives";
1537
- import { Fragment as Fragment8, jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
1657
+ import { Fragment as Fragment8, jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1538
1658
  function ProfileSelector({
1539
1659
  profiles,
1540
1660
  selectedId,
@@ -1549,77 +1669,77 @@ function ProfileSelector({
1549
1669
  const selected = profiles.find((p) => p.id === selectedId);
1550
1670
  const builtinProfiles = profiles.filter((p) => p.is_builtin);
1551
1671
  const customProfiles = profiles.filter((p) => !p.is_builtin);
1552
- return /* @__PURE__ */ jsxs13("div", { className, children: [
1553
- label && /* @__PURE__ */ jsx14("label", { className: "mb-2 block font-medium text-sm", children: label }),
1554
- /* @__PURE__ */ jsxs13(DropdownMenu4, { children: [
1555
- /* @__PURE__ */ jsx14(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs13(Button2, { variant: "outline", className: "w-full justify-between", children: [
1556
- /* @__PURE__ */ jsx14("span", { className: "truncate", children: selected ? selected.name : placeholder }),
1557
- /* @__PURE__ */ jsx14(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
1672
+ return /* @__PURE__ */ jsxs14("div", { className, children: [
1673
+ label && /* @__PURE__ */ jsx15("label", { className: "mb-2 block font-medium text-sm", children: label }),
1674
+ /* @__PURE__ */ jsxs14(DropdownMenu4, { children: [
1675
+ /* @__PURE__ */ jsx15(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsxs14(Button2, { variant: "outline", className: "w-full justify-between", children: [
1676
+ /* @__PURE__ */ jsx15("span", { className: "truncate", children: selected ? selected.name : placeholder }),
1677
+ /* @__PURE__ */ jsx15(ChevronDown, { className: "ml-2 h-4 w-4 shrink-0 opacity-50" })
1558
1678
  ] }) }),
1559
- /* @__PURE__ */ jsxs13(DropdownMenuContent4, { className: "w-[300px]", align: "start", children: [
1560
- /* @__PURE__ */ jsxs13(
1679
+ /* @__PURE__ */ jsxs14(DropdownMenuContent4, { className: "w-[300px]", align: "start", children: [
1680
+ /* @__PURE__ */ jsxs14(
1561
1681
  DropdownMenuItem4,
1562
1682
  {
1563
1683
  onClick: () => onSelect(null),
1564
1684
  className: "flex items-center justify-between",
1565
1685
  children: [
1566
- /* @__PURE__ */ jsx14("span", { children: placeholder }),
1567
- !selectedId && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
1686
+ /* @__PURE__ */ jsx15("span", { children: placeholder }),
1687
+ !selectedId && /* @__PURE__ */ jsx15(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
1568
1688
  ]
1569
1689
  }
1570
1690
  ),
1571
- builtinProfiles.length > 0 && /* @__PURE__ */ jsxs13(Fragment8, { children: [
1572
- /* @__PURE__ */ jsx14(DropdownMenuSeparator4, {}),
1573
- /* @__PURE__ */ jsx14(DropdownMenuLabel2, { children: "Built-in Profiles" }),
1574
- builtinProfiles.map((profile) => /* @__PURE__ */ jsxs13(
1691
+ builtinProfiles.length > 0 && /* @__PURE__ */ jsxs14(Fragment8, { children: [
1692
+ /* @__PURE__ */ jsx15(DropdownMenuSeparator4, {}),
1693
+ /* @__PURE__ */ jsx15(DropdownMenuLabel2, { children: "Built-in Profiles" }),
1694
+ builtinProfiles.map((profile) => /* @__PURE__ */ jsxs14(
1575
1695
  DropdownMenuItem4,
1576
1696
  {
1577
1697
  onClick: () => onSelect(profile),
1578
1698
  className: "flex flex-col items-start gap-1",
1579
1699
  children: [
1580
- /* @__PURE__ */ jsxs13("div", { className: "flex w-full items-center justify-between", children: [
1581
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
1582
- /* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
1583
- profile.extends && /* @__PURE__ */ jsxs13(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
1700
+ /* @__PURE__ */ jsxs14("div", { className: "flex w-full items-center justify-between", children: [
1701
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
1702
+ /* @__PURE__ */ jsx15("span", { className: "font-medium", children: profile.name }),
1703
+ profile.extends && /* @__PURE__ */ jsxs14(Badge, { variant: "secondary", className: "border-0 text-xs", children: [
1584
1704
  "extends ",
1585
1705
  profile.extends
1586
1706
  ] })
1587
1707
  ] }),
1588
- selectedId === profile.id && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
1708
+ selectedId === profile.id && /* @__PURE__ */ jsx15(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
1589
1709
  ] }),
1590
- profile.description && /* @__PURE__ */ jsx14("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
1710
+ profile.description && /* @__PURE__ */ jsx15("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description })
1591
1711
  ]
1592
1712
  },
1593
1713
  profile.id
1594
1714
  ))
1595
1715
  ] }),
1596
- customProfiles.length > 0 && /* @__PURE__ */ jsxs13(Fragment8, { children: [
1597
- /* @__PURE__ */ jsx14(DropdownMenuSeparator4, {}),
1598
- /* @__PURE__ */ jsx14(DropdownMenuLabel2, { children: "Custom Profiles" }),
1599
- customProfiles.map((profile) => /* @__PURE__ */ jsxs13(
1716
+ customProfiles.length > 0 && /* @__PURE__ */ jsxs14(Fragment8, { children: [
1717
+ /* @__PURE__ */ jsx15(DropdownMenuSeparator4, {}),
1718
+ /* @__PURE__ */ jsx15(DropdownMenuLabel2, { children: "Custom Profiles" }),
1719
+ customProfiles.map((profile) => /* @__PURE__ */ jsxs14(
1600
1720
  DropdownMenuItem4,
1601
1721
  {
1602
1722
  onClick: () => onSelect(profile),
1603
1723
  className: "flex flex-col items-start gap-1",
1604
1724
  children: [
1605
- /* @__PURE__ */ jsxs13("div", { className: "flex w-full items-center justify-between", children: [
1606
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
1607
- /* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
1608
- profile.model && /* @__PURE__ */ jsx14(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
1725
+ /* @__PURE__ */ jsxs14("div", { className: "flex w-full items-center justify-between", children: [
1726
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
1727
+ /* @__PURE__ */ jsx15("span", { className: "font-medium", children: profile.name }),
1728
+ profile.model && /* @__PURE__ */ jsx15(Badge, { variant: "secondary", className: "border-0 text-xs", children: profile.model.split("/").pop() })
1609
1729
  ] }),
1610
- selectedId === profile.id && /* @__PURE__ */ jsx14(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
1730
+ selectedId === profile.id && /* @__PURE__ */ jsx15(Check2, { className: "h-4 w-4 text-[var(--surface-success-text)]" })
1611
1731
  ] }),
1612
- profile.description && /* @__PURE__ */ jsx14("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
1613
- showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs13("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
1614
- /* @__PURE__ */ jsxs13("span", { children: [
1732
+ profile.description && /* @__PURE__ */ jsx15("span", { className: "line-clamp-1 text-muted-foreground text-xs", children: profile.description }),
1733
+ showMetrics && profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs14("div", { className: "flex gap-3 text-muted-foreground text-xs", children: [
1734
+ /* @__PURE__ */ jsxs14("span", { children: [
1615
1735
  profile.metrics.total_runs,
1616
1736
  " runs"
1617
1737
  ] }),
1618
- /* @__PURE__ */ jsxs13("span", { children: [
1738
+ /* @__PURE__ */ jsxs14("span", { children: [
1619
1739
  profile.metrics.success_rate.toFixed(0),
1620
1740
  "% success"
1621
1741
  ] }),
1622
- /* @__PURE__ */ jsxs13("span", { children: [
1742
+ /* @__PURE__ */ jsxs14("span", { children: [
1623
1743
  "~",
1624
1744
  (profile.metrics.avg_duration_ms / 1e3).toFixed(1),
1625
1745
  "s avg"
@@ -1630,26 +1750,26 @@ function ProfileSelector({
1630
1750
  profile.id
1631
1751
  ))
1632
1752
  ] }),
1633
- (onCreateClick || onManageClick) && /* @__PURE__ */ jsxs13(Fragment8, { children: [
1634
- /* @__PURE__ */ jsx14(DropdownMenuSeparator4, {}),
1635
- onCreateClick && /* @__PURE__ */ jsxs13(
1753
+ (onCreateClick || onManageClick) && /* @__PURE__ */ jsxs14(Fragment8, { children: [
1754
+ /* @__PURE__ */ jsx15(DropdownMenuSeparator4, {}),
1755
+ onCreateClick && /* @__PURE__ */ jsxs14(
1636
1756
  DropdownMenuItem4,
1637
1757
  {
1638
1758
  onClick: onCreateClick,
1639
1759
  className: "text-[var(--surface-info-text)]",
1640
1760
  children: [
1641
- /* @__PURE__ */ jsx14(Plus3, { className: "mr-2 h-4 w-4" }),
1761
+ /* @__PURE__ */ jsx15(Plus3, { className: "mr-2 h-4 w-4" }),
1642
1762
  "Create New Profile"
1643
1763
  ]
1644
1764
  }
1645
1765
  ),
1646
- onManageClick && /* @__PURE__ */ jsxs13(
1766
+ onManageClick && /* @__PURE__ */ jsxs14(
1647
1767
  DropdownMenuItem4,
1648
1768
  {
1649
1769
  onClick: onManageClick,
1650
1770
  className: "text-muted-foreground",
1651
1771
  children: [
1652
- /* @__PURE__ */ jsx14(Settings, { className: "mr-2 h-4 w-4" }),
1772
+ /* @__PURE__ */ jsx15(Settings, { className: "mr-2 h-4 w-4" }),
1653
1773
  "Manage Profiles"
1654
1774
  ]
1655
1775
  }
@@ -1675,26 +1795,26 @@ function ProfileComparison({
1675
1795
  const fastestProfile = profilesWithMetrics.reduce(
1676
1796
  (best, p) => (p.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) < (best.metrics?.avg_duration_ms ?? Number.POSITIVE_INFINITY) ? p : best
1677
1797
  );
1678
- return /* @__PURE__ */ jsxs13("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
1679
- /* @__PURE__ */ jsx14("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
1680
- /* @__PURE__ */ jsx14("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
1798
+ return /* @__PURE__ */ jsxs14("div", { className: `rounded-lg border border-border p-4 ${className ?? ""}`, children: [
1799
+ /* @__PURE__ */ jsx15("h4", { className: "mb-3 font-medium text-sm", children: "Profile Performance" }),
1800
+ /* @__PURE__ */ jsx15("div", { className: "space-y-3", children: profilesWithMetrics.map((profile) => {
1681
1801
  const isBestSuccess = profile.id === bestSuccess.id;
1682
1802
  const isFastest = profile.id === fastestProfile.id;
1683
- return /* @__PURE__ */ jsxs13(
1803
+ return /* @__PURE__ */ jsxs14(
1684
1804
  "div",
1685
1805
  {
1686
1806
  className: "flex items-center justify-between gap-4",
1687
1807
  children: [
1688
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-2", children: [
1689
- /* @__PURE__ */ jsx14("span", { className: "font-medium", children: profile.name }),
1690
- isBestSuccess && /* @__PURE__ */ jsx14(Badge, { className: "border border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] text-xs", children: "Best Success" }),
1691
- isFastest && !isBestSuccess && /* @__PURE__ */ jsx14(Badge, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Fastest" })
1808
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-2", children: [
1809
+ /* @__PURE__ */ jsx15("span", { className: "font-medium", children: profile.name }),
1810
+ isBestSuccess && /* @__PURE__ */ jsx15(Badge, { className: "border border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)] text-xs", children: "Best Success" }),
1811
+ isFastest && !isBestSuccess && /* @__PURE__ */ jsx15(Badge, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Fastest" })
1692
1812
  ] }),
1693
- /* @__PURE__ */ jsxs13("div", { className: "flex items-center gap-4 text-sm", children: [
1694
- /* @__PURE__ */ jsxs13("span", { children: [
1695
- /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: "Success:" }),
1813
+ /* @__PURE__ */ jsxs14("div", { className: "flex items-center gap-4 text-sm", children: [
1814
+ /* @__PURE__ */ jsxs14("span", { children: [
1815
+ /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: "Success:" }),
1696
1816
  " ",
1697
- /* @__PURE__ */ jsxs13(
1817
+ /* @__PURE__ */ jsxs14(
1698
1818
  "span",
1699
1819
  {
1700
1820
  className: (profile.metrics?.success_rate ?? 0) >= 80 ? "text-[var(--surface-success-text)]" : (profile.metrics?.success_rate ?? 0) >= 50 ? "text-[var(--surface-warning-text)]" : "text-[var(--surface-danger-text)]",
@@ -1705,13 +1825,13 @@ function ProfileComparison({
1705
1825
  }
1706
1826
  )
1707
1827
  ] }),
1708
- /* @__PURE__ */ jsxs13("span", { children: [
1709
- /* @__PURE__ */ jsx14("span", { className: "text-muted-foreground", children: "Avg:" }),
1828
+ /* @__PURE__ */ jsxs14("span", { children: [
1829
+ /* @__PURE__ */ jsx15("span", { className: "text-muted-foreground", children: "Avg:" }),
1710
1830
  " ",
1711
1831
  ((profile.metrics?.avg_duration_ms ?? 0) / 1e3).toFixed(1),
1712
1832
  "s"
1713
1833
  ] }),
1714
- /* @__PURE__ */ jsxs13("span", { className: "text-muted-foreground", children: [
1834
+ /* @__PURE__ */ jsxs14("span", { className: "text-muted-foreground", children: [
1715
1835
  profile.metrics?.total_runs,
1716
1836
  " runs"
1717
1837
  ] })
@@ -1725,8 +1845,8 @@ function ProfileComparison({
1725
1845
  }
1726
1846
 
1727
1847
  // src/dashboard/metric-area-chart.tsx
1728
- import * as React6 from "react";
1729
- import { jsx as jsx15, jsxs as jsxs14 } from "react/jsx-runtime";
1848
+ import * as React7 from "react";
1849
+ import { jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1730
1850
  var TONE_VARS = {
1731
1851
  primary: "var(--brand-primary, hsl(var(--primary)))",
1732
1852
  success: "var(--status-running, #22c55e)",
@@ -1772,7 +1892,7 @@ function MetricAreaChart({
1772
1892
  emptyState,
1773
1893
  className
1774
1894
  }) {
1775
- const gradientId = React6.useId();
1895
+ const gradientId = React7.useId();
1776
1896
  const width = 400;
1777
1897
  const values = points.map((p) => p.value).filter((v) => v !== null);
1778
1898
  const latest = values.length > 0 ? values[values.length - 1] : null;
@@ -1780,7 +1900,7 @@ function MetricAreaChart({
1780
1900
  const yMax = maxValue ?? (observedMax > 0 ? observedMax * 1.1 : 1);
1781
1901
  const segments = buildSegments(points, width, height, yMax);
1782
1902
  const color = TONE_VARS[tone];
1783
- return /* @__PURE__ */ jsxs14(
1903
+ return /* @__PURE__ */ jsxs15(
1784
1904
  "div",
1785
1905
  {
1786
1906
  className: cn(
@@ -1789,21 +1909,21 @@ function MetricAreaChart({
1789
1909
  ),
1790
1910
  "data-testid": `metric-chart-${label.toLowerCase().replace(/\s+/g, "-")}`,
1791
1911
  children: [
1792
- /* @__PURE__ */ jsxs14("div", { className: "flex items-baseline justify-between gap-3", children: [
1793
- /* @__PURE__ */ jsx15("p", { className: "font-medium text-muted-foreground text-xs uppercase tracking-[0.12em]", children: label }),
1794
- /* @__PURE__ */ jsxs14("div", { className: "text-right", children: [
1795
- /* @__PURE__ */ jsx15("span", { className: "font-semibold text-foreground text-xl tabular-nums tracking-tight", children: latest === null ? "\u2014" : formatValue(latest) }),
1796
- detail && /* @__PURE__ */ jsx15("span", { className: "ml-1.5 text-muted-foreground text-xs", children: detail })
1912
+ /* @__PURE__ */ jsxs15("div", { className: "flex items-baseline justify-between gap-3", children: [
1913
+ /* @__PURE__ */ jsx16("p", { className: "font-medium text-muted-foreground text-xs uppercase tracking-[0.12em]", children: label }),
1914
+ /* @__PURE__ */ jsxs15("div", { className: "text-right", children: [
1915
+ /* @__PURE__ */ jsx16("span", { className: "font-semibold text-foreground text-xl tabular-nums tracking-tight", children: latest === null ? "\u2014" : formatValue(latest) }),
1916
+ detail && /* @__PURE__ */ jsx16("span", { className: "ml-1.5 text-muted-foreground text-xs", children: detail })
1797
1917
  ] })
1798
1918
  ] }),
1799
- /* @__PURE__ */ jsx15("div", { className: "mt-3", children: values.length === 0 ? /* @__PURE__ */ jsx15(
1919
+ /* @__PURE__ */ jsx16("div", { className: "mt-3", children: values.length === 0 ? /* @__PURE__ */ jsx16(
1800
1920
  "div",
1801
1921
  {
1802
1922
  className: "flex items-center justify-center text-muted-foreground text-xs",
1803
1923
  style: { height },
1804
1924
  children: emptyState ?? "Waiting for samples\u2026"
1805
1925
  }
1806
- ) : /* @__PURE__ */ jsxs14(
1926
+ ) : /* @__PURE__ */ jsxs15(
1807
1927
  "svg",
1808
1928
  {
1809
1929
  viewBox: `0 0 ${width} ${height}`,
@@ -1813,7 +1933,7 @@ function MetricAreaChart({
1813
1933
  role: "img",
1814
1934
  "aria-label": `${label} chart`,
1815
1935
  children: [
1816
- [0.25, 0.5, 0.75].map((fraction) => /* @__PURE__ */ jsx15(
1936
+ [0.25, 0.5, 0.75].map((fraction) => /* @__PURE__ */ jsx16(
1817
1937
  "line",
1818
1938
  {
1819
1939
  x1: 0,
@@ -1828,13 +1948,13 @@ function MetricAreaChart({
1828
1948
  },
1829
1949
  fraction
1830
1950
  )),
1831
- /* @__PURE__ */ jsx15("defs", { children: /* @__PURE__ */ jsxs14("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
1832
- /* @__PURE__ */ jsx15("stop", { offset: "0%", stopColor: color, stopOpacity: 0.28 }),
1833
- /* @__PURE__ */ jsx15("stop", { offset: "100%", stopColor: color, stopOpacity: 0.02 })
1951
+ /* @__PURE__ */ jsx16("defs", { children: /* @__PURE__ */ jsxs15("linearGradient", { id: gradientId, x1: "0", y1: "0", x2: "0", y2: "1", children: [
1952
+ /* @__PURE__ */ jsx16("stop", { offset: "0%", stopColor: color, stopOpacity: 0.28 }),
1953
+ /* @__PURE__ */ jsx16("stop", { offset: "100%", stopColor: color, stopOpacity: 0.02 })
1834
1954
  ] }) }),
1835
- segments.map((segment) => /* @__PURE__ */ jsxs14(React6.Fragment, { children: [
1836
- /* @__PURE__ */ jsx15("path", { d: segment.area, fill: `url(#${gradientId})` }),
1837
- /* @__PURE__ */ jsx15(
1955
+ segments.map((segment) => /* @__PURE__ */ jsxs15(React7.Fragment, { children: [
1956
+ /* @__PURE__ */ jsx16("path", { d: segment.area, fill: `url(#${gradientId})` }),
1957
+ /* @__PURE__ */ jsx16(
1838
1958
  "path",
1839
1959
  {
1840
1960
  d: segment.path,
@@ -1850,9 +1970,9 @@ function MetricAreaChart({
1850
1970
  ]
1851
1971
  }
1852
1972
  ) }),
1853
- /* @__PURE__ */ jsxs14("div", { className: "mt-1.5 flex justify-between text-[10px] text-muted-foreground tabular-nums", children: [
1854
- /* @__PURE__ */ jsx15("span", { children: values.length > 0 ? formatValue(0) : "" }),
1855
- /* @__PURE__ */ jsx15("span", { children: values.length > 0 ? formatValue(yMax) : "" })
1973
+ /* @__PURE__ */ jsxs15("div", { className: "mt-1.5 flex justify-between text-[10px] text-muted-foreground tabular-nums", children: [
1974
+ /* @__PURE__ */ jsx16("span", { children: values.length > 0 ? formatValue(0) : "" }),
1975
+ /* @__PURE__ */ jsx16("span", { children: values.length > 0 ? formatValue(yMax) : "" })
1856
1976
  ] })
1857
1977
  ]
1858
1978
  }
@@ -1872,7 +1992,7 @@ import {
1872
1992
  } from "lucide-react";
1873
1993
  import { Button as Button3 } from "@tangle-network/ui/primitives";
1874
1994
  import { Badge as Badge2 } from "@tangle-network/ui/primitives";
1875
- import { Fragment as Fragment10, jsx as jsx16, jsxs as jsxs15 } from "react/jsx-runtime";
1995
+ import { Fragment as Fragment10, jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
1876
1996
  var statusConfig = {
1877
1997
  pending: {
1878
1998
  icon: Clock3,
@@ -1956,19 +2076,19 @@ function VariantList({
1956
2076
  isActioning,
1957
2077
  className
1958
2078
  }) {
1959
- return /* @__PURE__ */ jsx16("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
2079
+ return /* @__PURE__ */ jsx17("div", { className: `space-y-2 ${className || ""}`, children: variants.map((variant) => {
1960
2080
  const status = statusConfig[variant.status];
1961
2081
  const StatusIcon = status.icon;
1962
2082
  const isSelected = variant.id === selectedId;
1963
- return /* @__PURE__ */ jsxs15(
2083
+ return /* @__PURE__ */ jsxs16(
1964
2084
  "div",
1965
2085
  {
1966
2086
  className: `cursor-pointer rounded-lg border px-3 py-2.5 transition-colors ${isSelected ? "border-primary/30 bg-[var(--accent-surface-soft)]" : "border-border bg-card hover:border-primary/20 hover:bg-muted/50"}`,
1967
2087
  onClick: () => onSelect?.(variant.id),
1968
2088
  children: [
1969
- /* @__PURE__ */ jsxs15("div", { className: "flex items-center gap-2", children: [
1970
- /* @__PURE__ */ jsxs15(Badge2, { className: `shrink-0 ${status.bg} ${status.border} ${status.color}`, children: [
1971
- /* @__PURE__ */ jsx16(
2089
+ /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
2090
+ /* @__PURE__ */ jsxs16(Badge2, { className: `shrink-0 ${status.bg} ${status.border} ${status.color}`, children: [
2091
+ /* @__PURE__ */ jsx17(
1972
2092
  StatusIcon,
1973
2093
  {
1974
2094
  className: `mr-1 h-3 w-3 ${status.animate ? "animate-spin" : ""}`
@@ -1976,27 +2096,27 @@ function VariantList({
1976
2096
  ),
1977
2097
  status.label
1978
2098
  ] }),
1979
- /* @__PURE__ */ jsx16("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
1980
- variant.sublabel && /* @__PURE__ */ jsxs15("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
2099
+ /* @__PURE__ */ jsx17("span", { className: "truncate text-sm font-medium text-foreground", children: variant.label }),
2100
+ variant.sublabel && /* @__PURE__ */ jsxs16("span", { className: "shrink-0 text-xs text-muted-foreground", children: [
1981
2101
  "(",
1982
2102
  variant.sublabel,
1983
2103
  ")"
1984
2104
  ] }),
1985
- variant.durationMs && /* @__PURE__ */ jsxs15("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
1986
- /* @__PURE__ */ jsx16(Timer, { className: "h-3 w-3" }),
2105
+ variant.durationMs && /* @__PURE__ */ jsxs16("span", { className: "flex shrink-0 items-center gap-1 text-xs text-muted-foreground", children: [
2106
+ /* @__PURE__ */ jsx17(Timer, { className: "h-3 w-3" }),
1987
2107
  (variant.durationMs / 1e3).toFixed(1),
1988
2108
  "s"
1989
2109
  ] }),
1990
- /* @__PURE__ */ jsxs15("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
1991
- variant.outcome && /* @__PURE__ */ jsx16(
2110
+ /* @__PURE__ */ jsxs16("div", { className: "ml-auto flex shrink-0 items-center gap-1.5", children: [
2111
+ variant.outcome && /* @__PURE__ */ jsx17(
1992
2112
  Badge2,
1993
2113
  {
1994
2114
  className: `${outcomeConfig[variant.outcome].bg} ${outcomeConfig[variant.outcome].border} ${outcomeConfig[variant.outcome].color}`,
1995
2115
  children: outcomeConfig[variant.outcome].label
1996
2116
  }
1997
2117
  ),
1998
- variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs15(Fragment10, { children: [
1999
- /* @__PURE__ */ jsxs15(
2118
+ variant.status === "completed" && variant.outcome === "pending_review" && onAccept && onReject && /* @__PURE__ */ jsxs16(Fragment10, { children: [
2119
+ /* @__PURE__ */ jsxs16(
2000
2120
  Button3,
2001
2121
  {
2002
2122
  variant: "outline",
@@ -2008,12 +2128,12 @@ function VariantList({
2008
2128
  },
2009
2129
  disabled: isActioning === variant.id,
2010
2130
  children: [
2011
- /* @__PURE__ */ jsx16(Check3, { className: "mr-1 h-3 w-3" }),
2131
+ /* @__PURE__ */ jsx17(Check3, { className: "mr-1 h-3 w-3" }),
2012
2132
  "Accept"
2013
2133
  ]
2014
2134
  }
2015
2135
  ),
2016
- /* @__PURE__ */ jsxs15(
2136
+ /* @__PURE__ */ jsxs16(
2017
2137
  Button3,
2018
2138
  {
2019
2139
  variant: "outline",
@@ -2025,13 +2145,13 @@ function VariantList({
2025
2145
  },
2026
2146
  disabled: isActioning === variant.id,
2027
2147
  children: [
2028
- /* @__PURE__ */ jsx16(X, { className: "mr-1 h-3 w-3" }),
2148
+ /* @__PURE__ */ jsx17(X, { className: "mr-1 h-3 w-3" }),
2029
2149
  "Reject"
2030
2150
  ]
2031
2151
  }
2032
2152
  )
2033
2153
  ] }),
2034
- variant.detailsUrl && /* @__PURE__ */ jsx16(
2154
+ variant.detailsUrl && /* @__PURE__ */ jsx17(
2035
2155
  Button3,
2036
2156
  {
2037
2157
  variant: "ghost",
@@ -2041,13 +2161,13 @@ function VariantList({
2041
2161
  e.stopPropagation();
2042
2162
  window.open(variant.detailsUrl, "_blank");
2043
2163
  },
2044
- children: /* @__PURE__ */ jsx16(ExternalLink2, { className: "h-3.5 w-3.5" })
2164
+ children: /* @__PURE__ */ jsx17(ExternalLink2, { className: "h-3.5 w-3.5" })
2045
2165
  }
2046
2166
  )
2047
2167
  ] })
2048
2168
  ] }),
2049
- variant.error && /* @__PURE__ */ jsx16("p", { className: "mt-1.5 text-xs text-[var(--surface-danger-text)]", children: variant.error }),
2050
- variant.summary && /* @__PURE__ */ jsx16("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
2169
+ variant.error && /* @__PURE__ */ jsx17("p", { className: "mt-1.5 text-xs text-[var(--surface-danger-text)]", children: variant.error }),
2170
+ variant.summary && /* @__PURE__ */ jsx17("p", { className: "mt-1.5 line-clamp-2 text-xs text-muted-foreground", children: variant.summary })
2051
2171
  ]
2052
2172
  },
2053
2173
  variant.id
@@ -2058,7 +2178,7 @@ function VariantList({
2058
2178
  // src/dashboard/system-logs.tsx
2059
2179
  import { Terminal as Terminal3 } from "lucide-react";
2060
2180
  import { useEffect as useEffect2, useRef as useRef2, useState as useState4 } from "react";
2061
- import { jsx as jsx17, jsxs as jsxs16 } from "react/jsx-runtime";
2181
+ import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2062
2182
  function SystemLogsViewer({ apiUrl, token, className }) {
2063
2183
  const [logs, setLogs] = useState4([]);
2064
2184
  const [error, setError] = useState4(null);
@@ -2111,18 +2231,18 @@ function SystemLogsViewer({ apiUrl, token, className }) {
2111
2231
  const isAtBottom = scrollHeight - scrollTop - clientHeight < 20;
2112
2232
  setIsFollowing((prev) => prev === isAtBottom ? prev : isAtBottom);
2113
2233
  };
2114
- return /* @__PURE__ */ jsxs16("div", { className: cn("flex flex-col h-full bg-background text-foreground font-mono text-sm leading-relaxed overflow-hidden rounded-lg border border-border", className), children: [
2115
- /* @__PURE__ */ jsxs16("div", { className: "flex-none flex items-center justify-between border-b border-border bg-muted/50 backdrop-blur-md px-4 py-2", children: [
2116
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-2", children: [
2117
- /* @__PURE__ */ jsx17(Terminal3, { className: "h-4 w-4 text-primary animate-pulse" }),
2118
- /* @__PURE__ */ jsx17("span", { className: "font-bold text-xs uppercase tracking-widest text-muted-foreground", children: "System Traces" })
2234
+ return /* @__PURE__ */ jsxs17("div", { className: cn("flex flex-col h-full bg-background text-foreground font-mono text-sm leading-relaxed overflow-hidden rounded-lg border border-border", className), children: [
2235
+ /* @__PURE__ */ jsxs17("div", { className: "flex-none flex items-center justify-between border-b border-border bg-muted/50 backdrop-blur-md px-4 py-2", children: [
2236
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-2", children: [
2237
+ /* @__PURE__ */ jsx18(Terminal3, { className: "h-4 w-4 text-primary animate-pulse" }),
2238
+ /* @__PURE__ */ jsx18("span", { className: "font-bold text-xs uppercase tracking-widest text-muted-foreground", children: "System Traces" })
2119
2239
  ] }),
2120
- /* @__PURE__ */ jsxs16("div", { className: "flex items-center gap-3", children: [
2121
- error && /* @__PURE__ */ jsxs16("span", { className: "text-destructive text-xs flex items-center gap-1", children: [
2122
- /* @__PURE__ */ jsx17("span", { className: "w-2 h-2 rounded-full bg-destructive animate-ping" }),
2240
+ /* @__PURE__ */ jsxs17("div", { className: "flex items-center gap-3", children: [
2241
+ error && /* @__PURE__ */ jsxs17("span", { className: "text-destructive text-xs flex items-center gap-1", children: [
2242
+ /* @__PURE__ */ jsx18("span", { className: "w-2 h-2 rounded-full bg-destructive animate-ping" }),
2123
2243
  " Error fetching logs"
2124
2244
  ] }),
2125
- /* @__PURE__ */ jsx17(
2245
+ /* @__PURE__ */ jsx18(
2126
2246
  "button",
2127
2247
  {
2128
2248
  onClick: () => {
@@ -2137,29 +2257,29 @@ function SystemLogsViewer({ apiUrl, token, className }) {
2137
2257
  )
2138
2258
  ] })
2139
2259
  ] }),
2140
- /* @__PURE__ */ jsx17(
2260
+ /* @__PURE__ */ jsx18(
2141
2261
  "div",
2142
2262
  {
2143
2263
  ref: scrollRef,
2144
2264
  onScroll: handleScroll,
2145
2265
  className: "flex-1 overflow-y-auto p-4 space-y-1",
2146
- children: logs.length === 0 && !error ? /* @__PURE__ */ jsx17("div", { className: "flex h-full items-center justify-center text-muted-foreground italic", children: "Waiting for orchestrator logs..." }) : logs.map((log, i) => /* @__PURE__ */ jsxs16("div", { className: "break-words", children: [
2147
- /* @__PURE__ */ jsxs16("span", { className: "text-muted-foreground mr-3 select-none", children: [
2266
+ children: logs.length === 0 && !error ? /* @__PURE__ */ jsx18("div", { className: "flex h-full items-center justify-center text-muted-foreground italic", children: "Waiting for orchestrator logs..." }) : logs.map((log, i) => /* @__PURE__ */ jsxs17("div", { className: "break-words", children: [
2267
+ /* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground mr-3 select-none", children: [
2148
2268
  "[",
2149
2269
  log.timestamp || i.toString().padStart(4, "0"),
2150
2270
  "]"
2151
2271
  ] }),
2152
- /* @__PURE__ */ jsxs16("span", { className: "text-primary/70 mr-2", children: [
2272
+ /* @__PURE__ */ jsxs17("span", { className: "text-primary/70 mr-2", children: [
2153
2273
  "[",
2154
2274
  log.level,
2155
2275
  "]"
2156
2276
  ] }),
2157
- /* @__PURE__ */ jsxs16("span", { className: "text-muted-foreground mr-2", children: [
2277
+ /* @__PURE__ */ jsxs17("span", { className: "text-muted-foreground mr-2", children: [
2158
2278
  "[",
2159
2279
  log.scope,
2160
2280
  "]"
2161
2281
  ] }),
2162
- /* @__PURE__ */ jsx17("span", { className: log.level.toUpperCase() === "ERROR" || log.message.toLowerCase().includes("failed") ? "text-destructive" : log.level.toUpperCase() === "WARN" ? "text-warning" : "text-foreground", children: log.message })
2282
+ /* @__PURE__ */ jsx18("span", { className: log.level.toUpperCase() === "ERROR" || log.message.toLowerCase().includes("failed") ? "text-destructive" : log.level.toUpperCase() === "WARN" ? "text-warning" : "text-foreground", children: log.message })
2163
2283
  ] }, `${log.timestamp}-${log.scope}-${i}`))
2164
2284
  }
2165
2285
  )
@@ -2170,50 +2290,50 @@ function SystemLogsViewer({ apiUrl, token, className }) {
2170
2290
  import { Clock as Clock4, Layers, MessageSquare, DollarSign } from "lucide-react";
2171
2291
  import { StatCard } from "@tangle-network/ui/primitives";
2172
2292
  import { Skeleton as Skeleton4 } from "@tangle-network/ui/primitives";
2173
- import { jsx as jsx18, jsxs as jsxs17 } from "react/jsx-runtime";
2293
+ import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2174
2294
  function UsageSummary({ data, loading = false, className }) {
2175
2295
  if (loading || !data) {
2176
- return /* @__PURE__ */ jsx18("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx18(Skeleton4, { className: "h-28 rounded-xl" }, i)) });
2296
+ return /* @__PURE__ */ jsx19("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: Array.from({ length: 4 }).map((_, i) => /* @__PURE__ */ jsx19(Skeleton4, { className: "h-28 rounded-xl" }, i)) });
2177
2297
  }
2178
- return /* @__PURE__ */ jsxs17("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: [
2179
- /* @__PURE__ */ jsx18(
2298
+ return /* @__PURE__ */ jsxs18("div", { className: cn("grid grid-cols-2 gap-4 lg:grid-cols-4", className), children: [
2299
+ /* @__PURE__ */ jsx19(
2180
2300
  StatCard,
2181
2301
  {
2182
2302
  variant: "sandbox",
2183
2303
  title: "Compute Hours",
2184
2304
  value: data.computeHours.toFixed(1),
2185
2305
  subtitle: "This billing period",
2186
- icon: /* @__PURE__ */ jsx18(Clock4, { className: "h-5 w-5" })
2306
+ icon: /* @__PURE__ */ jsx19(Clock4, { className: "h-5 w-5" })
2187
2307
  }
2188
2308
  ),
2189
- /* @__PURE__ */ jsx18(
2309
+ /* @__PURE__ */ jsx19(
2190
2310
  StatCard,
2191
2311
  {
2192
2312
  variant: "sandbox",
2193
2313
  title: "Active Sessions",
2194
2314
  value: data.activeSessions,
2195
2315
  subtitle: "Currently running",
2196
- icon: /* @__PURE__ */ jsx18(Layers, { className: "h-5 w-5" })
2316
+ icon: /* @__PURE__ */ jsx19(Layers, { className: "h-5 w-5" })
2197
2317
  }
2198
2318
  ),
2199
- /* @__PURE__ */ jsx18(
2319
+ /* @__PURE__ */ jsx19(
2200
2320
  StatCard,
2201
2321
  {
2202
2322
  variant: "sandbox",
2203
2323
  title: "Messages Sent",
2204
2324
  value: data.messagesSent.toLocaleString(),
2205
2325
  subtitle: "Agent interactions",
2206
- icon: /* @__PURE__ */ jsx18(MessageSquare, { className: "h-5 w-5" })
2326
+ icon: /* @__PURE__ */ jsx19(MessageSquare, { className: "h-5 w-5" })
2207
2327
  }
2208
2328
  ),
2209
- /* @__PURE__ */ jsx18(
2329
+ /* @__PURE__ */ jsx19(
2210
2330
  StatCard,
2211
2331
  {
2212
2332
  variant: "sandbox",
2213
2333
  title: "Estimated Cost",
2214
2334
  value: `$${data.estimatedCost.toFixed(2)}`,
2215
2335
  subtitle: "This billing period",
2216
- icon: /* @__PURE__ */ jsx18(DollarSign, { className: "h-5 w-5" })
2336
+ icon: /* @__PURE__ */ jsx19(DollarSign, { className: "h-5 w-5" })
2217
2337
  }
2218
2338
  )
2219
2339
  ] });
@@ -2221,66 +2341,66 @@ function UsageSummary({ data, loading = false, className }) {
2221
2341
 
2222
2342
  // src/dashboard/git-panel.tsx
2223
2343
  import { GitBranch, GitCommit, FileEdit, FilePlus, File } from "lucide-react";
2224
- import { jsx as jsx19, jsxs as jsxs18 } from "react/jsx-runtime";
2344
+ import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
2225
2345
  function GitPanel({ status, log, loading = false, onRefresh, className }) {
2226
2346
  if (loading) {
2227
- return /* @__PURE__ */ jsx19("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
2228
- /* @__PURE__ */ jsx19("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
2347
+ return /* @__PURE__ */ jsx20("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
2348
+ /* @__PURE__ */ jsx20("div", { className: "h-4 w-4 animate-spin rounded-full border-2 border-primary border-t-transparent" }),
2229
2349
  "Loading git info..."
2230
2350
  ] }) });
2231
2351
  }
2232
2352
  if (!status) {
2233
- return /* @__PURE__ */ jsx19("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
2234
- /* @__PURE__ */ jsx19(GitBranch, { className: "h-4 w-4" }),
2353
+ return /* @__PURE__ */ jsx20("div", { className: cn("rounded-lg border border-border bg-card p-5", className), children: /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-sm text-muted-foreground", children: [
2354
+ /* @__PURE__ */ jsx20(GitBranch, { className: "h-4 w-4" }),
2235
2355
  "No git repository detected"
2236
2356
  ] }) });
2237
2357
  }
2238
2358
  const changedCount = status.staged.length + status.modified.length + status.untracked.length;
2239
- return /* @__PURE__ */ jsxs18("div", { className: cn("rounded-lg border border-border bg-card overflow-hidden", className), children: [
2240
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-4 py-3", children: [
2241
- /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2", children: [
2242
- /* @__PURE__ */ jsx19(GitBranch, { className: "h-4 w-4 text-primary" }),
2243
- /* @__PURE__ */ jsx19("span", { className: "text-sm font-bold text-foreground", children: status.branch }),
2244
- status.isDirty && /* @__PURE__ */ jsxs18("span", { className: "rounded-full bg-[var(--surface-warning-bg)] px-1.5 py-0.5 text-[10px] font-bold text-[var(--surface-warning-text)]", children: [
2359
+ return /* @__PURE__ */ jsxs19("div", { className: cn("rounded-lg border border-border bg-card overflow-hidden", className), children: [
2360
+ /* @__PURE__ */ jsxs19("div", { className: "flex items-center justify-between border-b border-border bg-muted/30 px-4 py-3", children: [
2361
+ /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2", children: [
2362
+ /* @__PURE__ */ jsx20(GitBranch, { className: "h-4 w-4 text-primary" }),
2363
+ /* @__PURE__ */ jsx20("span", { className: "text-sm font-bold text-foreground", children: status.branch }),
2364
+ status.isDirty && /* @__PURE__ */ jsxs19("span", { className: "rounded-full bg-[var(--surface-warning-bg)] px-1.5 py-0.5 text-[10px] font-bold text-[var(--surface-warning-text)]", children: [
2245
2365
  changedCount,
2246
2366
  " change",
2247
2367
  changedCount !== 1 ? "s" : ""
2248
2368
  ] })
2249
2369
  ] }),
2250
- onRefresh && /* @__PURE__ */ jsx19("button", { type: "button", onClick: onRefresh, className: "text-xs text-muted-foreground hover:text-foreground transition-colors", children: "Refresh" })
2370
+ onRefresh && /* @__PURE__ */ jsx20("button", { type: "button", onClick: onRefresh, className: "text-xs text-muted-foreground hover:text-foreground transition-colors", children: "Refresh" })
2251
2371
  ] }),
2252
- changedCount > 0 && /* @__PURE__ */ jsx19("div", { className: "border-b border-border px-4 py-3", children: /* @__PURE__ */ jsxs18("div", { className: "space-y-1.5", children: [
2253
- status.staged.map((f) => /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-xs", children: [
2254
- /* @__PURE__ */ jsx19(FilePlus, { className: "h-3 w-3 text-[var(--surface-success-text)]" }),
2255
- /* @__PURE__ */ jsx19("span", { className: "font-mono text-foreground truncate", children: f }),
2256
- /* @__PURE__ */ jsx19("span", { className: "text-[var(--surface-success-text)] text-[10px] font-bold ml-auto", children: "STAGED" })
2372
+ changedCount > 0 && /* @__PURE__ */ jsx20("div", { className: "border-b border-border px-4 py-3", children: /* @__PURE__ */ jsxs19("div", { className: "space-y-1.5", children: [
2373
+ status.staged.map((f) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-xs", children: [
2374
+ /* @__PURE__ */ jsx20(FilePlus, { className: "h-3 w-3 text-[var(--surface-success-text)]" }),
2375
+ /* @__PURE__ */ jsx20("span", { className: "font-mono text-foreground truncate", children: f }),
2376
+ /* @__PURE__ */ jsx20("span", { className: "text-[var(--surface-success-text)] text-[10px] font-bold ml-auto", children: "STAGED" })
2257
2377
  ] }, `s-${f}`)),
2258
- status.modified.map((f) => /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-xs", children: [
2259
- /* @__PURE__ */ jsx19(FileEdit, { className: "h-3 w-3 text-[var(--surface-warning-text)]" }),
2260
- /* @__PURE__ */ jsx19("span", { className: "font-mono text-foreground truncate", children: f })
2378
+ status.modified.map((f) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-xs", children: [
2379
+ /* @__PURE__ */ jsx20(FileEdit, { className: "h-3 w-3 text-[var(--surface-warning-text)]" }),
2380
+ /* @__PURE__ */ jsx20("span", { className: "font-mono text-foreground truncate", children: f })
2261
2381
  ] }, `m-${f}`)),
2262
- status.untracked.map((f) => /* @__PURE__ */ jsxs18("div", { className: "flex items-center gap-2 text-xs", children: [
2263
- /* @__PURE__ */ jsx19(File, { className: "h-3 w-3 text-muted-foreground" }),
2264
- /* @__PURE__ */ jsx19("span", { className: "font-mono text-muted-foreground truncate", children: f })
2382
+ status.untracked.map((f) => /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-2 text-xs", children: [
2383
+ /* @__PURE__ */ jsx20(File, { className: "h-3 w-3 text-muted-foreground" }),
2384
+ /* @__PURE__ */ jsx20("span", { className: "font-mono text-muted-foreground truncate", children: f })
2265
2385
  ] }, `u-${f}`))
2266
2386
  ] }) }),
2267
- log.length > 0 && /* @__PURE__ */ jsxs18("div", { className: "px-4 py-3", children: [
2268
- /* @__PURE__ */ jsx19("div", { className: "mb-2 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Recent Commits" }),
2269
- /* @__PURE__ */ jsx19("div", { className: "space-y-2", children: log.slice(0, 5).map((commit) => /* @__PURE__ */ jsxs18("div", { className: "flex items-start gap-2 text-xs", children: [
2270
- /* @__PURE__ */ jsx19(GitCommit, { className: "h-3 w-3 text-muted-foreground mt-0.5 shrink-0" }),
2271
- /* @__PURE__ */ jsxs18("div", { className: "min-w-0", children: [
2272
- /* @__PURE__ */ jsx19("span", { className: "font-mono text-primary mr-1.5", children: commit.shortSha }),
2273
- /* @__PURE__ */ jsx19("span", { className: "text-foreground", children: commit.message })
2387
+ log.length > 0 && /* @__PURE__ */ jsxs19("div", { className: "px-4 py-3", children: [
2388
+ /* @__PURE__ */ jsx20("div", { className: "mb-2 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Recent Commits" }),
2389
+ /* @__PURE__ */ jsx20("div", { className: "space-y-2", children: log.slice(0, 5).map((commit) => /* @__PURE__ */ jsxs19("div", { className: "flex items-start gap-2 text-xs", children: [
2390
+ /* @__PURE__ */ jsx20(GitCommit, { className: "h-3 w-3 text-muted-foreground mt-0.5 shrink-0" }),
2391
+ /* @__PURE__ */ jsxs19("div", { className: "min-w-0", children: [
2392
+ /* @__PURE__ */ jsx20("span", { className: "font-mono text-primary mr-1.5", children: commit.shortSha }),
2393
+ /* @__PURE__ */ jsx20("span", { className: "text-foreground", children: commit.message })
2274
2394
  ] })
2275
2395
  ] }, commit.shortSha)) })
2276
2396
  ] }),
2277
- (status.ahead > 0 || status.behind > 0) && /* @__PURE__ */ jsxs18("div", { className: "border-t border-border px-4 py-2 flex items-center gap-3 text-xs text-muted-foreground", children: [
2278
- status.ahead > 0 && /* @__PURE__ */ jsxs18("span", { children: [
2397
+ (status.ahead > 0 || status.behind > 0) && /* @__PURE__ */ jsxs19("div", { className: "border-t border-border px-4 py-2 flex items-center gap-3 text-xs text-muted-foreground", children: [
2398
+ status.ahead > 0 && /* @__PURE__ */ jsxs19("span", { children: [
2279
2399
  "\u2191 ",
2280
2400
  status.ahead,
2281
2401
  " ahead"
2282
2402
  ] }),
2283
- status.behind > 0 && /* @__PURE__ */ jsxs18("span", { children: [
2403
+ status.behind > 0 && /* @__PURE__ */ jsxs19("span", { children: [
2284
2404
  "\u2193 ",
2285
2405
  status.behind,
2286
2406
  " behind"
@@ -2290,14 +2410,14 @@ function GitPanel({ status, log, loading = false, onRefresh, className }) {
2290
2410
  }
2291
2411
 
2292
2412
  // src/dashboard/ports-list.tsx
2293
- import * as React8 from "react";
2413
+ import * as React9 from "react";
2294
2414
  import { Copy as Copy3, Check as Check4, Globe, Plus as Plus4, Trash2 as Trash23 } from "lucide-react";
2295
- import { jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
2415
+ import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
2296
2416
  function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, className }) {
2297
- const [newPort, setNewPort] = React8.useState("");
2298
- const [copiedPort, setCopiedPort] = React8.useState(null);
2299
- const copyTimerRef = React8.useRef(null);
2300
- React8.useEffect(() => {
2417
+ const [newPort, setNewPort] = React9.useState("");
2418
+ const [copiedPort, setCopiedPort] = React9.useState(null);
2419
+ const copyTimerRef = React9.useRef(null);
2420
+ React9.useEffect(() => {
2301
2421
  return () => {
2302
2422
  if (copyTimerRef.current) clearTimeout(copyTimerRef.current);
2303
2423
  };
@@ -2319,48 +2439,48 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
2319
2439
  setNewPort("");
2320
2440
  }
2321
2441
  };
2322
- return /* @__PURE__ */ jsxs19("div", { className: cn("space-y-4", className), children: [
2323
- ports.length > 0 ? /* @__PURE__ */ jsx20("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs19("table", { className: "w-full text-sm", children: [
2324
- /* @__PURE__ */ jsx20("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs19("tr", { children: [
2325
- /* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Port" }),
2326
- /* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Public URL" }),
2327
- /* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
2328
- /* @__PURE__ */ jsx20("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
2442
+ return /* @__PURE__ */ jsxs20("div", { className: cn("space-y-4", className), children: [
2443
+ ports.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs20("table", { className: "w-full text-sm", children: [
2444
+ /* @__PURE__ */ jsx21("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs20("tr", { children: [
2445
+ /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Port" }),
2446
+ /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Public URL" }),
2447
+ /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
2448
+ /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
2329
2449
  ] }) }),
2330
- /* @__PURE__ */ jsx20("tbody", { className: "divide-y divide-border", children: ports.map((p) => /* @__PURE__ */ jsxs19("tr", { children: [
2331
- /* @__PURE__ */ jsx20("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.port }),
2332
- /* @__PURE__ */ jsx20("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs19(
2450
+ /* @__PURE__ */ jsx21("tbody", { className: "divide-y divide-border", children: ports.map((p) => /* @__PURE__ */ jsxs20("tr", { children: [
2451
+ /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.port }),
2452
+ /* @__PURE__ */ jsx21("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsxs20(
2333
2453
  "button",
2334
2454
  {
2335
2455
  type: "button",
2336
2456
  onClick: () => handleCopy(p.url, p.port),
2337
2457
  className: "flex items-center gap-2 font-mono text-xs text-primary hover:underline cursor-pointer group",
2338
2458
  children: [
2339
- /* @__PURE__ */ jsx20("span", { className: "truncate max-w-[300px]", children: p.url }),
2340
- copiedPort === p.port ? /* @__PURE__ */ jsx20(Check4, { className: "h-3 w-3 text-[var(--surface-success-text)] shrink-0" }) : /* @__PURE__ */ jsx20(Copy3, { className: "h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0" })
2459
+ /* @__PURE__ */ jsx21("span", { className: "truncate max-w-[300px]", children: p.url }),
2460
+ copiedPort === p.port ? /* @__PURE__ */ jsx21(Check4, { className: "h-3 w-3 text-[var(--surface-success-text)] shrink-0" }) : /* @__PURE__ */ jsx21(Copy3, { className: "h-3 w-3 opacity-0 group-hover:opacity-100 transition-opacity shrink-0" })
2341
2461
  ]
2342
2462
  }
2343
2463
  ) }),
2344
- /* @__PURE__ */ jsx20("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx20("span", { className: cn(
2464
+ /* @__PURE__ */ jsx21("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx21("span", { className: cn(
2345
2465
  "inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
2346
2466
  p.status === "active" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]"
2347
2467
  ), children: p.status }) }),
2348
- /* @__PURE__ */ jsx20("td", { className: "px-4 py-3 text-right", children: onRemovePort && /* @__PURE__ */ jsx20(
2468
+ /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 text-right", children: onRemovePort && /* @__PURE__ */ jsx21(
2349
2469
  "button",
2350
2470
  {
2351
2471
  type: "button",
2352
2472
  onClick: () => onRemovePort(p.port),
2353
2473
  className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
2354
- children: /* @__PURE__ */ jsx20(Trash23, { className: "h-3.5 w-3.5" })
2474
+ children: /* @__PURE__ */ jsx21(Trash23, { className: "h-3.5 w-3.5" })
2355
2475
  }
2356
2476
  ) })
2357
2477
  ] }, p.port)) })
2358
- ] }) }) : /* @__PURE__ */ jsxs19("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2359
- /* @__PURE__ */ jsx20(Globe, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
2360
- /* @__PURE__ */ jsx20("p", { className: "text-sm text-muted-foreground", children: "No ports exposed yet" })
2478
+ ] }) }) : /* @__PURE__ */ jsxs20("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2479
+ /* @__PURE__ */ jsx21(Globe, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
2480
+ /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "No ports exposed yet" })
2361
2481
  ] }),
2362
- /* @__PURE__ */ jsxs19("div", { className: "flex items-center gap-3", children: [
2363
- /* @__PURE__ */ jsx20(
2482
+ /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-3", children: [
2483
+ /* @__PURE__ */ jsx21(
2364
2484
  "input",
2365
2485
  {
2366
2486
  type: "number",
@@ -2373,7 +2493,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
2373
2493
  className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2374
2494
  }
2375
2495
  ),
2376
- /* @__PURE__ */ jsxs19(
2496
+ /* @__PURE__ */ jsxs20(
2377
2497
  "button",
2378
2498
  {
2379
2499
  type: "button",
@@ -2381,7 +2501,7 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
2381
2501
  disabled: !newPort || isExposing,
2382
2502
  className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
2383
2503
  children: [
2384
- /* @__PURE__ */ jsx20(Plus4, { className: "h-4 w-4" }),
2504
+ /* @__PURE__ */ jsx21(Plus4, { className: "h-4 w-4" }),
2385
2505
  "Expose"
2386
2506
  ]
2387
2507
  }
@@ -2391,9 +2511,9 @@ function PortsList({ ports, onExposePort, onRemovePort, isExposing = false, clas
2391
2511
  }
2392
2512
 
2393
2513
  // src/dashboard/process-list.tsx
2394
- import * as React9 from "react";
2514
+ import * as React10 from "react";
2395
2515
  import { Activity as Activity3, Plus as Plus5, Skull, Terminal as Terminal4 } from "lucide-react";
2396
- import { jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
2516
+ import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
2397
2517
  function formatUptime(startedAt) {
2398
2518
  if (!startedAt) return "-";
2399
2519
  const ms = Date.now() - new Date(startedAt).getTime();
@@ -2403,7 +2523,7 @@ function formatUptime(startedAt) {
2403
2523
  return `${Math.floor(ms / 36e5)}h ${Math.floor(ms % 36e5 / 6e4)}m`;
2404
2524
  }
2405
2525
  function ProcessList({ processes, onSpawn, onKill, loading = false, className }) {
2406
- const [newCommand, setNewCommand] = React9.useState("");
2526
+ const [newCommand, setNewCommand] = React10.useState("");
2407
2527
  const handleSpawn = () => {
2408
2528
  const cmd = newCommand.trim();
2409
2529
  if (cmd) {
@@ -2411,43 +2531,43 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
2411
2531
  setNewCommand("");
2412
2532
  }
2413
2533
  };
2414
- return /* @__PURE__ */ jsxs20("div", { className: cn("space-y-4", className), children: [
2415
- loading ? /* @__PURE__ */ jsxs20("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2416
- /* @__PURE__ */ jsx21(Activity3, { className: "mx-auto h-6 w-6 text-muted-foreground animate-spin mb-2" }),
2417
- /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "Loading processes..." })
2418
- ] }) : processes.length > 0 ? /* @__PURE__ */ jsx21("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs20("table", { className: "w-full text-sm", children: [
2419
- /* @__PURE__ */ jsx21("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs20("tr", { children: [
2420
- /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "PID" }),
2421
- /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Command" }),
2422
- /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
2423
- /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Uptime" }),
2424
- /* @__PURE__ */ jsx21("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
2534
+ return /* @__PURE__ */ jsxs21("div", { className: cn("space-y-4", className), children: [
2535
+ loading ? /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2536
+ /* @__PURE__ */ jsx22(Activity3, { className: "mx-auto h-6 w-6 text-muted-foreground animate-spin mb-2" }),
2537
+ /* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Loading processes..." })
2538
+ ] }) : processes.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs21("table", { className: "w-full text-sm", children: [
2539
+ /* @__PURE__ */ jsx22("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs21("tr", { children: [
2540
+ /* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "PID" }),
2541
+ /* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Command" }),
2542
+ /* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Status" }),
2543
+ /* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Uptime" }),
2544
+ /* @__PURE__ */ jsx22("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-20" })
2425
2545
  ] }) }),
2426
- /* @__PURE__ */ jsx21("tbody", { className: "divide-y divide-border", children: processes.map((p) => /* @__PURE__ */ jsxs20("tr", { children: [
2427
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.pid }),
2428
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 font-mono text-xs text-foreground truncate max-w-[250px]", children: p.command }),
2429
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx21("span", { className: cn(
2546
+ /* @__PURE__ */ jsx22("tbody", { className: "divide-y divide-border", children: processes.map((p) => /* @__PURE__ */ jsxs21("tr", { children: [
2547
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: p.pid }),
2548
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 font-mono text-xs text-foreground truncate max-w-[250px]", children: p.command }),
2549
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3", children: /* @__PURE__ */ jsx22("span", { className: cn(
2430
2550
  "inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
2431
2551
  p.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-muted text-muted-foreground"
2432
2552
  ), children: p.running ? "running" : `exited (${p.exitCode ?? "?"})` }) }),
2433
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 font-mono text-xs text-muted-foreground", children: formatUptime(p.startedAt) }),
2434
- /* @__PURE__ */ jsx21("td", { className: "px-4 py-3 text-right", children: p.running && /* @__PURE__ */ jsx21(
2553
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 font-mono text-xs text-muted-foreground", children: formatUptime(p.startedAt) }),
2554
+ /* @__PURE__ */ jsx22("td", { className: "px-4 py-3 text-right", children: p.running && /* @__PURE__ */ jsx22(
2435
2555
  "button",
2436
2556
  {
2437
2557
  type: "button",
2438
2558
  onClick: () => onKill(p.pid),
2439
2559
  className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
2440
2560
  title: "Kill process",
2441
- children: /* @__PURE__ */ jsx21(Skull, { className: "h-3.5 w-3.5" })
2561
+ children: /* @__PURE__ */ jsx22(Skull, { className: "h-3.5 w-3.5" })
2442
2562
  }
2443
2563
  ) })
2444
2564
  ] }, `${p.pid}-${p.startedAt ?? p.command}`)) })
2445
- ] }) }) : /* @__PURE__ */ jsxs20("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2446
- /* @__PURE__ */ jsx21(Terminal4, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
2447
- /* @__PURE__ */ jsx21("p", { className: "text-sm text-muted-foreground", children: "No processes running" })
2565
+ ] }) }) : /* @__PURE__ */ jsxs21("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2566
+ /* @__PURE__ */ jsx22(Terminal4, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
2567
+ /* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "No processes running" })
2448
2568
  ] }),
2449
- /* @__PURE__ */ jsxs20("div", { className: "flex items-center gap-3", children: [
2450
- /* @__PURE__ */ jsx21(
2569
+ /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3", children: [
2570
+ /* @__PURE__ */ jsx22(
2451
2571
  "input",
2452
2572
  {
2453
2573
  type: "text",
@@ -2458,7 +2578,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
2458
2578
  className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2459
2579
  }
2460
2580
  ),
2461
- /* @__PURE__ */ jsxs20(
2581
+ /* @__PURE__ */ jsxs21(
2462
2582
  "button",
2463
2583
  {
2464
2584
  type: "button",
@@ -2466,7 +2586,7 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
2466
2586
  disabled: !newCommand.trim(),
2467
2587
  className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
2468
2588
  children: [
2469
- /* @__PURE__ */ jsx21(Plus5, { className: "h-4 w-4" }),
2589
+ /* @__PURE__ */ jsx22(Plus5, { className: "h-4 w-4" }),
2470
2590
  "Spawn"
2471
2591
  ]
2472
2592
  }
@@ -2476,11 +2596,11 @@ function ProcessList({ processes, onSpawn, onKill, loading = false, className })
2476
2596
  }
2477
2597
 
2478
2598
  // src/dashboard/network-config.tsx
2479
- import * as React10 from "react";
2599
+ import * as React11 from "react";
2480
2600
  import { Network as Network2, Plus as Plus6, Trash2 as Trash24, ShieldAlert } from "lucide-react";
2481
- import { jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
2601
+ import { jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
2482
2602
  function NetworkConfig({ config, onUpdate, loading = false, className }) {
2483
- const [newCidr, setNewCidr] = React10.useState("");
2603
+ const [newCidr, setNewCidr] = React11.useState("");
2484
2604
  const isValidCidr = (value) => {
2485
2605
  const match = value.match(/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})\/(\d{1,2})$/);
2486
2606
  if (!match) return false;
@@ -2501,21 +2621,21 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
2501
2621
  }
2502
2622
  };
2503
2623
  if (loading || !config) {
2504
- return /* @__PURE__ */ jsxs21("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
2505
- /* @__PURE__ */ jsx22(Network2, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
2506
- /* @__PURE__ */ jsx22("p", { className: "text-sm text-muted-foreground", children: "Loading network configuration..." })
2624
+ return /* @__PURE__ */ jsxs22("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
2625
+ /* @__PURE__ */ jsx23(Network2, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
2626
+ /* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Loading network configuration..." })
2507
2627
  ] });
2508
2628
  }
2509
- return /* @__PURE__ */ jsxs21("div", { className: cn("space-y-4", className), children: [
2510
- /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between rounded-lg border border-border bg-card px-4 py-3", children: [
2511
- /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3", children: [
2512
- /* @__PURE__ */ jsx22(ShieldAlert, { className: "h-4 w-4 text-muted-foreground" }),
2513
- /* @__PURE__ */ jsxs21("div", { children: [
2514
- /* @__PURE__ */ jsx22("p", { className: "text-sm font-medium text-foreground", children: "Block Outbound Traffic" }),
2515
- /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground", children: "Prevent the sandbox from making external network requests" })
2629
+ return /* @__PURE__ */ jsxs22("div", { className: cn("space-y-4", className), children: [
2630
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between rounded-lg border border-border bg-card px-4 py-3", children: [
2631
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
2632
+ /* @__PURE__ */ jsx23(ShieldAlert, { className: "h-4 w-4 text-muted-foreground" }),
2633
+ /* @__PURE__ */ jsxs22("div", { children: [
2634
+ /* @__PURE__ */ jsx23("p", { className: "text-sm font-medium text-foreground", children: "Block Outbound Traffic" }),
2635
+ /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "Prevent the sandbox from making external network requests" })
2516
2636
  ] })
2517
2637
  ] }),
2518
- /* @__PURE__ */ jsx22(
2638
+ /* @__PURE__ */ jsx23(
2519
2639
  "button",
2520
2640
  {
2521
2641
  type: "button",
@@ -2527,7 +2647,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
2527
2647
  "relative inline-flex h-6 w-11 items-center rounded-full transition-colors",
2528
2648
  config.blockOutbound ? "bg-destructive" : "bg-muted"
2529
2649
  ),
2530
- children: /* @__PURE__ */ jsx22(
2650
+ children: /* @__PURE__ */ jsx23(
2531
2651
  "span",
2532
2652
  {
2533
2653
  className: cn(
@@ -2539,22 +2659,22 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
2539
2659
  }
2540
2660
  )
2541
2661
  ] }),
2542
- /* @__PURE__ */ jsxs21("div", { children: [
2543
- /* @__PURE__ */ jsx22("h4", { className: "text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wider", children: "Allowlist (CIDR)" }),
2544
- config.allowList.length > 0 ? /* @__PURE__ */ jsx22("div", { className: "space-y-1.5 mb-3", children: config.allowList.map((cidr) => /* @__PURE__ */ jsxs21("div", { className: "flex items-center justify-between rounded border border-border bg-muted/20 px-3 py-2", children: [
2545
- /* @__PURE__ */ jsx22("span", { className: "font-mono text-xs text-foreground", children: cidr }),
2546
- /* @__PURE__ */ jsx22(
2662
+ /* @__PURE__ */ jsxs22("div", { children: [
2663
+ /* @__PURE__ */ jsx23("h4", { className: "text-xs font-medium text-muted-foreground mb-2 uppercase tracking-wider", children: "Allowlist (CIDR)" }),
2664
+ config.allowList.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "space-y-1.5 mb-3", children: config.allowList.map((cidr) => /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between rounded border border-border bg-muted/20 px-3 py-2", children: [
2665
+ /* @__PURE__ */ jsx23("span", { className: "font-mono text-xs text-foreground", children: cidr }),
2666
+ /* @__PURE__ */ jsx23(
2547
2667
  "button",
2548
2668
  {
2549
2669
  type: "button",
2550
2670
  onClick: () => handleRemoveCidr(cidr),
2551
2671
  className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
2552
- children: /* @__PURE__ */ jsx22(Trash24, { className: "h-3 w-3" })
2672
+ children: /* @__PURE__ */ jsx23(Trash24, { className: "h-3 w-3" })
2553
2673
  }
2554
2674
  )
2555
- ] }, cidr)) }) : /* @__PURE__ */ jsx22("p", { className: "text-xs text-muted-foreground mb-3", children: "No CIDR rules configured. All traffic is allowed." }),
2556
- /* @__PURE__ */ jsxs21("div", { className: "flex items-center gap-3", children: [
2557
- /* @__PURE__ */ jsx22(
2675
+ ] }, cidr)) }) : /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground mb-3", children: "No CIDR rules configured. All traffic is allowed." }),
2676
+ /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3", children: [
2677
+ /* @__PURE__ */ jsx23(
2558
2678
  "input",
2559
2679
  {
2560
2680
  type: "text",
@@ -2565,7 +2685,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
2565
2685
  className: "flex-1 rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2566
2686
  }
2567
2687
  ),
2568
- /* @__PURE__ */ jsxs21(
2688
+ /* @__PURE__ */ jsxs22(
2569
2689
  "button",
2570
2690
  {
2571
2691
  type: "button",
@@ -2573,7 +2693,7 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
2573
2693
  disabled: !newCidr.trim(),
2574
2694
  className: "inline-flex items-center gap-2 rounded-lg bg-primary/20 border border-primary/30 px-4 py-2 text-sm font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors disabled:opacity-50",
2575
2695
  children: [
2576
- /* @__PURE__ */ jsx22(Plus6, { className: "h-4 w-4" }),
2696
+ /* @__PURE__ */ jsx23(Plus6, { className: "h-4 w-4" }),
2577
2697
  "Add"
2578
2698
  ]
2579
2699
  }
@@ -2584,9 +2704,9 @@ function NetworkConfig({ config, onUpdate, loading = false, className }) {
2584
2704
  }
2585
2705
 
2586
2706
  // src/dashboard/backend-config.tsx
2587
- import * as React11 from "react";
2707
+ import * as React12 from "react";
2588
2708
  import { Bot, Plus as Plus7, RefreshCw as RefreshCw2, Trash2 as Trash25, Server, Wrench } from "lucide-react";
2589
- import { Fragment as Fragment11, jsx as jsx23, jsxs as jsxs22 } from "react/jsx-runtime";
2709
+ import { Fragment as Fragment11, jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
2590
2710
  function BackendConfig({
2591
2711
  status,
2592
2712
  mcpServers,
@@ -2596,10 +2716,10 @@ function BackendConfig({
2596
2716
  loading = false,
2597
2717
  className
2598
2718
  }) {
2599
- const [showAddMcp, setShowAddMcp] = React11.useState(false);
2600
- const [mcpName, setMcpName] = React11.useState("");
2601
- const [mcpCommand, setMcpCommand] = React11.useState("");
2602
- const [mcpArgs, setMcpArgs] = React11.useState("");
2719
+ const [showAddMcp, setShowAddMcp] = React12.useState(false);
2720
+ const [mcpName, setMcpName] = React12.useState("");
2721
+ const [mcpCommand, setMcpCommand] = React12.useState("");
2722
+ const [mcpArgs, setMcpArgs] = React12.useState("");
2603
2723
  const handleAddMcp = () => {
2604
2724
  const name = mcpName.trim();
2605
2725
  const command = mcpCommand.trim();
@@ -2616,91 +2736,91 @@ function BackendConfig({
2616
2736
  }
2617
2737
  };
2618
2738
  if (loading || !status) {
2619
- return /* @__PURE__ */ jsxs22("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
2620
- /* @__PURE__ */ jsx23(Bot, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
2621
- /* @__PURE__ */ jsx23("p", { className: "text-sm text-muted-foreground", children: "Loading backend status..." })
2739
+ return /* @__PURE__ */ jsxs23("div", { className: cn("rounded-lg border border-border bg-muted/20 p-6 text-center", className), children: [
2740
+ /* @__PURE__ */ jsx24(Bot, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
2741
+ /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "Loading backend status..." })
2622
2742
  ] });
2623
2743
  }
2624
- return /* @__PURE__ */ jsxs22("div", { className: cn("space-y-4", className), children: [
2625
- /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
2626
- /* @__PURE__ */ jsxs22("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
2627
- /* @__PURE__ */ jsx23("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Agent Status" }),
2628
- /* @__PURE__ */ jsxs22(
2744
+ return /* @__PURE__ */ jsxs23("div", { className: cn("space-y-4", className), children: [
2745
+ /* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
2746
+ /* @__PURE__ */ jsxs23("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
2747
+ /* @__PURE__ */ jsx24("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider", children: "Agent Status" }),
2748
+ /* @__PURE__ */ jsxs23(
2629
2749
  "button",
2630
2750
  {
2631
2751
  type: "button",
2632
2752
  onClick: onRestart,
2633
2753
  className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
2634
2754
  children: [
2635
- /* @__PURE__ */ jsx23(RefreshCw2, { className: "h-3 w-3" }),
2755
+ /* @__PURE__ */ jsx24(RefreshCw2, { className: "h-3 w-3" }),
2636
2756
  "Restart"
2637
2757
  ]
2638
2758
  }
2639
2759
  )
2640
2760
  ] }),
2641
- /* @__PURE__ */ jsx23("div", { className: "p-4", children: /* @__PURE__ */ jsxs22("dl", { className: "grid grid-cols-[100px_1fr] gap-y-3 text-sm", children: [
2642
- /* @__PURE__ */ jsx23("dt", { className: "text-muted-foreground", children: "Status" }),
2643
- /* @__PURE__ */ jsx23("dd", { children: /* @__PURE__ */ jsx23("span", { className: cn(
2761
+ /* @__PURE__ */ jsx24("div", { className: "p-4", children: /* @__PURE__ */ jsxs23("dl", { className: "grid grid-cols-[100px_1fr] gap-y-3 text-sm", children: [
2762
+ /* @__PURE__ */ jsx24("dt", { className: "text-muted-foreground", children: "Status" }),
2763
+ /* @__PURE__ */ jsx24("dd", { children: /* @__PURE__ */ jsx24("span", { className: cn(
2644
2764
  "inline-flex items-center gap-1.5 rounded-full px-2 py-0.5 text-[10px] font-bold uppercase tracking-wider",
2645
2765
  status.running ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : "bg-destructive/10 text-destructive"
2646
2766
  ), children: status.running ? "Running" : "Stopped" }) }),
2647
- /* @__PURE__ */ jsx23("dt", { className: "text-muted-foreground", children: "Model" }),
2648
- /* @__PURE__ */ jsx23("dd", { className: "font-mono text-xs", children: status.model ?? "Default" }),
2649
- status.provider && /* @__PURE__ */ jsxs22(Fragment11, { children: [
2650
- /* @__PURE__ */ jsx23("dt", { className: "text-muted-foreground", children: "Provider" }),
2651
- /* @__PURE__ */ jsx23("dd", { className: "font-mono text-xs", children: status.provider })
2767
+ /* @__PURE__ */ jsx24("dt", { className: "text-muted-foreground", children: "Model" }),
2768
+ /* @__PURE__ */ jsx24("dd", { className: "font-mono text-xs", children: status.model ?? "Default" }),
2769
+ status.provider && /* @__PURE__ */ jsxs23(Fragment11, { children: [
2770
+ /* @__PURE__ */ jsx24("dt", { className: "text-muted-foreground", children: "Provider" }),
2771
+ /* @__PURE__ */ jsx24("dd", { className: "font-mono text-xs", children: status.provider })
2652
2772
  ] })
2653
2773
  ] }) })
2654
2774
  ] }),
2655
- /* @__PURE__ */ jsxs22("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
2656
- /* @__PURE__ */ jsxs22("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
2657
- /* @__PURE__ */ jsxs22("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
2658
- /* @__PURE__ */ jsx23(Wrench, { className: "h-3.5 w-3.5" }),
2775
+ /* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-border bg-card overflow-hidden", children: [
2776
+ /* @__PURE__ */ jsxs23("div", { className: "px-4 py-3 border-b border-border bg-muted/30 flex items-center justify-between", children: [
2777
+ /* @__PURE__ */ jsxs23("h4", { className: "text-xs font-medium text-muted-foreground uppercase tracking-wider flex items-center gap-2", children: [
2778
+ /* @__PURE__ */ jsx24(Wrench, { className: "h-3.5 w-3.5" }),
2659
2779
  "MCP Servers"
2660
2780
  ] }),
2661
- /* @__PURE__ */ jsxs22(
2781
+ /* @__PURE__ */ jsxs23(
2662
2782
  "button",
2663
2783
  {
2664
2784
  type: "button",
2665
2785
  onClick: () => setShowAddMcp(!showAddMcp),
2666
2786
  className: "inline-flex items-center gap-1.5 rounded-md bg-primary/20 border border-primary/30 px-2.5 py-1 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
2667
2787
  children: [
2668
- /* @__PURE__ */ jsx23(Plus7, { className: "h-3 w-3" }),
2788
+ /* @__PURE__ */ jsx24(Plus7, { className: "h-3 w-3" }),
2669
2789
  "Add"
2670
2790
  ]
2671
2791
  }
2672
2792
  )
2673
2793
  ] }),
2674
- mcpServers.length > 0 ? /* @__PURE__ */ jsx23("div", { className: "divide-y divide-border", children: mcpServers.map((s) => /* @__PURE__ */ jsxs22("div", { className: "flex items-center justify-between px-4 py-3", children: [
2675
- /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-3 min-w-0", children: [
2676
- /* @__PURE__ */ jsx23(Server, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
2677
- /* @__PURE__ */ jsxs22("div", { className: "min-w-0", children: [
2678
- /* @__PURE__ */ jsx23("p", { className: "text-sm font-medium text-foreground truncate", children: s.name }),
2679
- /* @__PURE__ */ jsxs22("p", { className: "text-xs font-mono text-muted-foreground truncate", children: [
2794
+ mcpServers.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "divide-y divide-border", children: mcpServers.map((s) => /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between px-4 py-3", children: [
2795
+ /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-3 min-w-0", children: [
2796
+ /* @__PURE__ */ jsx24(Server, { className: "h-3.5 w-3.5 text-muted-foreground shrink-0" }),
2797
+ /* @__PURE__ */ jsxs23("div", { className: "min-w-0", children: [
2798
+ /* @__PURE__ */ jsx24("p", { className: "text-sm font-medium text-foreground truncate", children: s.name }),
2799
+ /* @__PURE__ */ jsxs23("p", { className: "text-xs font-mono text-muted-foreground truncate", children: [
2680
2800
  s.command,
2681
2801
  " ",
2682
2802
  s.args?.join(" ") ?? ""
2683
2803
  ] })
2684
2804
  ] })
2685
2805
  ] }),
2686
- /* @__PURE__ */ jsxs22("div", { className: "flex items-center gap-2 shrink-0", children: [
2687
- s.status && /* @__PURE__ */ jsx23("span", { className: cn(
2806
+ /* @__PURE__ */ jsxs23("div", { className: "flex items-center gap-2 shrink-0", children: [
2807
+ s.status && /* @__PURE__ */ jsx24("span", { className: cn(
2688
2808
  "inline-flex items-center rounded-full px-1.5 py-0.5 text-[9px] font-bold uppercase",
2689
2809
  s.status === "running" ? "bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]" : s.status === "error" ? "bg-destructive/10 text-destructive" : "bg-muted text-muted-foreground"
2690
2810
  ), children: s.status }),
2691
- /* @__PURE__ */ jsx23(
2811
+ /* @__PURE__ */ jsx24(
2692
2812
  "button",
2693
2813
  {
2694
2814
  type: "button",
2695
2815
  onClick: () => onRemoveMcp(s.name),
2696
2816
  className: "p-1 text-muted-foreground hover:text-destructive transition-colors rounded",
2697
- children: /* @__PURE__ */ jsx23(Trash25, { className: "h-3.5 w-3.5" })
2817
+ children: /* @__PURE__ */ jsx24(Trash25, { className: "h-3.5 w-3.5" })
2698
2818
  }
2699
2819
  )
2700
2820
  ] })
2701
- ] }, s.name)) }) : /* @__PURE__ */ jsx23("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx23("p", { className: "text-xs text-muted-foreground", children: "No MCP servers configured" }) }),
2702
- showAddMcp && /* @__PURE__ */ jsxs22("div", { className: "p-4 border-t border-border bg-muted/10 space-y-2", children: [
2703
- /* @__PURE__ */ jsx23(
2821
+ ] }, s.name)) }) : /* @__PURE__ */ jsx24("div", { className: "p-4 text-center", children: /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground", children: "No MCP servers configured" }) }),
2822
+ showAddMcp && /* @__PURE__ */ jsxs23("div", { className: "p-4 border-t border-border bg-muted/10 space-y-2", children: [
2823
+ /* @__PURE__ */ jsx24(
2704
2824
  "input",
2705
2825
  {
2706
2826
  type: "text",
@@ -2710,7 +2830,7 @@ function BackendConfig({
2710
2830
  className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2711
2831
  }
2712
2832
  ),
2713
- /* @__PURE__ */ jsx23(
2833
+ /* @__PURE__ */ jsx24(
2714
2834
  "input",
2715
2835
  {
2716
2836
  type: "text",
@@ -2720,7 +2840,7 @@ function BackendConfig({
2720
2840
  className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2721
2841
  }
2722
2842
  ),
2723
- /* @__PURE__ */ jsx23(
2843
+ /* @__PURE__ */ jsx24(
2724
2844
  "input",
2725
2845
  {
2726
2846
  type: "text",
@@ -2730,8 +2850,8 @@ function BackendConfig({
2730
2850
  className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2731
2851
  }
2732
2852
  ),
2733
- /* @__PURE__ */ jsxs22("div", { className: "flex justify-end gap-2 pt-1", children: [
2734
- /* @__PURE__ */ jsx23(
2853
+ /* @__PURE__ */ jsxs23("div", { className: "flex justify-end gap-2 pt-1", children: [
2854
+ /* @__PURE__ */ jsx24(
2735
2855
  "button",
2736
2856
  {
2737
2857
  type: "button",
@@ -2740,7 +2860,7 @@ function BackendConfig({
2740
2860
  children: "Cancel"
2741
2861
  }
2742
2862
  ),
2743
- /* @__PURE__ */ jsx23(
2863
+ /* @__PURE__ */ jsx24(
2744
2864
  "button",
2745
2865
  {
2746
2866
  type: "button",
@@ -2757,9 +2877,9 @@ function BackendConfig({
2757
2877
  }
2758
2878
 
2759
2879
  // src/dashboard/snapshot-list.tsx
2760
- import * as React12 from "react";
2880
+ import * as React13 from "react";
2761
2881
  import { Camera, Clock as Clock5, HardDrive, Plus as Plus8, RotateCcw } from "lucide-react";
2762
- import { jsx as jsx24, jsxs as jsxs23 } from "react/jsx-runtime";
2882
+ import { jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
2763
2883
  function formatBytes(bytes) {
2764
2884
  if (bytes == null || bytes < 0) return "-";
2765
2885
  if (bytes === 0) return "0 B";
@@ -2774,33 +2894,33 @@ function formatDate(dateStr) {
2774
2894
  return d.toLocaleDateString(void 0, { month: "short", day: "numeric", hour: "2-digit", minute: "2-digit" });
2775
2895
  }
2776
2896
  function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loading = false, className }) {
2777
- const [showCreate, setShowCreate] = React12.useState(false);
2778
- const [tags, setTags] = React12.useState("");
2897
+ const [showCreate, setShowCreate] = React13.useState(false);
2898
+ const [tags, setTags] = React13.useState("");
2779
2899
  const handleCreate = () => {
2780
2900
  const tagList = tags.trim() ? tags.trim().split(",").map((t) => t.trim()).filter(Boolean) : void 0;
2781
2901
  onCreate(tagList);
2782
2902
  setTags("");
2783
2903
  setShowCreate(false);
2784
2904
  };
2785
- return /* @__PURE__ */ jsxs23("div", { className: cn("space-y-4", className), children: [
2786
- /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-between", children: [
2787
- /* @__PURE__ */ jsx24("h3", { className: "text-sm font-bold text-foreground", children: "Snapshots" }),
2788
- /* @__PURE__ */ jsxs23(
2905
+ return /* @__PURE__ */ jsxs24("div", { className: cn("space-y-4", className), children: [
2906
+ /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-between", children: [
2907
+ /* @__PURE__ */ jsx25("h3", { className: "text-sm font-bold text-foreground", children: "Snapshots" }),
2908
+ /* @__PURE__ */ jsxs24(
2789
2909
  "button",
2790
2910
  {
2791
2911
  type: "button",
2792
2912
  onClick: () => setShowCreate(!showCreate),
2793
2913
  className: "inline-flex items-center gap-1.5 rounded-lg bg-primary/20 border border-primary/30 px-3 py-1.5 text-xs font-medium text-primary hover:bg-primary hover:text-primary-foreground transition-colors",
2794
2914
  children: [
2795
- /* @__PURE__ */ jsx24(Plus8, { className: "h-3.5 w-3.5" }),
2915
+ /* @__PURE__ */ jsx25(Plus8, { className: "h-3.5 w-3.5" }),
2796
2916
  "Create Snapshot"
2797
2917
  ]
2798
2918
  }
2799
2919
  )
2800
2920
  ] }),
2801
- showCreate && /* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-primary/20 bg-primary/5 p-4 space-y-3", children: [
2802
- /* @__PURE__ */ jsx24("p", { className: "text-sm text-foreground font-medium", children: "Create a new snapshot of the current sandbox state." }),
2803
- /* @__PURE__ */ jsx24(
2921
+ showCreate && /* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-primary/20 bg-primary/5 p-4 space-y-3", children: [
2922
+ /* @__PURE__ */ jsx25("p", { className: "text-sm text-foreground font-medium", children: "Create a new snapshot of the current sandbox state." }),
2923
+ /* @__PURE__ */ jsx25(
2804
2924
  "input",
2805
2925
  {
2806
2926
  type: "text",
@@ -2811,8 +2931,8 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
2811
2931
  className: "w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2812
2932
  }
2813
2933
  ),
2814
- /* @__PURE__ */ jsxs23("div", { className: "flex justify-end gap-2", children: [
2815
- /* @__PURE__ */ jsx24(
2934
+ /* @__PURE__ */ jsxs24("div", { className: "flex justify-end gap-2", children: [
2935
+ /* @__PURE__ */ jsx25(
2816
2936
  "button",
2817
2937
  {
2818
2938
  type: "button",
@@ -2821,44 +2941,44 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
2821
2941
  children: "Cancel"
2822
2942
  }
2823
2943
  ),
2824
- /* @__PURE__ */ jsxs23(
2944
+ /* @__PURE__ */ jsxs24(
2825
2945
  "button",
2826
2946
  {
2827
2947
  type: "button",
2828
2948
  onClick: handleCreate,
2829
2949
  className: "rounded-md bg-primary px-3 py-1.5 text-xs font-medium text-primary-foreground hover:bg-primary/90 transition-colors",
2830
2950
  children: [
2831
- /* @__PURE__ */ jsx24(Camera, { className: "h-3 w-3 mr-1.5 inline" }),
2951
+ /* @__PURE__ */ jsx25(Camera, { className: "h-3 w-3 mr-1.5 inline" }),
2832
2952
  "Create"
2833
2953
  ]
2834
2954
  }
2835
2955
  )
2836
2956
  ] })
2837
2957
  ] }),
2838
- loading ? /* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2839
- /* @__PURE__ */ jsx24(Camera, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
2840
- /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "Loading snapshots..." })
2841
- ] }) : snapshots.length > 0 ? /* @__PURE__ */ jsx24("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs23("table", { className: "w-full text-sm", children: [
2842
- /* @__PURE__ */ jsx24("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs23("tr", { children: [
2843
- /* @__PURE__ */ jsx24("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "ID" }),
2844
- /* @__PURE__ */ jsx24("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Created" }),
2845
- /* @__PURE__ */ jsx24("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Size" }),
2846
- /* @__PURE__ */ jsx24("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Tags" }),
2847
- /* @__PURE__ */ jsx24("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-24" })
2958
+ loading ? /* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2959
+ /* @__PURE__ */ jsx25(Camera, { className: "mx-auto h-6 w-6 text-muted-foreground animate-pulse mb-2" }),
2960
+ /* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: "Loading snapshots..." })
2961
+ ] }) : snapshots.length > 0 ? /* @__PURE__ */ jsx25("div", { className: "rounded-lg border border-border overflow-hidden", children: /* @__PURE__ */ jsxs24("table", { className: "w-full text-sm", children: [
2962
+ /* @__PURE__ */ jsx25("thead", { className: "bg-muted/30 border-b border-border", children: /* @__PURE__ */ jsxs24("tr", { children: [
2963
+ /* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "ID" }),
2964
+ /* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Created" }),
2965
+ /* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Size" }),
2966
+ /* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-left text-xs font-medium text-muted-foreground", children: "Tags" }),
2967
+ /* @__PURE__ */ jsx25("th", { className: "px-4 py-2.5 text-right text-xs font-medium text-muted-foreground w-24" })
2848
2968
  ] }) }),
2849
- /* @__PURE__ */ jsx24("tbody", { className: "divide-y divide-border", children: snapshots.map((s) => /* @__PURE__ */ jsxs23("tr", { children: [
2850
- /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: s.id.slice(0, 12) }),
2851
- /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs23("span", { className: "inline-flex items-center gap-1.5", children: [
2852
- /* @__PURE__ */ jsx24(Clock5, { className: "h-3 w-3" }),
2969
+ /* @__PURE__ */ jsx25("tbody", { className: "divide-y divide-border", children: snapshots.map((s) => /* @__PURE__ */ jsxs24("tr", { children: [
2970
+ /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 font-mono text-xs text-foreground", children: s.id.slice(0, 12) }),
2971
+ /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs24("span", { className: "inline-flex items-center gap-1.5", children: [
2972
+ /* @__PURE__ */ jsx25(Clock5, { className: "h-3 w-3" }),
2853
2973
  formatDate(s.createdAt)
2854
2974
  ] }) }),
2855
- /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs23("span", { className: "inline-flex items-center gap-1.5", children: [
2856
- /* @__PURE__ */ jsx24(HardDrive, { className: "h-3 w-3" }),
2975
+ /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-xs text-muted-foreground", children: /* @__PURE__ */ jsxs24("span", { className: "inline-flex items-center gap-1.5", children: [
2976
+ /* @__PURE__ */ jsx25(HardDrive, { className: "h-3 w-3" }),
2857
2977
  formatBytes(s.sizeBytes)
2858
2978
  ] }) }),
2859
- /* @__PURE__ */ jsx24("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx24("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx24("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground border border-border", children: tag }, tag)) }) : /* @__PURE__ */ jsx24("span", { className: "text-xs text-muted-foreground", children: "-" }) }),
2860
- /* @__PURE__ */ jsx24("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs23("div", { className: "flex items-center justify-end gap-2", children: [
2861
- /* @__PURE__ */ jsxs23(
2979
+ /* @__PURE__ */ jsx25("td", { className: "px-4 py-3", children: s.tags?.length ? /* @__PURE__ */ jsx25("div", { className: "flex items-center gap-1 flex-wrap", children: s.tags.map((tag) => /* @__PURE__ */ jsx25("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground border border-border", children: tag }, tag)) }) : /* @__PURE__ */ jsx25("span", { className: "text-xs text-muted-foreground", children: "-" }) }),
2980
+ /* @__PURE__ */ jsx25("td", { className: "px-4 py-3 text-right", children: /* @__PURE__ */ jsxs24("div", { className: "flex items-center justify-end gap-2", children: [
2981
+ /* @__PURE__ */ jsxs24(
2862
2982
  "button",
2863
2983
  {
2864
2984
  type: "button",
@@ -2866,12 +2986,12 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
2866
2986
  className: "inline-flex items-center gap-1.5 rounded-md bg-muted px-2.5 py-1 text-xs font-medium text-foreground hover:bg-muted/80 transition-colors border border-border",
2867
2987
  title: "Restore to new sandbox",
2868
2988
  children: [
2869
- /* @__PURE__ */ jsx24(RotateCcw, { className: "h-3 w-3" }),
2989
+ /* @__PURE__ */ jsx25(RotateCcw, { className: "h-3 w-3" }),
2870
2990
  "Restore"
2871
2991
  ]
2872
2992
  }
2873
2993
  ),
2874
- onSaveAsTemplate && /* @__PURE__ */ jsx24(
2994
+ onSaveAsTemplate && /* @__PURE__ */ jsx25(
2875
2995
  "button",
2876
2996
  {
2877
2997
  type: "button",
@@ -2883,16 +3003,16 @@ function SnapshotList({ snapshots, onCreate, onRestore, onSaveAsTemplate, loadin
2883
3003
  )
2884
3004
  ] }) })
2885
3005
  ] }, s.id)) })
2886
- ] }) }) : /* @__PURE__ */ jsxs23("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
2887
- /* @__PURE__ */ jsx24(Camera, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
2888
- /* @__PURE__ */ jsx24("p", { className: "text-sm text-muted-foreground", children: "No snapshots yet" }),
2889
- /* @__PURE__ */ jsx24("p", { className: "text-xs text-muted-foreground mt-1", children: "Create a snapshot to save the current state of your sandbox." })
3006
+ ] }) }) : /* @__PURE__ */ jsxs24("div", { className: "rounded-lg border border-border bg-muted/20 p-6 text-center", children: [
3007
+ /* @__PURE__ */ jsx25(Camera, { className: "mx-auto h-8 w-8 text-muted-foreground mb-2" }),
3008
+ /* @__PURE__ */ jsx25("p", { className: "text-sm text-muted-foreground", children: "No snapshots yet" }),
3009
+ /* @__PURE__ */ jsx25("p", { className: "text-xs text-muted-foreground mt-1", children: "Create a snapshot to save the current state of your sandbox." })
2890
3010
  ] })
2891
3011
  ] });
2892
3012
  }
2893
3013
 
2894
3014
  // src/dashboard/promo-banner.tsx
2895
- import { Fragment as Fragment12, jsx as jsx25, jsxs as jsxs24 } from "react/jsx-runtime";
3015
+ import { Fragment as Fragment12, jsx as jsx26, jsxs as jsxs25 } from "react/jsx-runtime";
2896
3016
  function PromoBanner({
2897
3017
  title,
2898
3018
  description,
@@ -2907,21 +3027,21 @@ function PromoBanner({
2907
3027
  "mt-6 inline-flex items-center gap-2 rounded-md border border-white/20 bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-medium text-[var(--btn-primary-text)] transition-colors",
2908
3028
  disabled ? "opacity-50 cursor-not-allowed" : "hover:bg-[var(--btn-primary-hover)]"
2909
3029
  );
2910
- const buttonContent = /* @__PURE__ */ jsxs24(Fragment12, { children: [
3030
+ const buttonContent = /* @__PURE__ */ jsxs25(Fragment12, { children: [
2911
3031
  buttonLabel,
2912
- /* @__PURE__ */ jsxs24("svg", { "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-4 w-4", children: [
2913
- /* @__PURE__ */ jsx25("path", { d: "M5 12h14" }),
2914
- /* @__PURE__ */ jsx25("path", { d: "m12 5 7 7-7 7" })
3032
+ /* @__PURE__ */ jsxs25("svg", { "aria-hidden": "true", xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", className: "h-4 w-4", children: [
3033
+ /* @__PURE__ */ jsx26("path", { d: "M5 12h14" }),
3034
+ /* @__PURE__ */ jsx26("path", { d: "m12 5 7 7-7 7" })
2915
3035
  ] })
2916
3036
  ] });
2917
- return /* @__PURE__ */ jsxs24("div", { className: cn("relative overflow-hidden rounded-xl bg-[var(--brand-strong)] p-8 md:flex md:items-center md:justify-between", className), children: [
2918
- /* @__PURE__ */ jsxs24("div", { className: "relative z-10", children: [
2919
- /* @__PURE__ */ jsx25("h3", { className: "text-xl font-bold text-[var(--brand-strong-text)]", children: title }),
2920
- /* @__PURE__ */ jsx25("p", { className: "mt-2 max-w-md text-sm text-[var(--brand-strong-text-muted)]", children: description }),
2921
- href && !disabled ? /* @__PURE__ */ jsx25("a", { href, target: "_blank", rel: "noopener noreferrer", onClick, className: buttonClasses, children: buttonContent }) : /* @__PURE__ */ jsx25("button", { type: "button", onClick, disabled, className: buttonClasses, children: buttonContent })
3037
+ return /* @__PURE__ */ jsxs25("div", { className: cn("relative overflow-hidden rounded-xl bg-[var(--brand-strong)] p-8 md:flex md:items-center md:justify-between", className), children: [
3038
+ /* @__PURE__ */ jsxs25("div", { className: "relative z-10", children: [
3039
+ /* @__PURE__ */ jsx26("h3", { className: "text-xl font-bold text-[var(--brand-strong-text)]", children: title }),
3040
+ /* @__PURE__ */ jsx26("p", { className: "mt-2 max-w-md text-sm text-[var(--brand-strong-text-muted)]", children: description }),
3041
+ href && !disabled ? /* @__PURE__ */ jsx26("a", { href, target: "_blank", rel: "noopener noreferrer", onClick, className: buttonClasses, children: buttonContent }) : /* @__PURE__ */ jsx26("button", { type: "button", onClick, disabled, className: buttonClasses, children: buttonContent })
2922
3042
  ] }),
2923
- icon && /* @__PURE__ */ jsx25("div", { className: "relative z-10 mt-6 flex items-center md:mt-0", children: /* @__PURE__ */ jsx25("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl border border-white/10 bg-white/10", children: icon }) }),
2924
- /* @__PURE__ */ jsx25("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-1/3 bg-gradient-to-l from-white/5 to-transparent" })
3043
+ icon && /* @__PURE__ */ jsx26("div", { className: "relative z-10 mt-6 flex items-center md:mt-0", children: /* @__PURE__ */ jsx26("div", { className: "flex h-16 w-16 items-center justify-center rounded-2xl border border-white/10 bg-white/10", children: icon }) }),
3044
+ /* @__PURE__ */ jsx26("div", { className: "pointer-events-none absolute inset-y-0 right-0 w-1/3 bg-gradient-to-l from-white/5 to-transparent" })
2925
3045
  ] });
2926
3046
  }
2927
3047
 
@@ -2960,6 +3080,7 @@ export {
2960
3080
  InvoiceTable,
2961
3081
  PlanCards,
2962
3082
  DashboardLayout,
3083
+ SidebarLayout,
2963
3084
  ProfileSelector,
2964
3085
  ProfileComparison,
2965
3086
  MetricAreaChart,