@tangle-network/sandbox-ui 0.111.2 → 0.113.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.
@@ -325,8 +325,8 @@ function GitStatusBadge({ status }) {
325
325
  }
326
326
  );
327
327
  }
328
- function DiffStatsBadge({ stats }) {
329
- return /* @__PURE__ */ jsxs2("span", { className: "inline-flex items-center gap-1.5 font-mono text-xs", children: [
328
+ function DiffStatsBadge({ stats, className }) {
329
+ return /* @__PURE__ */ jsxs2("span", { className: cn("inline-flex items-center gap-1.5 font-mono text-xs", className), children: [
330
330
  /* @__PURE__ */ jsxs2("span", { className: "text-[var(--code-success,#10B981)]", children: [
331
331
  "+",
332
332
  stats.added
@@ -7280,15 +7280,19 @@ var DIFF_OPTIONS = {
7280
7280
  themeType: "dark",
7281
7281
  stickyHeader: true
7282
7282
  };
7283
- function DiffView({ filename, baseline, current, className }) {
7283
+ function DiffView({ filename, baseline, current, showFileHeader = true, className }) {
7284
7284
  const patch = React7.useMemo(
7285
7285
  () => buildUnifiedPatch(filename, baseline, current),
7286
7286
  [filename, baseline, current]
7287
7287
  );
7288
+ const options = React7.useMemo(
7289
+ () => showFileHeader ? DIFF_OPTIONS : { ...DIFF_OPTIONS, disableFileHeader: true },
7290
+ [showFileHeader]
7291
+ );
7288
7292
  if (!patch) {
7289
7293
  return /* @__PURE__ */ jsx7("div", { className: cn("flex h-full items-center justify-center bg-surface-container", className), children: /* @__PURE__ */ jsx7("p", { className: "text-sm text-muted-foreground", children: "No changes \u2014 baseline and working copy are identical." }) });
7290
7294
  }
7291
- return /* @__PURE__ */ jsx7("div", { className: cn("h-full min-h-0 overflow-auto bg-surface-container text-[13px]", className), children: /* @__PURE__ */ jsx7(PatchDiff, { patch, options: DIFF_OPTIONS }) });
7295
+ return /* @__PURE__ */ jsx7("div", { className: cn("h-full min-h-0 overflow-auto bg-surface-container text-[13px]", className), children: /* @__PURE__ */ jsx7(PatchDiff, { patch, options }) });
7292
7296
  }
7293
7297
 
7294
7298
  // src/workbench/preview-view.tsx
@@ -7511,9 +7515,322 @@ function SandboxArtifactPane({
7511
7515
  );
7512
7516
  }
7513
7517
 
7518
+ // src/workbench/changes-pane.tsx
7519
+ import * as React10 from "react";
7520
+ import { GitBranch, RefreshCw } from "lucide-react";
7521
+ import { Button, Skeleton, Textarea } from "@tangle-network/ui/primitives";
7522
+ import { Fragment as Fragment2, jsx as jsx10, jsxs as jsxs7 } from "react/jsx-runtime";
7523
+ var BORDER = "border-[var(--md3-outline-variant)]";
7524
+ function splitPath(path) {
7525
+ const at = path.lastIndexOf("/");
7526
+ if (at < 0) return { dir: "", base: path };
7527
+ return { dir: path.slice(0, at + 1), base: path.slice(at + 1) };
7528
+ }
7529
+ function resolveContents(file) {
7530
+ const { status, baseline, current } = file;
7531
+ if (status === "added" || status === "untracked") {
7532
+ return current == null ? null : { baseline: baseline ?? "", current };
7533
+ }
7534
+ if (status === "deleted") {
7535
+ return baseline == null ? null : { baseline, current: current ?? "" };
7536
+ }
7537
+ return baseline == null || current == null ? null : { baseline, current };
7538
+ }
7539
+ function errorText(err) {
7540
+ if (err instanceof Error && err.message) return err.message;
7541
+ return String(err);
7542
+ }
7543
+ var SKELETON_ROWS = [0, 1, 2, 3];
7544
+ function ChangesPane({
7545
+ branch,
7546
+ ahead = 0,
7547
+ behind = 0,
7548
+ files,
7549
+ selectedPath,
7550
+ onSelectFile,
7551
+ loading = false,
7552
+ error,
7553
+ onRefresh,
7554
+ onCommit,
7555
+ onPush,
7556
+ busy,
7557
+ onOpenFile,
7558
+ className
7559
+ }) {
7560
+ const idPrefix = React10.useId();
7561
+ const listRef = React10.useRef(null);
7562
+ const rowRefs = React10.useRef(/* @__PURE__ */ new Map());
7563
+ const [message, setMessage] = React10.useState("");
7564
+ const [actionError, setActionError] = React10.useState(null);
7565
+ const [pending, setPending] = React10.useState(null);
7566
+ const inFlight = busy ?? pending;
7567
+ const totals = React10.useMemo(() => {
7568
+ let added = 0;
7569
+ let removed = 0;
7570
+ for (const f of files) {
7571
+ added += f.additions;
7572
+ removed += f.deletions;
7573
+ }
7574
+ return { added, removed };
7575
+ }, [files]);
7576
+ const selectedIndex = selectedPath == null ? -1 : files.findIndex((f) => f.path === selectedPath);
7577
+ const selected = selectedIndex >= 0 ? files[selectedIndex] : void 0;
7578
+ React10.useEffect(() => {
7579
+ const list = listRef.current;
7580
+ if (!list || selected == null) return;
7581
+ if (!list.contains(document.activeElement)) return;
7582
+ rowRefs.current.get(selected.path)?.focus();
7583
+ }, [selected]);
7584
+ const handleListKeyDown = React10.useCallback(
7585
+ (event) => {
7586
+ if (files.length === 0 || !onSelectFile) return;
7587
+ const last = files.length - 1;
7588
+ let next = null;
7589
+ switch (event.key) {
7590
+ case "ArrowDown":
7591
+ next = selectedIndex < 0 ? 0 : Math.min(selectedIndex + 1, last);
7592
+ break;
7593
+ case "ArrowUp":
7594
+ next = selectedIndex < 0 ? last : Math.max(selectedIndex - 1, 0);
7595
+ break;
7596
+ case "Home":
7597
+ next = 0;
7598
+ break;
7599
+ case "End":
7600
+ next = last;
7601
+ break;
7602
+ case "Enter":
7603
+ case " ":
7604
+ next = selectedIndex < 0 ? 0 : selectedIndex;
7605
+ break;
7606
+ default:
7607
+ return;
7608
+ }
7609
+ event.preventDefault();
7610
+ const file = files[next];
7611
+ if (file) onSelectFile(file.path);
7612
+ },
7613
+ [files, onSelectFile, selectedIndex]
7614
+ );
7615
+ const runCommit = React10.useCallback(async () => {
7616
+ const text = message.trim();
7617
+ if (!onCommit || !text || inFlight) return;
7618
+ setActionError(null);
7619
+ setPending("commit");
7620
+ try {
7621
+ await onCommit(text);
7622
+ setMessage("");
7623
+ } catch (err) {
7624
+ setActionError(errorText(err));
7625
+ } finally {
7626
+ setPending(null);
7627
+ }
7628
+ }, [message, onCommit, inFlight]);
7629
+ const runPush = React10.useCallback(async () => {
7630
+ if (!onPush || inFlight) return;
7631
+ setActionError(null);
7632
+ setPending("push");
7633
+ try {
7634
+ await onPush();
7635
+ } catch (err) {
7636
+ setActionError(errorText(err));
7637
+ } finally {
7638
+ setPending(null);
7639
+ }
7640
+ }, [onPush, inFlight]);
7641
+ const handleMessageKeyDown = React10.useCallback(
7642
+ (event) => {
7643
+ if (event.key === "Enter" && (event.metaKey || event.ctrlKey)) {
7644
+ event.preventDefault();
7645
+ void runCommit();
7646
+ }
7647
+ },
7648
+ [runCommit]
7649
+ );
7650
+ const canCommit = files.length > 0 && message.trim().length > 0 && inFlight == null;
7651
+ const canPush = ahead > 0 && inFlight == null;
7652
+ const contents = React10.useMemo(() => selected ? resolveContents(selected) : null, [selected]);
7653
+ const stats = React10.useMemo(
7654
+ () => contents ? computeDiffStats(contents.baseline, contents.current) : void 0,
7655
+ [contents]
7656
+ );
7657
+ const patch = React10.useMemo(
7658
+ () => selected && contents ? buildUnifiedPatch(selected.path, contents.baseline, contents.current) : void 0,
7659
+ [selected, contents]
7660
+ );
7661
+ const showList = !loading && files.length > 0;
7662
+ const showEmpty = !loading && files.length === 0 && !error;
7663
+ return /* @__PURE__ */ jsxs7("div", { className: cn("flex h-full min-h-0 flex-col text-foreground", className), children: [
7664
+ /* @__PURE__ */ jsxs7(
7665
+ "div",
7666
+ {
7667
+ className: cn(
7668
+ "flex min-h-[38px] shrink-0 items-center gap-2 border-b bg-surface-container-low px-3 py-1",
7669
+ BORDER
7670
+ ),
7671
+ children: [
7672
+ /* @__PURE__ */ jsx10(GitBranch, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground", "aria-hidden": true }),
7673
+ loading && branch == null ? /* @__PURE__ */ jsx10(Skeleton, { className: "h-4 w-24 rounded-full" }) : branch == null ? /* @__PURE__ */ jsx10("span", { className: "text-xs text-muted-foreground", children: "no commits yet" }) : /* @__PURE__ */ jsx10("span", { className: "truncate rounded-full bg-surface-container-high px-2 py-0.5 font-mono text-xs text-foreground", children: branch }),
7674
+ (ahead > 0 || behind > 0) && /* @__PURE__ */ jsxs7("span", { className: "flex items-center gap-1.5 font-mono text-xs text-muted-foreground", children: [
7675
+ ahead > 0 && /* @__PURE__ */ jsxs7("span", { "aria-label": `${ahead} ahead`, children: [
7676
+ "\u2191",
7677
+ ahead
7678
+ ] }),
7679
+ behind > 0 && /* @__PURE__ */ jsxs7("span", { "aria-label": `${behind} behind`, children: [
7680
+ "\u2193",
7681
+ behind
7682
+ ] })
7683
+ ] }),
7684
+ /* @__PURE__ */ jsxs7("div", { className: "ml-auto flex items-center gap-3", children: [
7685
+ files.length > 0 && /* @__PURE__ */ jsx10(DiffStatsBadge, { stats: totals }),
7686
+ onRefresh && /* @__PURE__ */ jsx10(
7687
+ "button",
7688
+ {
7689
+ type: "button",
7690
+ onClick: onRefresh,
7691
+ "aria-label": "Refresh",
7692
+ className: "rounded-md p-1 text-muted-foreground transition-colors hover:bg-surface-container-high hover:text-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-primary/60",
7693
+ children: /* @__PURE__ */ jsx10(RefreshCw, { className: cn("h-3.5 w-3.5", loading && "animate-spin") })
7694
+ }
7695
+ )
7696
+ ] })
7697
+ ]
7698
+ }
7699
+ ),
7700
+ /* @__PURE__ */ jsxs7("div", { className: cn("flex max-h-[40%] shrink-0 flex-col border-b", BORDER), "aria-busy": loading || void 0, children: [
7701
+ error && /* @__PURE__ */ jsx10("p", { role: "alert", className: "px-3 py-2 text-xs text-[var(--surface-danger-text)]", children: error }),
7702
+ loading && /* @__PURE__ */ jsxs7("div", { className: "space-y-1 px-3 py-2", "data-testid": "changes-skeleton", children: [
7703
+ /* @__PURE__ */ jsx10("span", { className: "sr-only", children: "Loading changes\u2026" }),
7704
+ SKELETON_ROWS.map((row) => /* @__PURE__ */ jsx10(Skeleton, { className: "h-6 w-full" }, row))
7705
+ ] }),
7706
+ showEmpty && /* @__PURE__ */ jsx10("p", { className: "px-3 py-6 text-center text-xs text-muted-foreground", children: "No changes in the working tree." }),
7707
+ showList && /* @__PURE__ */ jsx10(
7708
+ "ul",
7709
+ {
7710
+ ref: listRef,
7711
+ role: "listbox",
7712
+ "aria-label": "Changed files",
7713
+ "aria-activedescendant": selected ? `${idPrefix}-${selectedIndex}` : void 0,
7714
+ onKeyDown: handleListKeyDown,
7715
+ className: "min-h-0 overflow-y-auto py-1 focus:outline-none",
7716
+ children: files.map((file, index) => {
7717
+ const isSelected = index === selectedIndex;
7718
+ const { dir, base } = splitPath(file.path);
7719
+ const tabbable = isSelected || selectedIndex < 0 && index === 0;
7720
+ return /* @__PURE__ */ jsxs7(
7721
+ "li",
7722
+ {
7723
+ id: `${idPrefix}-${index}`,
7724
+ ref: (el) => {
7725
+ if (el) rowRefs.current.set(file.path, el);
7726
+ else rowRefs.current.delete(file.path);
7727
+ },
7728
+ role: "option",
7729
+ "aria-selected": isSelected,
7730
+ tabIndex: tabbable ? 0 : -1,
7731
+ onClick: () => onSelectFile?.(file.path),
7732
+ className: cn(
7733
+ "flex cursor-pointer items-center gap-2 px-3 py-1.5 text-xs transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-inset focus-visible:ring-primary/60",
7734
+ isSelected ? "bg-surface-container-high" : "hover:bg-surface-container"
7735
+ ),
7736
+ children: [
7737
+ /* @__PURE__ */ jsxs7("span", { className: "min-w-0 flex-1 truncate font-mono", title: file.path, children: [
7738
+ dir && /* @__PURE__ */ jsx10("span", { className: "text-muted-foreground", children: dir }),
7739
+ /* @__PURE__ */ jsx10("span", { className: "text-foreground", children: base })
7740
+ ] }),
7741
+ /* @__PURE__ */ jsx10(GitStatusBadge, { status: file.status }),
7742
+ /* @__PURE__ */ jsx10(
7743
+ DiffStatsBadge,
7744
+ {
7745
+ stats: { added: file.additions, removed: file.deletions },
7746
+ className: "w-[5.5rem] justify-end tabular-nums"
7747
+ }
7748
+ )
7749
+ ]
7750
+ },
7751
+ file.path
7752
+ );
7753
+ })
7754
+ }
7755
+ )
7756
+ ] }),
7757
+ /* @__PURE__ */ jsx10("div", { className: "flex min-h-0 flex-1 flex-col", children: selected ? /* @__PURE__ */ jsxs7(Fragment2, { children: [
7758
+ /* @__PURE__ */ jsx10(PanelHeader, { filename: selected.path, gitStatus: selected.status, stats, copyText: patch, children: onOpenFile && /* @__PURE__ */ jsx10(
7759
+ Button,
7760
+ {
7761
+ type: "button",
7762
+ variant: "outline",
7763
+ size: "sm",
7764
+ className: "h-7 px-2",
7765
+ onClick: () => onOpenFile(selected.path),
7766
+ children: "Open"
7767
+ }
7768
+ ) }),
7769
+ contents ? /* @__PURE__ */ jsx10(
7770
+ DiffView,
7771
+ {
7772
+ filename: selected.path,
7773
+ baseline: contents.baseline,
7774
+ current: contents.current,
7775
+ showFileHeader: false,
7776
+ className: "flex-1"
7777
+ }
7778
+ ) : /* @__PURE__ */ jsx10("p", { className: "px-3 py-3 text-xs text-muted-foreground", role: "status", children: "Loading diff\u2026" })
7779
+ ] }) : showList && /* @__PURE__ */ jsx10("p", { className: "px-3 py-3 text-xs text-muted-foreground", children: "Select a file to read its diff." }) }),
7780
+ (onCommit || onPush) && /* @__PURE__ */ jsxs7("div", { className: cn("shrink-0 space-y-2 border-t bg-surface-container-low p-3", BORDER), children: [
7781
+ onCommit && /* @__PURE__ */ jsx10(
7782
+ Textarea,
7783
+ {
7784
+ "aria-label": "Commit message",
7785
+ placeholder: "Commit message",
7786
+ rows: 2,
7787
+ value: message,
7788
+ onChange: (event) => setMessage(event.target.value),
7789
+ onKeyDown: handleMessageKeyDown,
7790
+ disabled: inFlight != null,
7791
+ className: "min-h-[3.5rem] resize-none px-3 py-2 text-xs"
7792
+ }
7793
+ ),
7794
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
7795
+ onCommit && /* @__PURE__ */ jsx10(
7796
+ Button,
7797
+ {
7798
+ type: "button",
7799
+ size: "sm",
7800
+ disabled: !canCommit,
7801
+ loading: inFlight === "commit",
7802
+ onClick: () => void runCommit(),
7803
+ children: "Commit"
7804
+ }
7805
+ ),
7806
+ onPush && /* @__PURE__ */ jsxs7(
7807
+ Button,
7808
+ {
7809
+ type: "button",
7810
+ size: "sm",
7811
+ variant: "secondary",
7812
+ disabled: !canPush,
7813
+ loading: inFlight === "push",
7814
+ onClick: () => void runPush(),
7815
+ children: [
7816
+ "Push",
7817
+ ahead > 0 && /* @__PURE__ */ jsxs7("span", { className: "font-mono text-muted-foreground", children: [
7818
+ "\u2191",
7819
+ ahead
7820
+ ] })
7821
+ ]
7822
+ }
7823
+ )
7824
+ ] }),
7825
+ actionError && /* @__PURE__ */ jsx10("p", { role: "alert", className: "text-xs text-[var(--surface-danger-text)]", children: actionError })
7826
+ ] })
7827
+ ] });
7828
+ }
7829
+
7514
7830
  export {
7515
7831
  PillTabs,
7516
7832
  GitStatusBadge,
7833
+ DiffStatsBadge,
7517
7834
  PanelHeader,
7518
7835
  resolveLanguage,
7519
7836
  BRAND_PRISM_THEME,
@@ -7524,5 +7841,6 @@ export {
7524
7841
  buildUnifiedPatch,
7525
7842
  DiffView,
7526
7843
  PreviewView,
7527
- SandboxArtifactPane
7844
+ SandboxArtifactPane,
7845
+ ChangesPane
7528
7846
  };
package/dist/globals.css CHANGED
@@ -368,6 +368,9 @@
368
368
  .top-full {
369
369
  top: 100%;
370
370
  }
371
+ .-right-0\.5 {
372
+ right: calc(var(--spacing) * -0.5);
373
+ }
371
374
  .-right-1 {
372
375
  right: calc(var(--spacing) * -1);
373
376
  }
@@ -389,6 +392,9 @@
389
392
  .right-4 {
390
393
  right: calc(var(--spacing) * 4);
391
394
  }
395
+ .-bottom-0\.5 {
396
+ bottom: calc(var(--spacing) * -0.5);
397
+ }
392
398
  .bottom-0 {
393
399
  bottom: 0px;
394
400
  }
@@ -847,6 +853,9 @@
847
853
  .h-\[640px\] {
848
854
  height: 640px;
849
855
  }
856
+ .h-\[720px\] {
857
+ height: 720px;
858
+ }
850
859
  .h-\[var\(--avatar-size\)\] {
851
860
  height: var(--avatar-size);
852
861
  }
@@ -898,6 +907,9 @@
898
907
  .max-h-96 {
899
908
  max-height: calc(var(--spacing) * 96);
900
909
  }
910
+ .max-h-\[40\%\] {
911
+ max-height: 40%;
912
+ }
901
913
  .max-h-\[70vh\] {
902
914
  max-height: 70vh;
903
915
  }
@@ -913,12 +925,18 @@
913
925
  .min-h-0 {
914
926
  min-height: 0px;
915
927
  }
928
+ .min-h-8 {
929
+ min-height: calc(var(--spacing) * 8);
930
+ }
916
931
  .min-h-24 {
917
932
  min-height: calc(var(--spacing) * 24);
918
933
  }
919
934
  .min-h-\[2px\] {
920
935
  min-height: 2px;
921
936
  }
937
+ .min-h-\[3\.5rem\] {
938
+ min-height: 3.5rem;
939
+ }
922
940
  .min-h-\[6rem\] {
923
941
  min-height: 6rem;
924
942
  }
@@ -1102,6 +1120,9 @@
1102
1120
  .w-\[3px\] {
1103
1121
  width: 3px;
1104
1122
  }
1123
+ .w-\[5\.5rem\] {
1124
+ width: 5.5rem;
1125
+ }
1105
1126
  .w-\[17px\] {
1106
1127
  width: 17px;
1107
1128
  }
@@ -1135,6 +1156,9 @@
1135
1156
  .w-\[420px\] {
1136
1157
  width: 420px;
1137
1158
  }
1159
+ .w-\[440px\] {
1160
+ width: 440px;
1161
+ }
1138
1162
  .w-\[480px\] {
1139
1163
  width: 480px;
1140
1164
  }
@@ -2691,6 +2715,9 @@
2691
2715
  .px-\[var\(--tool-card-px\)\] {
2692
2716
  padding-inline: var(--tool-card-px);
2693
2717
  }
2718
+ .py-0 {
2719
+ padding-block: 0px;
2720
+ }
2694
2721
  .py-0\.5 {
2695
2722
  padding-block: calc(var(--spacing) * 0.5);
2696
2723
  }
@@ -2796,6 +2823,9 @@
2796
2823
  .pr-2\.5 {
2797
2824
  padding-right: calc(var(--spacing) * 2.5);
2798
2825
  }
2826
+ .pr-3 {
2827
+ padding-right: calc(var(--spacing) * 3);
2828
+ }
2799
2829
  .pr-8 {
2800
2830
  padding-right: calc(var(--spacing) * 8);
2801
2831
  }
@@ -2965,6 +2995,10 @@
2965
2995
  --tw-leading: calc(var(--spacing) * 4);
2966
2996
  line-height: calc(var(--spacing) * 4);
2967
2997
  }
2998
+ .leading-5 {
2999
+ --tw-leading: calc(var(--spacing) * 5);
3000
+ line-height: calc(var(--spacing) * 5);
3001
+ }
2968
3002
  .leading-6 {
2969
3003
  --tw-leading: calc(var(--spacing) * 6);
2970
3004
  line-height: calc(var(--spacing) * 6);
@@ -3300,6 +3334,12 @@
3300
3334
  color: color-mix(in oklab, var(--color-foreground) 70%, transparent);
3301
3335
  }
3302
3336
  }
3337
+ .text-foreground\/75 {
3338
+ color: color-mix(in srgb, hsl(var(--foreground)) 75%, transparent);
3339
+ @supports (color: color-mix(in lab, red, red)) {
3340
+ color: color-mix(in oklab, var(--color-foreground) 75%, transparent);
3341
+ }
3342
+ }
3303
3343
  .text-foreground\/80 {
3304
3344
  color: color-mix(in srgb, hsl(var(--foreground)) 80%, transparent);
3305
3345
  @supports (color: color-mix(in lab, red, red)) {
@@ -3471,6 +3511,10 @@
3471
3511
  --tw-shadow: 0 1px 3px 0 var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 1px 2px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
3472
3512
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
3473
3513
  }
3514
+ .shadow-\[0_1px_2px_rgba\(0\,0\,0\,0\.2\)\] {
3515
+ --tw-shadow: 0 1px 2px var(--tw-shadow-color, rgba(0,0,0,0.2));
3516
+ box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
3517
+ }
3474
3518
  .shadow-\[0_1px_2px_rgba\(15\,23\,42\,0\.04\)\] {
3475
3519
  --tw-shadow: 0 1px 2px var(--tw-shadow-color, rgba(15,23,42,0.04));
3476
3520
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -3724,6 +3768,9 @@
3724
3768
  border-color: color-mix(in oklab, var(--color-primary) 40%, transparent);
3725
3769
  }
3726
3770
  }
3771
+ .group-hover\:text-foreground:is(:where(.group):hover *) {
3772
+ color: var(--color-foreground);
3773
+ }
3727
3774
  .group-hover\:text-foreground\/40:is(:where(.group):hover *) {
3728
3775
  color: color-mix(in srgb, hsl(var(--foreground)) 40%, transparent);
3729
3776
  }
@@ -4124,6 +4171,9 @@
4124
4171
  .hover\:bg-red-700:hover {
4125
4172
  background-color: var(--color-red-700);
4126
4173
  }
4174
+ .hover\:bg-surface-container:hover {
4175
+ background-color: var(--color-surface-container);
4176
+ }
4127
4177
  .hover\:bg-surface-container-high:hover {
4128
4178
  background-color: var(--color-surface-container-high);
4129
4179
  }
@@ -4327,6 +4377,9 @@
4327
4377
  background-color: color-mix(in oklab, var(--color-primary) 40%, transparent);
4328
4378
  }
4329
4379
  }
4380
+ .focus-visible\:bg-surface-container:focus-visible {
4381
+ background-color: var(--color-surface-container);
4382
+ }
4330
4383
  .focus-visible\:bg-transparent:focus-visible {
4331
4384
  background-color: transparent;
4332
4385
  }
@@ -4696,6 +4749,9 @@
4696
4749
  .lg\:items-center {
4697
4750
  align-items: center;
4698
4751
  }
4752
+ .lg\:p-0 {
4753
+ padding: 0px;
4754
+ }
4699
4755
  .lg\:p-4 {
4700
4756
  padding: calc(var(--spacing) * 4);
4701
4757
  }
package/dist/index.d.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  export { ArtifactPane, ArtifactPaneProps, Avatar, AvatarFallback, AvatarImage, Badge, BadgeProps, Button, ButtonProps, Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, CodeBlock, CodeBlockProps, CopyButton, Dialog, DialogClose, DialogContent, DialogDescription, DialogFooter, DialogHeader, DialogOverlay, DialogPortal, DialogTitle, DialogTrigger, DropZone, DropZoneProps, DropdownMenu, DropdownMenuCheckboxItem, DropdownMenuContent, DropdownMenuGroup, DropdownMenuItem, DropdownMenuLabel, DropdownMenuPortal, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator, DropdownMenuShortcut, DropdownMenuSub, DropdownMenuSubContent, DropdownMenuSubTrigger, DropdownMenuTrigger, EmptyState, EmptyStateProps, FilterField, FilterFieldProps, InlineCode, InlineCodeProps, Input, InputProps, Label, Metric, MetricProps, MetricStrip, MetricStripProps, Progress, SegmentedControl, SegmentedControlOption, SegmentedControlProps, Select, SelectContent, SelectGroup, SelectItem, SelectLabel, SelectScrollDownButton, SelectScrollUpButton, SelectSeparator, SelectTrigger, SelectValue, SidebarDropZone, SidebarDropZoneProps, Skeleton, SkeletonCard, SkeletonTable, StatCard, StatCardProps, StatusPill, StatusPillProps, StatusTone, Switch, Table, TableBody, TableCaption, TableCell, TableFooter, TableHead, TableHeader, TableRow, Tabs, TabsContent, TabsList, TabsTrigger, TerminalDisplay, TerminalCursor as TerminalDisplayCursor, TerminalInput as TerminalDisplayInput, TerminalLine as TerminalDisplayLine, Textarea, TextareaProps, ThemeToggle, Toast, ToastContainer, ToastProvider, Toolbar, ToolbarProps, UploadFile, UploadProgress, UploadProgressProps, badgeVariants, buttonVariants, useTheme, useToast } from '@tangle-network/ui/primitives';
2
2
  export { L as Logo, a as LogoProps, T as TangleKnot } from './logo-CaIvk3J1.js';
3
3
  export { CodeBlock as CodeBlockDisplay, Markdown, MarkdownProps } from '@tangle-network/ui/markdown';
4
- export { AgentWorkbench, ApprovalConfidenceStat, ApprovalItem, ApprovalQueue, ApprovalQueueProps, AuditCheck, AuditResults, AuditResultsProps, BannerType, CalendarEvent, CalendarView, CalendarViewProps, ContextBadge, DirectoryPane, DirectoryPaneProps, FormAudit, RuntimePane, RuntimePaneProps, SESSION_CREATED_EVENT, SandboxWorkbench, SandboxWorkbenchArtifact, SandboxWorkbenchCustomArtifact, SandboxWorkbenchFileArtifact, SandboxWorkbenchLayoutOptions, SandboxWorkbenchMarkdownArtifact, SandboxWorkbenchOpenUIArtifact, SandboxWorkbenchProps, SandboxWorkbenchSessionProps, SessionActivityMonitor, SessionActivityMonitorProps, SessionCreatedDetail, SessionOptimisticController, SessionSidebar, SessionSidebarBadge, SessionSidebarFilter, SessionSidebarItem, SessionSidebarLink, SessionSidebarProps, ShellShouldRevalidateArgs, ShellShouldRevalidateOptions, StatusBanner, StatusBannerProps, StatusBar, StatusBarProps, TaskBoard, TaskBoardColumn, TaskBoardItem, TaskBoardProps, TerminalLine, TerminalPanel, TerminalProps, UseOptimisticSessionItemsOptions, WorkspaceLayout, WorkspaceLayoutProps, WorkspacePaneHeader, WorkspacePaneHeaderProps, createShellShouldRevalidate, dispatchSessionCreated, shellShouldRevalidate, useOptimisticSessionItems } from './workspace.js';
5
- export { ArtifactView, BRAND_PRISM_THEME, CodeSurface, CodeSurfaceProps, CodeView, CodeViewProps, DiffStats, DiffView, DiffViewProps, FileBreadcrumb, FileBreadcrumbProps, GitStatusBadge, PanelHeader, PanelHeaderProps, PillTabItem, PillTabs, PillTabsProps, PreviewView, PreviewViewProps, SandboxArtifact, SandboxArtifactPane, SandboxArtifactPaneProps, SandboxArtifactTerminal, buildUnifiedPatch, computeDiffStats, resolveLanguage } from './workbench.js';
4
+ export { AgentWorkbench, ApprovalConfidenceStat, ApprovalItem, ApprovalQueue, ApprovalQueueProps, AuditCheck, AuditResults, AuditResultsProps, BannerType, CalendarEvent, CalendarView, CalendarViewProps, ContextBadge, DirectoryPane, DirectoryPaneProps, FormAudit, RuntimePane, RuntimePaneProps, SESSION_CREATED_EVENT, SandboxWorkbench, SandboxWorkbenchArtifact, SandboxWorkbenchCustomArtifact, SandboxWorkbenchFileArtifact, SandboxWorkbenchLayoutOptions, SandboxWorkbenchMarkdownArtifact, SandboxWorkbenchOpenUIArtifact, SandboxWorkbenchProps, SandboxWorkbenchSessionProps, SessionActivityMonitor, SessionActivityMonitorProps, SessionCreatedDetail, SessionOptimisticController, SessionSidebar, SessionSidebarBadge, SessionSidebarFilter, SessionSidebarGroupBy, SessionSidebarItem, SessionSidebarLink, SessionSidebarProps, SessionSidebarVariant, ShellShouldRevalidateArgs, ShellShouldRevalidateOptions, StatusBanner, StatusBannerProps, StatusBar, StatusBarProps, TaskBoard, TaskBoardColumn, TaskBoardItem, TaskBoardProps, TerminalLine, TerminalPanel, TerminalProps, UseOptimisticSessionItemsOptions, WorkspaceLayout, WorkspaceLayoutProps, WorkspacePaneHeader, WorkspacePaneHeaderProps, createShellShouldRevalidate, dispatchSessionCreated, formatRelativeAge, shellShouldRevalidate, useOptimisticSessionItems } from './workspace.js';
5
+ export { ArtifactView, BRAND_PRISM_THEME, ChangedFile, ChangesPane, ChangesPaneProps, CodeSurface, CodeSurfaceProps, CodeView, CodeViewProps, DiffStats, DiffStatsBadge, DiffView, DiffViewProps, FileBreadcrumb, FileBreadcrumbProps, GitStatusBadge, PanelHeader, PanelHeaderProps, PillTabItem, PillTabs, PillTabsProps, PreviewView, PreviewViewProps, SandboxArtifact, SandboxArtifactPane, SandboxArtifactPaneProps, SandboxArtifactTerminal, buildUnifiedPatch, computeDiffStats, resolveLanguage } from './workbench.js';
6
6
  export { OpenUIAction, OpenUIActionsNode, OpenUIArtifactRenderer, OpenUIArtifactRendererProps, OpenUIBadgeNode, OpenUICardNode, OpenUICodeNode, OpenUIComponentNode, OpenUIGridNode, OpenUIHeadingNode, OpenUIKeyValueNode, OpenUIMarkdownNode, OpenUIPrimitive, OpenUISeparatorNode, OpenUIStackNode, OpenUIStatNode, OpenUITableNode, OpenUITextNode } from '@tangle-network/ui/openui';
7
7
  export { AgentTimeline, AgentTimelineArtifactItem, AgentTimelineCustomItem, AgentTimelineItem, AgentTimelineMessageItem, AgentTimelineProps, AgentTimelineStatusItem, AgentTimelineTone, AgentTimelineToolGroupItem, AgentTimelineToolItem, ChatContainer, ChatContainerProps, ChatMessage, ChatMessageProps, MessageList, MessageListProps, MessageRole, ThinkingIndicator, ThinkingIndicatorProps, UserMessage, UserMessageProps } from '@tangle-network/ui/chat';
8
8
  export { AgentProfileCapability, AgentProfileDraft, AgentProfileOption, AgentProfilePicker, AgentProfilePickerProps, ArtifactAgentDock, ArtifactAgentDockProps, ArtifactAgentDockTransport, ArtifactDockMessage, ArtifactDockStreamEvent, ArtifactKind, ArtifactScope, DEFAULT_REASONING_LEVEL_OPTIONS, HARNESS_REASONING_OPTIONS, ReasoningLevel, ReasoningLevelOption, ReasoningLevelPicker, ReasoningLevelPickerProps, createFetchTransport } from './chat.js';
@@ -25,6 +25,7 @@ export { AgentBranding, CustomToolRenderer, DisplayVariant, FinalTextPart, Group
25
25
  export { Session } from './types.js';
26
26
  export { TOOL_CATEGORY_ICONS, cn, copyText, formatBytes, formatDuration, formatUptime, getToolCategory, getToolDisplayMetadata, getToolErrorText, timeAgo, truncateText } from '@tangle-network/ui/utils';
27
27
  import 'react';
28
+ import 'lucide-react';
28
29
  import '@radix-ui/react-dropdown-menu';
29
30
  import '@tanstack/react-query';
30
31
  import '@tangle-network/ui/sdk-hooks';
package/dist/index.js CHANGED
@@ -130,13 +130,16 @@ import {
130
130
  WorkspacePaneHeader,
131
131
  createShellShouldRevalidate,
132
132
  dispatchSessionCreated,
133
+ formatRelativeAge,
133
134
  shellShouldRevalidate,
134
135
  useOptimisticSessionItems
135
- } from "./chunk-D5VXCWUG.js";
136
+ } from "./chunk-2Q3KDQX7.js";
136
137
  import {
137
138
  BRAND_PRISM_THEME,
139
+ ChangesPane,
138
140
  CodeSurface,
139
141
  CodeView,
142
+ DiffStatsBadge,
140
143
  DiffView,
141
144
  FileBreadcrumb,
142
145
  GitStatusBadge,
@@ -147,7 +150,7 @@ import {
147
150
  buildUnifiedPatch,
148
151
  computeDiffStats,
149
152
  resolveLanguage
150
- } from "./chunk-5M67IFVI.js";
153
+ } from "./chunk-ISTJTUHJ.js";
151
154
  import {
152
155
  FileArtifactPane,
153
156
  FilePreview,
@@ -383,6 +386,7 @@ export {
383
386
  CardFooter,
384
387
  CardHeader,
385
388
  CardTitle,
389
+ ChangesPane,
386
390
  ChatContainer,
387
391
  ChatMessage,
388
392
  ClusterStatusBar,
@@ -406,6 +410,7 @@ export {
406
410
  DialogTitle,
407
411
  DialogTrigger,
408
412
  DiffPreview,
413
+ DiffStatsBadge,
409
414
  DiffView,
410
415
  DirectoryPane,
411
416
  DropZone,
@@ -604,6 +609,7 @@ export {
604
609
  formatBytes,
605
610
  formatDuration,
606
611
  formatPrice,
612
+ formatRelativeAge,
607
613
  formatUptime,
608
614
  getActiveSession,
609
615
  getAllActiveSessions,