@tangle-network/sandbox-ui 0.115.7 → 0.116.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,11 +1,12 @@
1
1
  import { t as cn$1 } from "./utils-DzWbktWG.js";
2
- import { t as WorkspacePaneHeader } from "./workspace-pane-header-C5e7sPaS.js";
2
+ import { t as WorkspacePaneHeader } from "./workspace-pane-header-Bg1cCcHX.js";
3
3
  import { t as MOTION_CONTROL } from "./motion-DkyBRJb9.js";
4
- import { ArtifactPane, ArtifactPane as ArtifactPane$1, Badge, EmptyState, Input } from "@tangle-network/ui/primitives";
4
+ import { ArtifactPane, ArtifactPane as ArtifactPane$1, EmptyState, Input } from "@tangle-network/ui/primitives";
5
5
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
6
6
  import { useCallback, useEffect, useId, useImperativeHandle, useMemo, useRef, useState } from "react";
7
7
  import { focusField, focusRing, focusRingInset } from "@tangle-network/ui/utils";
8
8
  import { Markdown } from "@tangle-network/ui/markdown";
9
+ import * as DialogPrimitive from "@radix-ui/react-dialog";
9
10
  import { Activity, AlertCircle, AlertTriangle, ArrowLeft, Binary, Bot, Boxes, CheckCircle, ChevronDown, ChevronRight, ChevronUp, FileCode2, FileText, FolderTree, LayoutPanelTop, Loader2, LoaderCircle, MessageSquareText, PanelBottomClose, PanelBottomOpen, PanelLeftClose, PanelLeftOpen, PanelRightClose, PanelRightOpen, Plus, RefreshCw, Search, Settings, Shield, ShieldCheck, Sparkles, Terminal, TerminalSquare, Upload, Wifi, X, XCircle, Zap } from "lucide-react";
10
11
  import { FileArtifactPane, FileTree, filterFileTree } from "@tangle-network/ui/files";
11
12
  import { useActiveSessions, useNavbarSessions, useProjectActivity, useTotalRunningSessions } from "@tangle-network/ui/stores";
@@ -88,8 +89,14 @@ function ResizeHandle({ label, onDragStart, onStep, className }) {
88
89
  "aria-orientation": "vertical",
89
90
  onPointerDown: handlePointerDown,
90
91
  onKeyDown: handleKeyDown,
91
- className: cn$1("relative hidden w-3 shrink-0 cursor-col-resize lg:flex", "items-stretch justify-center bg-transparent touch-none", focusRing, className),
92
- children: [/* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-[var(--md3-outline-variant)] transition-colors" }), /* @__PURE__ */ jsx("span", { className: "absolute inset-y-0 left-1/2 w-[3px] -translate-x-1/2 rounded-full bg-transparent hover:bg-primary/30 focus-visible:bg-primary/40" })]
92
+ className: cn$1("group relative z-10 hidden w-px shrink-0 cursor-col-resize overflow-visible bg-transparent p-0 touch-none lg:flex", focusRing, className),
93
+ children: [/* @__PURE__ */ jsx("span", {
94
+ "aria-hidden": "true",
95
+ className: "absolute inset-y-0 left-1/2 z-10 w-[9px] -translate-x-1/2 cursor-col-resize bg-transparent"
96
+ }), /* @__PURE__ */ jsx("span", {
97
+ "aria-hidden": "true",
98
+ className: "absolute inset-y-0 left-1/2 w-px -translate-x-1/2 bg-border transition-colors group-hover:bg-primary/20 group-focus-visible:bg-primary/30"
99
+ })]
93
100
  });
94
101
  }
95
102
  function HorizontalResizeHandle({ label, onDragStart, onStep, className }) {
@@ -114,46 +121,65 @@ function HorizontalResizeHandle({ label, onDragStart, onStep, className }) {
114
121
  "aria-orientation": "horizontal",
115
122
  onPointerDown: handlePointerDown,
116
123
  onKeyDown: handleKeyDown,
117
- className: cn$1("relative hidden h-3 shrink-0 cursor-row-resize lg:flex", "items-center justify-center bg-transparent touch-none w-full", focusRing, className),
118
- children: [/* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 top-1/2 h-px -translate-y-1/2 bg-[var(--md3-outline-variant)] transition-colors" }), /* @__PURE__ */ jsx("span", { className: "absolute inset-x-0 top-1/2 h-[3px] -translate-y-1/2 rounded-full bg-transparent hover:bg-primary/30 focus-visible:bg-primary/40" })]
124
+ className: cn$1("group relative z-10 hidden h-px w-full shrink-0 cursor-row-resize overflow-visible bg-transparent p-0 touch-none lg:flex", focusRing, className),
125
+ children: [/* @__PURE__ */ jsx("span", {
126
+ "aria-hidden": "true",
127
+ className: "absolute inset-x-0 top-1/2 z-10 h-[9px] w-full -translate-y-1/2 cursor-row-resize bg-transparent"
128
+ }), /* @__PURE__ */ jsx("span", {
129
+ "aria-hidden": "true",
130
+ className: "absolute inset-x-0 top-1/2 h-px -translate-y-1/2 bg-border transition-colors group-hover:bg-primary/20 group-focus-visible:bg-primary/30"
131
+ })]
119
132
  });
120
133
  }
121
- function MobileDrawer({ side, title, header, onClose, children }) {
122
- return /* @__PURE__ */ jsxs("div", {
123
- className: "fixed inset-0 z-50 flex lg:hidden",
124
- "aria-modal": "true",
125
- role: "dialog",
126
- "aria-label": title,
127
- children: [/* @__PURE__ */ jsx("button", {
128
- type: "button",
129
- "aria-label": `Close ${title}`,
130
- onClick: onClose,
131
- className: "absolute inset-0 bg-black/80 backdrop-blur-sm"
132
- }), /* @__PURE__ */ jsxs("aside", {
133
- className: cn$1("relative flex h-full w-[min(88vw,24rem)] flex-col border-[var(--md3-outline-variant)] bg-surface-container-highest shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]", side === "left" ? "border-r" : "ml-auto border-l"),
134
- children: [/* @__PURE__ */ jsxs(WorkspacePaneHeader, {
135
- className: "justify-between gap-3",
136
- children: [/* @__PURE__ */ jsx("div", {
137
- className: "min-w-0 flex-1",
138
- children: header ?? /* @__PURE__ */ jsx("span", {
139
- className: "text-[13px] font-medium text-foreground",
140
- children: title
141
- })
142
- }), /* @__PURE__ */ jsx("button", {
143
- type: "button",
144
- "aria-label": `Close ${title}`,
145
- onClick: onClose,
146
- className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
147
- children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
148
- })]
149
- }), /* @__PURE__ */ jsx("div", {
150
- className: "flex-1 overflow-auto",
151
- children
152
- })]
153
- })]
134
+ function MobileDrawer({ side, title, header, onClose, onReturnFocus, theme, density, children }) {
135
+ return /* @__PURE__ */ jsx(DialogPrimitive.Root, {
136
+ open: true,
137
+ onOpenChange: (open) => {
138
+ if (!open) onClose();
139
+ },
140
+ children: /* @__PURE__ */ jsxs(DialogPrimitive.Portal, { children: [/* @__PURE__ */ jsx(DialogPrimitive.Overlay, { className: "fixed inset-0 z-50 bg-black/80 backdrop-blur-sm lg:hidden" }), /* @__PURE__ */ jsxs(DialogPrimitive.Content, {
141
+ ...theme ? {
142
+ "data-sandbox-ui": "true",
143
+ "data-sandbox-theme": theme
144
+ } : {},
145
+ "data-density": density,
146
+ onCloseAutoFocus: (event) => {
147
+ event.preventDefault();
148
+ requestAnimationFrame(onReturnFocus);
149
+ },
150
+ className: cn$1("fixed inset-y-0 z-50 flex h-full w-[min(88vw,24rem)] flex-col border-border bg-card shadow-[0_8px_30px_rgba(0,0,0,0.18)] lg:hidden", side === "left" ? "left-0 border-r" : "right-0 border-l"),
151
+ children: [
152
+ /* @__PURE__ */ jsx(DialogPrimitive.Title, {
153
+ className: "sr-only",
154
+ children: title
155
+ }),
156
+ /* @__PURE__ */ jsxs(WorkspacePaneHeader, {
157
+ className: "justify-between gap-3",
158
+ children: [/* @__PURE__ */ jsx("div", {
159
+ className: "min-w-0 flex-1",
160
+ children: header ?? /* @__PURE__ */ jsx("span", {
161
+ className: "text-[13px] font-medium text-foreground",
162
+ children: title
163
+ })
164
+ }), /* @__PURE__ */ jsx(DialogPrimitive.Close, {
165
+ asChild: true,
166
+ children: /* @__PURE__ */ jsx("button", {
167
+ type: "button",
168
+ "aria-label": `Close ${title}`,
169
+ className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
170
+ children: /* @__PURE__ */ jsx(X, { className: "h-4 w-4" })
171
+ })
172
+ })]
173
+ }),
174
+ /* @__PURE__ */ jsx("div", {
175
+ className: "min-h-0 flex-1 overflow-auto",
176
+ children
177
+ })
178
+ ]
179
+ })] })
154
180
  });
155
181
  }
156
- function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter, right, rightHeader, bottom, bottomHeader, defaultLeftOpen = true, defaultRightOpen = false, defaultBottomOpen = false, defaultLeftWidth = 280, defaultRightWidth = 480, defaultBottomHeight = 224, minLeftWidth = 220, maxLeftWidth = 420, minRightWidth = 320, maxRightWidth = 720, minCenterWidth = 400, minBottomHeight = 100, maxBottomHeight = 500, persistenceKey, resizable = true, theme, density = "comfortable", leftLabel = "Left workspace panel", rightLabel = "Right workspace panel", bottomLabel = "Bottom runtime panel", leftOpen: leftOpenProp, onLeftOpenChange, rightOpen: rightOpenProp, onRightOpenChange, keyboardShortcuts = false, leftCollapsedControl, leftContentClassName, rightContentClassName, centerHeaderVisibility = "always", className }) {
182
+ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter, right, rightHeader, bottom, bottomHeader, defaultLeftOpen = true, defaultRightOpen = false, defaultBottomOpen = false, defaultLeftWidth = 280, defaultRightWidth = 480, defaultBottomHeight = 224, minLeftWidth = 220, maxLeftWidth = 420, minRightWidth = 320, maxRightWidth = 720, minCenterWidth = 400, minBottomHeight = 100, maxBottomHeight = 500, persistenceKey, resizable = true, theme, density = "comfortable", leftLabel = "Left workspace panel", rightLabel = "Right workspace panel", bottomLabel = "Bottom runtime panel", leftOpen: leftOpenProp, onLeftOpenChange, rightOpen: rightOpenProp, onRightOpenChange, keyboardShortcuts = false, leftCollapsedControl, leftContentClassName, rightContentClassName, centerHeaderVisibility = "auto", className }) {
157
183
  const desktop = useDesktopMediaQuery(DESKTOP_BREAKPOINT);
158
184
  const dragStateRef = useRef(null);
159
185
  const storedLayout = useMemo(() => persistenceKey ? readStoredLayout(persistenceKey) : null, [persistenceKey]);
@@ -177,7 +203,31 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
177
203
  const [leftWidth, setLeftWidth] = useState(clamp(storedLayout?.leftWidth ?? defaultLeftWidth, minLeftWidth, maxLeftWidth));
178
204
  const [rightWidth, setRightWidth] = useState(clamp(storedLayout?.rightWidth ?? defaultRightWidth, minRightWidth, maxRightWidth));
179
205
  const [bottomHeight, setBottomHeight] = useState(clamp(storedLayout?.bottomHeight ?? defaultBottomHeight, minBottomHeight, maxBottomHeight));
180
- const showCenterHeader = centerHeaderVisibility === "auto" ? Boolean(centerHeader) || hasLeft && !leftOpen || hasRight && !rightOpen || Boolean(bottom) && !bottomOpen : Boolean(centerHeader || left || right || bottom);
206
+ const showCenterHeader = centerHeaderVisibility === "auto" ? Boolean(centerHeader) : Boolean(centerHeader || left || right || bottom);
207
+ const reopenClassName = showCenterHeader ? `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}` : `flex h-10 w-8 items-center justify-center rounded-md border border-border bg-card text-muted-foreground shadow-sm transition-colors hover:bg-accent hover:text-foreground ${focusRing}`;
208
+ const leftReopenControl = left && !leftOpen ? leftCollapsedControl ?? /* @__PURE__ */ jsx("button", {
209
+ type: "button",
210
+ "aria-label": "Open left panel",
211
+ onClick: () => setLeftOpen(true),
212
+ className: reopenClassName,
213
+ children: /* @__PURE__ */ jsx(PanelLeftOpen, { className: "h-4 w-4" })
214
+ }) : null;
215
+ const bottomReopenControl = bottom && !bottomOpen ? /* @__PURE__ */ jsx("button", {
216
+ type: "button",
217
+ "aria-label": "Open bottom panel",
218
+ onClick: () => setBottomOpen(true),
219
+ className: reopenClassName,
220
+ children: /* @__PURE__ */ jsx(PanelBottomOpen, { className: "h-4 w-4" })
221
+ }) : null;
222
+ const rightReopenControl = right && !rightOpen ? /* @__PURE__ */ jsx("button", {
223
+ type: "button",
224
+ "aria-label": "Open right panel",
225
+ onClick: () => setRightOpen(true),
226
+ className: reopenClassName,
227
+ children: /* @__PURE__ */ jsx(PanelRightOpen, { className: "h-4 w-4" })
228
+ }) : null;
229
+ const leftReopenRef = useRef(null);
230
+ const rightReopenRef = useRef(null);
181
231
  useEffect(() => {
182
232
  if (!persistenceKey || typeof window === "undefined") return;
183
233
  const payload = {
@@ -260,6 +310,14 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
260
310
  minRightWidth
261
311
  ]);
262
312
  const shellRef = useRef(null);
313
+ const focusSideControl = (side) => {
314
+ const target = (side === "left" ? leftReopenRef : rightReopenRef).current?.querySelector("button, a[href], [tabindex]:not([tabindex=\"-1\"])");
315
+ if (target) {
316
+ target.focus();
317
+ return;
318
+ }
319
+ shellRef.current?.querySelector(`[aria-label="Collapse ${side} panel"]`)?.focus();
320
+ };
263
321
  const [shellWidth, setShellWidth] = useState(null);
264
322
  useEffect(() => {
265
323
  const shell = shellRef.current;
@@ -335,7 +393,7 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
335
393
  "data-sandbox-theme": theme
336
394
  } : {},
337
395
  "data-density": density,
338
- className: cn$1("flex h-screen flex-col overflow-hidden bg-[var(--bg-root)] text-foreground font-sans", className),
396
+ className: cn$1("flex h-screen flex-col overflow-hidden bg-background text-foreground font-sans", className),
339
397
  children: [
340
398
  /* @__PURE__ */ jsxs("div", {
341
399
  ref: shellRef,
@@ -344,7 +402,7 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
344
402
  desktop && left && leftOpen && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsxs("aside", {
345
403
  "aria-label": leftLabel,
346
404
  style: leftStyle,
347
- className: "hidden shrink-0 border-r border-[var(--md3-outline-variant)] bg-surface-container-low lg:flex lg:flex-col",
405
+ className: cn$1("hidden shrink-0 bg-card lg:flex lg:flex-col", !resizable && "border-r border-border"),
348
406
  children: [leftHeader && /* @__PURE__ */ jsxs(WorkspacePaneHeader, {
349
407
  className: "justify-between gap-2",
350
408
  children: [/* @__PURE__ */ jsx("div", {
@@ -353,7 +411,10 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
353
411
  }), /* @__PURE__ */ jsx("button", {
354
412
  type: "button",
355
413
  "aria-label": "Collapse left panel",
356
- onClick: () => setLeftOpen(false),
414
+ onClick: () => {
415
+ setLeftOpen(false);
416
+ requestAnimationFrame(() => focusSideControl("left"));
417
+ },
357
418
  className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
358
419
  children: /* @__PURE__ */ jsx(PanelLeftClose, { className: "h-4 w-4" })
359
420
  })]
@@ -372,36 +433,43 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
372
433
  showCenterHeader && /* @__PURE__ */ jsxs(WorkspacePaneHeader, {
373
434
  className: "gap-2",
374
435
  children: [
375
- left && !leftOpen && (leftCollapsedControl ?? /* @__PURE__ */ jsx("button", {
376
- type: "button",
377
- "aria-label": "Open left panel",
378
- onClick: () => setLeftOpen(true),
379
- className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
380
- children: /* @__PURE__ */ jsx(PanelLeftOpen, { className: "h-4 w-4" })
381
- })),
436
+ leftReopenControl && /* @__PURE__ */ jsx("div", {
437
+ ref: leftReopenRef,
438
+ className: "shrink-0",
439
+ children: leftReopenControl
440
+ }),
382
441
  /* @__PURE__ */ jsx("div", {
383
442
  className: "min-w-0 flex-1",
384
443
  children: centerHeader
385
444
  }),
386
- bottom && !bottomOpen && /* @__PURE__ */ jsx("button", {
387
- type: "button",
388
- "aria-label": "Open bottom panel",
389
- onClick: () => setBottomOpen(true),
390
- className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
391
- children: /* @__PURE__ */ jsx(PanelBottomOpen, { className: "h-4 w-4" })
392
- }),
393
- right && !rightOpen && /* @__PURE__ */ jsx("button", {
394
- type: "button",
395
- "aria-label": "Open right panel",
396
- onClick: () => setRightOpen(true),
397
- className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
398
- children: /* @__PURE__ */ jsx(PanelRightOpen, { className: "h-4 w-4" })
445
+ bottomReopenControl,
446
+ rightReopenControl && /* @__PURE__ */ jsx("div", {
447
+ ref: rightReopenRef,
448
+ className: "shrink-0",
449
+ children: rightReopenControl
399
450
  })
400
451
  ]
401
452
  }),
402
- /* @__PURE__ */ jsx("div", {
403
- className: "min-h-0 flex-1 overflow-auto",
404
- children: center
453
+ /* @__PURE__ */ jsxs("div", {
454
+ className: "flex min-h-0 flex-1",
455
+ children: [
456
+ !showCenterHeader && leftReopenControl && /* @__PURE__ */ jsx("div", {
457
+ ref: leftReopenRef,
458
+ className: "shrink-0 pt-2",
459
+ children: leftReopenControl
460
+ }),
461
+ /* @__PURE__ */ jsx("div", {
462
+ className: "min-w-0 flex-1 overflow-auto",
463
+ children: center
464
+ }),
465
+ !showCenterHeader && (bottomReopenControl || rightReopenControl) && /* @__PURE__ */ jsxs("div", {
466
+ className: "flex shrink-0 flex-col gap-1 pt-2",
467
+ children: [bottomReopenControl, rightReopenControl && /* @__PURE__ */ jsx("div", {
468
+ ref: rightReopenRef,
469
+ children: rightReopenControl
470
+ })]
471
+ })
472
+ ]
405
473
  }),
406
474
  bottom && bottomOpen && /* @__PURE__ */ jsxs(Fragment, { children: [resizable && /* @__PURE__ */ jsx(HorizontalResizeHandle, {
407
475
  label: "Resize bottom panel",
@@ -409,12 +477,12 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
409
477
  onStep: stepBottomHeight
410
478
  }), /* @__PURE__ */ jsx("section", {
411
479
  "aria-label": bottomLabel,
412
- className: "border-t border-[var(--md3-outline-variant)] bg-surface-container shrink-0",
480
+ className: cn$1("shrink-0 bg-card", !resizable && "border-t border-border"),
413
481
  style: { height: `${bottomHeight}px` },
414
482
  children: /* @__PURE__ */ jsxs("div", {
415
483
  className: "flex h-full flex-col",
416
484
  children: [/* @__PURE__ */ jsxs("div", {
417
- className: "flex items-center justify-between gap-2 border-b border-[var(--md3-outline-variant)] px-3 py-1.5 bg-surface-container-high shrink-0",
485
+ className: "flex items-center justify-between gap-2 border-b border-border bg-background px-3 py-1.5 shrink-0",
418
486
  children: [/* @__PURE__ */ jsx("div", {
419
487
  className: "min-w-0 flex-1",
420
488
  children: bottomHeader ?? /* @__PURE__ */ jsx("span", {
@@ -435,7 +503,7 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
435
503
  })
436
504
  })] }),
437
505
  centerFooter && /* @__PURE__ */ jsx("div", {
438
- className: "shrink-0 border-t border-[var(--md3-outline-variant)] bg-surface-container-low",
506
+ className: "shrink-0 border-t border-border bg-card",
439
507
  children: centerFooter
440
508
  })
441
509
  ]
@@ -447,7 +515,7 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
447
515
  }), /* @__PURE__ */ jsxs("aside", {
448
516
  "aria-label": rightLabel,
449
517
  style: rightStyle,
450
- className: "hidden shrink-0 border-l border-[var(--md3-outline-variant)] bg-surface-container-low lg:flex lg:flex-col",
518
+ className: cn$1("hidden shrink-0 bg-card lg:flex lg:flex-col", !resizable && "border-l border-border"),
451
519
  children: [/* @__PURE__ */ jsxs(WorkspacePaneHeader, {
452
520
  className: "justify-between gap-2",
453
521
  children: [/* @__PURE__ */ jsx("div", {
@@ -459,7 +527,10 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
459
527
  }), /* @__PURE__ */ jsx("button", {
460
528
  type: "button",
461
529
  "aria-label": "Collapse right panel",
462
- onClick: () => setRightOpen(false),
530
+ onClick: () => {
531
+ setRightOpen(false);
532
+ requestAnimationFrame(() => focusSideControl("right"));
533
+ },
463
534
  className: `rounded-[2px] p-1 text-muted-foreground transition-colors hover:bg-accent hover:text-foreground ${focusRing}`,
464
535
  children: /* @__PURE__ */ jsx(PanelRightClose, { className: "h-4 w-4" })
465
536
  })]
@@ -470,11 +541,14 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
470
541
  })] })
471
542
  ]
472
543
  }),
473
- !desktop && left && leftOpen && /* @__PURE__ */ jsx(MobileDrawer, {
544
+ !desktop && left && leftOpen && !(right && rightOpen) && /* @__PURE__ */ jsx(MobileDrawer, {
474
545
  side: "left",
475
546
  title: leftLabel,
476
547
  header: leftHeader,
477
548
  onClose: () => setLeftOpen(false),
549
+ onReturnFocus: () => focusSideControl("left"),
550
+ theme,
551
+ density,
478
552
  children: left
479
553
  }),
480
554
  !desktop && right && rightOpen && /* @__PURE__ */ jsx(MobileDrawer, {
@@ -482,6 +556,9 @@ function WorkspaceLayout({ left, leftHeader, center, centerHeader, centerFooter,
482
556
  title: rightLabel,
483
557
  header: rightHeader,
484
558
  onClose: () => setRightOpen(false),
559
+ onReturnFocus: () => focusSideControl("right"),
560
+ theme,
561
+ density,
485
562
  children: right
486
563
  })
487
564
  ]
@@ -586,7 +663,7 @@ function DirectoryPane({ root, selectedPath, onSelect, onRefresh, onUpload, titl
586
663
  //#endregion
587
664
  //#region src/workspace/status-banner.tsx
588
665
  /**
589
- * StatusBanner — full-width notification banner for connection/provisioning states.
666
+ * StatusBanner — inline notice for connection and provisioning states.
590
667
  */
591
668
  const BANNER_STYLES = {
592
669
  provisioning: {
@@ -602,9 +679,9 @@ const BANNER_STYLES = {
602
679
  icon: Wifi
603
680
  },
604
681
  error: {
605
- bg: "bg-[var(--code-error)]/5",
606
- border: "border-[var(--code-error)]/20",
607
- text: "text-[var(--code-error)]",
682
+ bg: "bg-[var(--surface-danger-bg)]",
683
+ border: "border-[var(--surface-danger-border)]",
684
+ text: "text-[var(--surface-danger-text)]",
608
685
  icon: AlertCircle
609
686
  },
610
687
  warning: {
@@ -620,8 +697,8 @@ const BANNER_STYLES = {
620
697
  icon: CheckCircle
621
698
  },
622
699
  info: {
623
- bg: "bg-surface-container-high",
624
- border: "border-[var(--md3-outline-variant)]",
700
+ bg: "bg-background",
701
+ border: "border-border",
625
702
  text: "text-muted-foreground",
626
703
  icon: AlertCircle
627
704
  }
@@ -632,27 +709,27 @@ function StatusBanner({ type, message, detail, onDismiss, className }) {
632
709
  const isAnimated = type === "provisioning" || type === "connecting";
633
710
  const role = type === "error" ? "alert" : "status";
634
711
  return /* @__PURE__ */ jsxs("div", {
635
- className: cn$1("flex items-center gap-2.5 px-4 py-2 border-b font-sans text-sm", style.bg, style.border, className),
712
+ className: cn$1("flex items-start gap-3 rounded-lg border px-3 py-2.5 font-sans text-sm", style.bg, style.border, className),
636
713
  children: [/* @__PURE__ */ jsxs("div", {
637
714
  role,
638
- className: "flex min-w-0 items-center gap-2.5",
639
- children: [
640
- /* @__PURE__ */ jsx(Icon, {
641
- className: cn$1("h-4 w-4 shrink-0", style.text, isAnimated && "animate-spin"),
642
- ...isAnimated ? { "data-motion": "essential" } : {}
643
- }),
644
- /* @__PURE__ */ jsx("span", {
645
- className: "font-medium text-foreground",
715
+ className: "flex min-w-0 flex-1 items-start gap-2.5",
716
+ children: [/* @__PURE__ */ jsx(Icon, {
717
+ className: cn$1("mt-0.5 h-4 w-4 shrink-0", style.text, isAnimated && "animate-spin"),
718
+ ...isAnimated ? { "data-motion": "essential" } : {}
719
+ }), /* @__PURE__ */ jsxs("div", {
720
+ className: "min-w-0 flex-1",
721
+ children: [/* @__PURE__ */ jsx("p", {
722
+ className: "break-words font-medium text-foreground",
646
723
  children: message
647
- }),
648
- detail && /* @__PURE__ */ jsx("span", {
649
- className: "font-mono text-xs text-muted-foreground tabular-nums",
724
+ }), detail && /* @__PURE__ */ jsx("p", {
725
+ className: "mt-0.5 break-words font-mono text-xs text-muted-foreground tabular-nums",
650
726
  children: detail
651
- })
652
- ]
727
+ })]
728
+ })]
653
729
  }), onDismiss && /* @__PURE__ */ jsx("button", {
730
+ type: "button",
654
731
  onClick: onDismiss,
655
- className: "ml-auto font-sans text-xs font-medium text-muted-foreground transition-colors hover:text-foreground",
732
+ className: `ml-auto mt-0.5 shrink-0 font-sans text-xs font-medium text-muted-foreground transition-colors hover:text-foreground ${focusRing}`,
656
733
  children: "Dismiss"
657
734
  })]
658
735
  });
@@ -1541,12 +1618,12 @@ function ArtifactTabs({ artifacts, activeArtifactId, onSelect, onClose, tabIdPre
1541
1618
  return /* @__PURE__ */ jsx("div", {
1542
1619
  role: "tablist",
1543
1620
  "aria-label": "Artifacts",
1544
- className: "flex items-center overflow-x-auto border-b border-[var(--md3-outline-variant)] bg-surface-container-high",
1621
+ className: "flex items-center overflow-x-auto border-b border-border bg-background",
1545
1622
  children: artifacts.map((artifact) => {
1546
1623
  const Icon = artifact.icon ?? getArtifactTabIcon(artifact.kind);
1547
1624
  const isActive = artifact.id === activeArtifactId;
1548
1625
  return /* @__PURE__ */ jsxs("div", {
1549
- className: cn$1("group flex shrink-0 items-center border-r border-[var(--md3-outline-variant)] bg-surface-container relative", isActive ? "text-foreground after:absolute after:top-0 after:left-0 after:right-0 after:h-[2px] after:bg-primary" : "text-muted-foreground hover:bg-surface-container-high cursor-pointer"),
1626
+ className: cn$1("group relative flex shrink-0 items-center border-r border-border bg-card", isActive ? "text-foreground after:absolute after:top-0 after:left-0 after:right-0 after:h-[2px] after:bg-primary" : "cursor-pointer text-muted-foreground hover:bg-muted"),
1550
1627
  children: [/* @__PURE__ */ jsxs("button", {
1551
1628
  type: "button",
1552
1629
  ref: (element) => {
@@ -1602,7 +1679,7 @@ function ArtifactTabs({ artifacts, activeArtifactId, onSelect, onClose, tabIdPre
1602
1679
  function renderArtifact(artifact) {
1603
1680
  switch (artifact.kind) {
1604
1681
  case "file": return /* @__PURE__ */ jsx(FileArtifactPane, {
1605
- path: artifact.path,
1682
+ path: artifact.path === artifact.filename ? void 0 : artifact.path,
1606
1683
  filename: artifact.filename,
1607
1684
  content: artifact.content,
1608
1685
  blobUrl: artifact.blobUrl,
@@ -1612,10 +1689,11 @@ function renderArtifact(artifact) {
1612
1689
  activeTabId: artifact.activeTabId,
1613
1690
  onTabSelect: artifact.onTabSelect,
1614
1691
  onTabClose: artifact.onTabClose,
1615
- eyebrow: artifact.eyebrow,
1692
+ eyebrow: artifact.eyebrow ?? null,
1616
1693
  meta: artifact.meta,
1617
1694
  toolbar: artifact.toolbar,
1618
- footer: artifact.footer
1695
+ footer: artifact.footer,
1696
+ hideTitleBlock: typeof artifact.title === "string" && artifact.title === artifact.filename && artifact.path === artifact.filename && !artifact.eyebrow && !artifact.meta
1619
1697
  });
1620
1698
  case "markdown": return /* @__PURE__ */ jsx(ArtifactPane, {
1621
1699
  eyebrow: artifact.eyebrow ?? "Document",
@@ -1693,7 +1771,7 @@ function renderRegion(sections, region) {
1693
1771
  * into a complete session surface: directory, agent timeline, artifacts, and
1694
1772
  * runtime in one reusable shell.
1695
1773
  */
1696
- function SandboxWorkbench({ title = "Sandbox session", subtitle, status, centerHeader: centerHeaderProp, composer, rail, directory, session, artifacts: artifactsProp = [], activeArtifactId, onArtifactChange, onArtifactClose, runtime, layout, emptyArtifactState, className }) {
1774
+ function SandboxWorkbench({ title, subtitle, status, centerHeader: centerHeaderProp, composer, rail, directory, session, artifacts: artifactsProp = [], activeArtifactId, onArtifactChange, onArtifactClose, runtime, layout, emptyArtifactState, className }) {
1697
1775
  const artifacts = useMemo(() => sortPinnedFirst(artifactsProp), [artifactsProp]);
1698
1776
  const artifactTabsId = useId();
1699
1777
  const artifactPanelId = `${artifactTabsId}-panel`;
@@ -1712,68 +1790,64 @@ function SandboxWorkbench({ title = "Sandbox session", subtitle, status, centerH
1712
1790
  if (activeArtifactId === void 0) setUncontrolledArtifactId(artifactId);
1713
1791
  onArtifactChange?.(artifactId);
1714
1792
  };
1715
- const brandedHeader = /* @__PURE__ */ jsxs("div", {
1716
- className: "flex min-w-0 items-start justify-between gap-4 rounded-[var(--radius-xl)] border border-[var(--md3-outline-variant)] bg-surface-container px-4 py-3.5",
1717
- children: [/* @__PURE__ */ jsxs("div", {
1718
- className: "min-w-0",
1719
- children: [
1720
- /* @__PURE__ */ jsx("div", {
1721
- className: "text-[10px] font-semibold uppercase tracking-[0.18em] text-primary",
1722
- children: "Tangle Sandbox"
1723
- }),
1724
- /* @__PURE__ */ jsx("div", {
1725
- className: "truncate text-[17px] font-semibold tracking-[0.01em] text-foreground",
1726
- children: title
1727
- }),
1728
- subtitle && /* @__PURE__ */ jsx("div", {
1729
- className: "truncate text-sm text-muted-foreground",
1730
- children: subtitle
1731
- })
1732
- ]
1733
- }), /* @__PURE__ */ jsxs("div", {
1734
- className: "flex shrink-0 flex-wrap items-center justify-end gap-2",
1735
- children: [status, artifacts.length > 0 && /* @__PURE__ */ jsxs(Badge, {
1736
- variant: "outline",
1737
- children: [artifacts.length, " artifacts"]
1738
- })]
1739
- })]
1740
- });
1741
1793
  const quiet = centerHeaderProp === null;
1742
- const centerHeader = centerHeaderProp === void 0 ? brandedHeader : centerHeaderProp ?? void 0;
1794
+ const centerHeader = centerHeaderProp ?? void 0;
1743
1795
  const { composerControls, ...chatSession } = session;
1744
1796
  const transcript = /* @__PURE__ */ jsxs("div", {
1745
- className: cn$1("flex h-full min-h-0 flex-col", quiet && "bg-surface"),
1746
- children: [
1747
- /* @__PURE__ */ jsx(ChatContainer, {
1748
- ...chatSession,
1749
- className: "min-h-0 flex-1",
1750
- presentation: session.presentation ?? "timeline"
1751
- }),
1752
- composerControls && /* @__PURE__ */ jsx("div", {
1753
- className: "shrink-0 border-t border-[var(--md3-outline-variant)] bg-surface-container-high px-3 py-2",
1754
- children: composerControls
1755
- }),
1756
- composer && /* @__PURE__ */ jsx("div", {
1757
- className: "shrink-0",
1758
- children: /* @__PURE__ */ jsx("div", {
1759
- className: "mx-auto w-full max-w-3xl px-3 pb-3",
1760
- children: composer
1761
- })
1762
- })
1763
- ]
1797
+ className: cn$1("flex h-full min-h-0 flex-col", quiet && "bg-background"),
1798
+ children: [/* @__PURE__ */ jsx(ChatContainer, {
1799
+ ...chatSession,
1800
+ className: "min-h-0 flex-1",
1801
+ presentation: session.presentation ?? "timeline"
1802
+ }), (composerControls || composer) && /* @__PURE__ */ jsxs("div", {
1803
+ className: "mx-auto flex w-full max-w-3xl shrink-0 flex-col gap-2 px-3 py-3",
1804
+ children: [composerControls, composer]
1805
+ })]
1764
1806
  });
1765
- const center = quiet ? transcript : /* @__PURE__ */ jsx(ArtifactPane, {
1766
- eyebrow: session.eyebrow ?? "Agent Session",
1767
- title: session.title ?? "Execution timeline",
1768
- subtitle: session.subtitle,
1769
- meta: session.meta,
1770
- headerActions: session.headerActions,
1771
- className: "h-full",
1772
- contentClassName: "bg-surface-container",
1773
- children: transcript
1807
+ const paneSubtitle = subtitle ?? session.subtitle;
1808
+ const center = quiet ? transcript : /* @__PURE__ */ jsxs("section", {
1809
+ className: "flex h-full min-h-0 flex-col overflow-hidden bg-background text-foreground",
1810
+ children: [/* @__PURE__ */ jsxs(WorkspacePaneHeader, {
1811
+ className: "gap-3",
1812
+ children: [/* @__PURE__ */ jsxs("div", {
1813
+ className: "min-w-0 flex-1",
1814
+ children: [/* @__PURE__ */ jsxs("div", {
1815
+ className: "flex min-w-0 items-center gap-2",
1816
+ children: [session.eyebrow && /* @__PURE__ */ jsx("span", {
1817
+ className: "max-w-[35%] shrink-0 truncate text-[10px] font-semibold uppercase tracking-wider text-muted-foreground",
1818
+ children: session.eyebrow
1819
+ }), /* @__PURE__ */ jsx("div", {
1820
+ className: "min-w-0 flex-1 truncate text-[13px] font-medium text-foreground",
1821
+ children: title ?? session.title ?? "Execution timeline"
1822
+ })]
1823
+ }), (paneSubtitle || session.meta || status) && /* @__PURE__ */ jsxs("div", {
1824
+ className: "mt-0.5 flex min-w-0 items-center gap-2 overflow-hidden text-xs text-muted-foreground",
1825
+ children: [
1826
+ paneSubtitle && /* @__PURE__ */ jsx("span", {
1827
+ className: "min-w-0 truncate",
1828
+ children: paneSubtitle
1829
+ }),
1830
+ session.meta && /* @__PURE__ */ jsx("span", {
1831
+ className: "min-w-0 truncate",
1832
+ children: session.meta
1833
+ }),
1834
+ status && /* @__PURE__ */ jsx("span", {
1835
+ className: "shrink-0",
1836
+ children: status
1837
+ })
1838
+ ]
1839
+ })]
1840
+ }), session.headerActions && /* @__PURE__ */ jsx("div", {
1841
+ className: "flex shrink-0 items-center gap-1.5",
1842
+ children: session.headerActions
1843
+ })]
1844
+ }), /* @__PURE__ */ jsx("div", {
1845
+ className: "min-h-0 flex-1 overflow-auto bg-background",
1846
+ children: transcript
1847
+ })]
1774
1848
  });
1775
1849
  const artifactPanel = artifacts.length > 0 || emptyArtifactState ? /* @__PURE__ */ jsxs("section", {
1776
- className: "flex h-full min-h-0 flex-col bg-surface-container",
1850
+ className: "flex h-full min-h-0 flex-col bg-background",
1777
1851
  children: [/* @__PURE__ */ jsx(ArtifactTabs, {
1778
1852
  artifacts,
1779
1853
  activeArtifactId: resolvedArtifactId,
@@ -1787,7 +1861,7 @@ function SandboxWorkbench({ title = "Sandbox session", subtitle, status, centerH
1787
1861
  "aria-labelledby": activeArtifact ? `${artifactTabsId}-${activeArtifact.id}` : void 0,
1788
1862
  "aria-label": activeArtifact ? void 0 : "Artifact content",
1789
1863
  tabIndex: 0,
1790
- className: `min-h-0 flex-1 overflow-auto bg-surface-container ${focusRingInset}`,
1864
+ className: `min-h-0 flex-1 overflow-auto bg-background ${focusRingInset}`,
1791
1865
  children: activeArtifact ? renderArtifact(activeArtifact) : /* @__PURE__ */ jsx("div", {
1792
1866
  className: "flex h-full items-center justify-center p-6",
1793
1867
  children: emptyArtifactState ?? /* @__PURE__ */ jsx(EmptyState, {
@@ -1865,8 +1939,8 @@ function SandboxWorkbench({ title = "Sandbox session", subtitle, status, centerH
1865
1939
  keyboardShortcuts: layout?.keyboardShortcuts,
1866
1940
  leftCollapsedControl: layout?.leftCollapsedControl,
1867
1941
  leftContentClassName: railOnly ? "py-0" : void 0,
1868
- centerHeaderVisibility: quiet ? "auto" : "always",
1869
- className: cn$1("p-3 lg:p-4", className)
1942
+ centerHeaderVisibility: "auto",
1943
+ className: cn$1("p-2", className)
1870
1944
  });
1871
1945
  }
1872
1946
  function AgentWorkbench(props) {
@@ -7,7 +7,7 @@ import { jsx } from "react/jsx-runtime";
7
7
  */
8
8
  function WorkspacePaneHeader({ className, ...props }) {
9
9
  return /* @__PURE__ */ jsx("div", {
10
- className: cn("flex h-14 shrink-0 items-center border-b border-[var(--md3-outline-variant)] bg-surface-container-high px-3", className),
10
+ className: cn("flex h-14 shrink-0 items-center border-b border-border bg-card px-3", className),
11
11
  ...props
12
12
  });
13
13
  }
@@ -1,2 +1,2 @@
1
- import { $ as TerminalProps, A as ShellShouldRevalidateArgs, B as SessionSidebarLink, C as SandboxWorkbenchLayoutOptions, D as SandboxWorkbenchSessionProps, E as SandboxWorkbenchProps, F as SessionSidebar, G as SessionOptimisticController, H as SessionSidebarVariant, I as SessionSidebarBadge, J as useOptimisticSessionItems, K as UseOptimisticSessionItemsOptions, L as SessionSidebarFilter, M as createShellShouldRevalidate, N as shellShouldRevalidate, O as SessionActivityMonitor, P as formatRelativeAge, Q as TerminalPanel, R as SessionSidebarGroupBy, S as SandboxWorkbenchFileArtifact, T as SandboxWorkbenchOpenUIArtifact, U as SESSION_CREATED_EVENT, V as SessionSidebarProps, W as SessionCreatedDetail, X as RuntimePaneProps, Y as RuntimePane, Z as TerminalLine, _ as FormAudit, a as ApprovalQueue, at as StatusBannerProps, b as SandboxWorkbenchArtifact, c as CalendarView, ct as WorkspacePaneHeader, d as TaskBoardColumn, dt as WorkspaceLayoutProps, et as ContextBadge, f as TaskBoardItem, g as AuditResultsProps, h as AuditResults, i as ApprovalItem, it as StatusBanner, j as ShellShouldRevalidateOptions, k as SessionActivityMonitorProps, l as CalendarViewProps, lt as WorkspacePaneHeaderProps, m as AuditCheck, n as ArtifactPaneProps, nt as StatusBarProps, o as ApprovalQueueProps, ot as DirectoryPane, p as TaskBoardProps, q as dispatchSessionCreated, r as ApprovalConfidenceStat, rt as BannerType, s as CalendarEvent, st as DirectoryPaneProps, t as ArtifactPane, tt as StatusBar, u as TaskBoard, ut as WorkspaceLayout, v as AgentWorkbench, w as SandboxWorkbenchMarkdownArtifact, x as SandboxWorkbenchCustomArtifact, y as SandboxWorkbench, z as SessionSidebarItem } from "./index-CKRaj1pM.js";
1
+ import { $ as TerminalProps, A as ShellShouldRevalidateArgs, B as SessionSidebarLink, C as SandboxWorkbenchLayoutOptions, D as SandboxWorkbenchSessionProps, E as SandboxWorkbenchProps, F as SessionSidebar, G as SessionOptimisticController, H as SessionSidebarVariant, I as SessionSidebarBadge, J as useOptimisticSessionItems, K as UseOptimisticSessionItemsOptions, L as SessionSidebarFilter, M as createShellShouldRevalidate, N as shellShouldRevalidate, O as SessionActivityMonitor, P as formatRelativeAge, Q as TerminalPanel, R as SessionSidebarGroupBy, S as SandboxWorkbenchFileArtifact, T as SandboxWorkbenchOpenUIArtifact, U as SESSION_CREATED_EVENT, V as SessionSidebarProps, W as SessionCreatedDetail, X as RuntimePaneProps, Y as RuntimePane, Z as TerminalLine, _ as FormAudit, a as ApprovalQueue, at as StatusBannerProps, b as SandboxWorkbenchArtifact, c as CalendarView, ct as WorkspacePaneHeader, d as TaskBoardColumn, dt as WorkspaceLayoutProps, et as ContextBadge, f as TaskBoardItem, g as AuditResultsProps, h as AuditResults, i as ApprovalItem, it as StatusBanner, j as ShellShouldRevalidateOptions, k as SessionActivityMonitorProps, l as CalendarViewProps, lt as WorkspacePaneHeaderProps, m as AuditCheck, n as ArtifactPaneProps, nt as StatusBarProps, o as ApprovalQueueProps, ot as DirectoryPane, p as TaskBoardProps, q as dispatchSessionCreated, r as ApprovalConfidenceStat, rt as BannerType, s as CalendarEvent, st as DirectoryPaneProps, t as ArtifactPane, tt as StatusBar, u as TaskBoard, ut as WorkspaceLayout, v as AgentWorkbench, w as SandboxWorkbenchMarkdownArtifact, x as SandboxWorkbenchCustomArtifact, y as SandboxWorkbench, z as SessionSidebarItem } from "./index-iDiLnSoo.js";
2
2
  export { AgentWorkbench, type ApprovalConfidenceStat, type ApprovalItem, ApprovalQueue, type ApprovalQueueProps, ArtifactPane, type ArtifactPaneProps, type AuditCheck, AuditResults, type AuditResultsProps, type BannerType, type CalendarEvent, CalendarView, type CalendarViewProps, type ContextBadge, DirectoryPane, type DirectoryPaneProps, type FormAudit, RuntimePane, type RuntimePaneProps, SESSION_CREATED_EVENT, SandboxWorkbench, type SandboxWorkbenchArtifact, type SandboxWorkbenchCustomArtifact, type SandboxWorkbenchFileArtifact, type SandboxWorkbenchLayoutOptions, type SandboxWorkbenchMarkdownArtifact, type SandboxWorkbenchOpenUIArtifact, type SandboxWorkbenchProps, type SandboxWorkbenchSessionProps, SessionActivityMonitor, type SessionActivityMonitorProps, type SessionCreatedDetail, type SessionOptimisticController, SessionSidebar, type SessionSidebarBadge, type SessionSidebarFilter, type SessionSidebarGroupBy, type SessionSidebarItem, type SessionSidebarLink, type SessionSidebarProps, type SessionSidebarVariant, type ShellShouldRevalidateArgs, type ShellShouldRevalidateOptions, StatusBanner, type StatusBannerProps, StatusBar, type StatusBarProps, TaskBoard, type TaskBoardColumn, type TaskBoardItem, type TaskBoardProps, type TerminalLine, TerminalPanel, type TerminalProps, type UseOptimisticSessionItemsOptions, WorkspaceLayout, type WorkspaceLayoutProps, WorkspacePaneHeader, type WorkspacePaneHeaderProps, createShellShouldRevalidate, dispatchSessionCreated, formatRelativeAge, shellShouldRevalidate, useOptimisticSessionItems };