@tangle-network/sandbox-ui 0.69.0 → 0.71.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/chat.d.ts CHANGED
@@ -230,16 +230,21 @@ interface AgentSessionControlsProps {
230
230
  * existing behavior. `"gear"` collapses them behind a single compact gear
231
231
  * button whose menu opens up-and-left, for right-anchored copilots where
232
232
  * the composer is tight. Nested model/harness/effort menus render adjacent
233
- * on the left of the gear menu.
233
+ * on the left of the gear menu. `"combined"` is the gear layout with a
234
+ * labeled trigger instead of the anonymous icon: the button summarizes the
235
+ * current selection as text (`harness · model · effort`) so the choice stays
236
+ * visible without opening the menu — for a composer that wants one compact
237
+ * agent control it can read at a glance.
234
238
  */
235
- layout?: "inline" | "gear";
239
+ layout?: "inline" | "gear" | "combined";
236
240
  /**
237
- * Where the inline pickers open. `"auto"` (default) keeps Radix's
238
- * collision-aware behavior: the menus open downward but flip up when the
239
- * composer is docked at the bottom of the viewport. `"down"` pins them open
240
- * downward — for a composer floating in open space (e.g. a centered new-chat
241
- * surface) where flipping up would cover the heading. Only affects the
242
- * `"inline"` layout; the gear menu is unchanged.
241
+ * Where the pickers open. `"auto"` (default) keeps Radix's collision-aware
242
+ * behavior: the menus open downward but flip up when the composer is docked
243
+ * at the bottom of the viewport. `"down"` pins them open downward — for a
244
+ * composer floating in open space (e.g. a centered new-chat surface) where
245
+ * flipping up would cover the heading. Honored by the `"inline"` strip (its
246
+ * nested pickers) and by the `"combined"` panel (which opens downward instead
247
+ * of upward); the `"gear"` menu keeps its own placement.
243
248
  */
244
249
  menuPlacement?: "auto" | "down";
245
250
  }
package/dist/chat.js CHANGED
@@ -17,9 +17,9 @@ import {
17
17
  modelProvider,
18
18
  snapHarnessToModel,
19
19
  snapModelToHarness
20
- } from "./chunk-XL573ZOV.js";
21
- import "./chunk-HU4B2M4K.js";
22
- import "./chunk-SF6LPMMN.js";
20
+ } from "./chunk-UQXDIQWD.js";
21
+ import "./chunk-IWIZ7RZE.js";
22
+ import "./chunk-L62ZT6RS.js";
23
23
  import "./chunk-EI44GEQ5.js";
24
24
  import "./chunk-U67V476Y.js";
25
25
  export {
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  moonshot_default
3
- } from "./chunk-SF6LPMMN.js";
3
+ } from "./chunk-L62ZT6RS.js";
4
4
  import {
5
5
  cn
6
6
  } from "./chunk-EI44GEQ5.js";
@@ -360,7 +360,7 @@ function ModelPicker({
360
360
  children: [
361
361
  currentIdentity ? /* @__PURE__ */ jsx2(ModelBrandStack, { identity: currentIdentity, size: "sm" }) : /* @__PURE__ */ jsx2(Sparkles, { className: "h-3 w-3 text-muted-foreground" }),
362
362
  /* @__PURE__ */ jsx2("span", { className: "truncate max-w-[160px]", children: currentLabel || placeholder }),
363
- /* @__PURE__ */ jsx2(ChevronDown, { className: "h-3 w-3 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
363
+ /* @__PURE__ */ jsx2(ChevronDown, { className: "ml-auto h-3 w-3 shrink-0 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
364
364
  ]
365
365
  }
366
366
  ) : /* @__PURE__ */ jsxs2(
@@ -793,5 +793,8 @@ export {
793
793
  DEFAULT_FEATURED_MODEL_IDS,
794
794
  formatPricing,
795
795
  formatContext,
796
- ModelPicker
796
+ resolveModelBrandIdentity,
797
+ stripBrandPrefix,
798
+ ModelPicker,
799
+ ModelBrandStack
797
800
  };
@@ -2,11 +2,14 @@ import {
2
2
  HARNESS_OPTIONS,
3
3
  HarnessLogo,
4
4
  chatCapableHarnesses
5
- } from "./chunk-HU4B2M4K.js";
5
+ } from "./chunk-IWIZ7RZE.js";
6
6
  import {
7
+ ModelBrandStack,
7
8
  ModelPicker,
8
- canonicalModelId
9
- } from "./chunk-SF6LPMMN.js";
9
+ canonicalModelId,
10
+ resolveModelBrandIdentity,
11
+ stripBrandPrefix
12
+ } from "./chunk-L62ZT6RS.js";
10
13
  import {
11
14
  cn
12
15
  } from "./chunk-EI44GEQ5.js";
@@ -110,9 +113,9 @@ function ReasoningLevelPicker({
110
113
  ),
111
114
  "aria-label": "Reasoning level",
112
115
  children: [
113
- /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5 text-muted-foreground" }),
116
+ /* @__PURE__ */ jsx(Brain, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" }),
114
117
  /* @__PURE__ */ jsx("span", { children: label }),
115
- /* @__PURE__ */ jsx(ChevronDown, { className: "h-3.5 w-3.5 text-muted-foreground" })
118
+ /* @__PURE__ */ jsx(ChevronDown, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-muted-foreground" })
116
119
  ]
117
120
  }
118
121
  ) }),
@@ -470,7 +473,7 @@ function ProfileForm({
470
473
  }
471
474
 
472
475
  // src/chat/agent-session-controls.tsx
473
- import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
476
+ import { Fragment as Fragment2, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
474
477
  function selectorIgnoreNote(harness) {
475
478
  const ignoresModel = !harnessHonorsModel(harness);
476
479
  const ignoresEffort = !harnessHonorsEffort(harness);
@@ -592,7 +595,8 @@ function HarnessDropdown({
592
595
  newChatLabel,
593
596
  side = "bottom",
594
597
  align = "start",
595
- avoidCollisions
598
+ avoidCollisions,
599
+ triggerClassName
596
600
  }) {
597
601
  const allowed = new Set(
598
602
  available ?? HARNESS_OPTIONS.map((h) => h.type)
@@ -624,13 +628,14 @@ function HarnessDropdown({
624
628
  "text-xs font-medium text-foreground shadow-sm transition-colors",
625
629
  "hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
626
630
  "data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high",
627
- "disabled:cursor-not-allowed disabled:opacity-60"
631
+ "disabled:cursor-not-allowed disabled:opacity-60",
632
+ triggerClassName
628
633
  ),
629
634
  "aria-label": "Agent harness",
630
635
  children: [
631
- /* @__PURE__ */ jsx3(HarnessLogo, { type: value, size: 16 }),
632
- /* @__PURE__ */ jsx3("span", { children: selected?.label ?? value }),
633
- !locked && /* @__PURE__ */ jsx3(ChevronDown3, { className: "h-3.5 w-3.5 text-muted-foreground" })
636
+ /* @__PURE__ */ jsx3(HarnessLogo, { type: value, size: 16, className: "shrink-0" }),
637
+ /* @__PURE__ */ jsx3("span", { className: "truncate", children: selected?.label ?? value }),
638
+ !locked && /* @__PURE__ */ jsx3(ChevronDown3, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-muted-foreground" })
634
639
  ]
635
640
  }
636
641
  ) }),
@@ -745,9 +750,11 @@ function AgentSessionControls({
745
750
  )
746
751
  ) : model?.models;
747
752
  const harnessAvailable = harness?.available ?? (context === "chat" ? chatCapableHarnesses : void 0);
748
- const menuSide = layout === "gear" ? "left" : "bottom";
749
- const menuAlign = layout === "gear" ? "end" : "start";
750
- const inlineForceDown = menuPlacement === "down" && layout !== "gear";
753
+ const collapsed = layout === "gear" || layout === "combined";
754
+ const menuSide = collapsed ? "left" : "bottom";
755
+ const menuAlign = collapsed ? "end" : "start";
756
+ const collapsedTriggerClass = layout === "combined" ? "w-full bg-transparent shadow-none hover:bg-muted/60 data-[state=open]:bg-muted/60" : collapsed ? "w-full" : void 0;
757
+ const inlineForceDown = menuPlacement === "down" && layout === "inline";
751
758
  const avoidCollisions = inlineForceDown ? false : void 0;
752
759
  const harnessNode = harness && /* @__PURE__ */ jsx3(
753
760
  HarnessDropdown,
@@ -757,7 +764,8 @@ function AgentSessionControls({
757
764
  onChange: handleHarnessChange,
758
765
  side: menuSide,
759
766
  align: menuAlign,
760
- avoidCollisions
767
+ avoidCollisions,
768
+ triggerClassName: collapsedTriggerClass
761
769
  }
762
770
  );
763
771
  const profileNode = profile && /* @__PURE__ */ jsx3(
@@ -771,7 +779,7 @@ function AgentSessionControls({
771
779
  onUpdate: profile.onUpdate,
772
780
  onDelete: profile.onDelete,
773
781
  disabled: profile.disabled,
774
- side: inlineForceDown || layout === "gear" ? "bottom" : "top"
782
+ side: inlineForceDown || collapsed ? "bottom" : "top"
775
783
  }
776
784
  );
777
785
  const modelNode = model && /* @__PURE__ */ jsx3(
@@ -786,8 +794,9 @@ function AgentSessionControls({
786
794
  popular: model.popular,
787
795
  recents: model.recents,
788
796
  disabled: model.disabled || (visibleModels ?? []).length === 0 || !selectorHonorsModel,
789
- side: layout === "gear" ? void 0 : "bottom",
790
- avoidCollisions
797
+ side: collapsed ? void 0 : "bottom",
798
+ avoidCollisions,
799
+ triggerClassName: collapsedTriggerClass
791
800
  }
792
801
  );
793
802
  const modelReasoning = modelReasoningCapability(model?.models, model?.value);
@@ -800,8 +809,9 @@ function AgentSessionControls({
800
809
  options: reasoningOptions,
801
810
  disabled: reasoning.disabled || !selectorHonorsEffort,
802
811
  available: harness ? reasoningEffortsFor(harness.value, modelReasoning) : reasoning.available,
803
- side: layout === "gear" ? void 0 : "bottom",
804
- avoidCollisions
812
+ side: collapsed ? void 0 : "bottom",
813
+ avoidCollisions,
814
+ triggerClassName: collapsedTriggerClass
805
815
  }
806
816
  );
807
817
  if (layout === "gear") {
@@ -817,6 +827,76 @@ function AgentSessionControls({
817
827
  }
818
828
  );
819
829
  }
830
+ if (layout === "combined") {
831
+ const segments = [];
832
+ if (harness) {
833
+ const harnessLabel = HARNESS_OPTIONS.find((option) => option.type === harness.value)?.label ?? harness.value;
834
+ segments.push({
835
+ key: "harness",
836
+ label: harnessLabel,
837
+ node: /* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-1.5", children: [
838
+ /* @__PURE__ */ jsx3(HarnessLogo, { type: harness.value, size: 16, className: "shrink-0" }),
839
+ harnessLabel
840
+ ] })
841
+ });
842
+ }
843
+ if (model && selectorHonorsModel) {
844
+ const current = (model.models ?? []).find(
845
+ (entry) => canonicalModelId(entry) === model.value
846
+ );
847
+ const identity = current ? resolveModelBrandIdentity(current) : null;
848
+ const modelLabel = stripBrandPrefix(
849
+ current?.name ?? current?.id ?? model.value,
850
+ identity
851
+ );
852
+ segments.push({
853
+ key: "model",
854
+ label: modelLabel,
855
+ node: /* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-1.5", children: [
856
+ identity && /* @__PURE__ */ jsx3(ModelBrandStack, { identity, size: "sm" }),
857
+ modelLabel
858
+ ] })
859
+ });
860
+ }
861
+ if (reasoning && selectorHonorsEffort) {
862
+ const effortLabel = (reasoningOptions ?? DEFAULT_REASONING_LEVEL_OPTIONS).find(
863
+ (option) => option.value === reasoning.value
864
+ )?.label ?? "Auto";
865
+ segments.push({
866
+ key: "effort",
867
+ label: effortLabel,
868
+ node: /* @__PURE__ */ jsxs3("span", { className: "flex items-center gap-1.5", children: [
869
+ /* @__PURE__ */ jsx3("span", { className: "flex w-3.5 shrink-0 justify-center", children: /* @__PURE__ */ jsx3(ReasoningGlyph, { level: reasoning.value }) }),
870
+ effortLabel
871
+ ] })
872
+ });
873
+ }
874
+ const summary = /* @__PURE__ */ jsx3("span", { className: "flex items-center gap-1.5", children: segments.map((segment, index) => /* @__PURE__ */ jsxs3(React3.Fragment, { children: [
875
+ index > 0 && /* @__PURE__ */ jsx3(
876
+ "span",
877
+ {
878
+ className: "text-base leading-none text-muted-foreground/60",
879
+ "aria-hidden": true,
880
+ children: "\xB7"
881
+ }
882
+ ),
883
+ segment.node
884
+ ] }, segment.key)) });
885
+ return /* @__PURE__ */ jsx3(
886
+ SummaryControls,
887
+ {
888
+ className,
889
+ summary,
890
+ title: segments.map((segment) => segment.label).join(" \xB7 "),
891
+ contentSide: menuPlacement === "down" ? "bottom" : "top",
892
+ profileNode,
893
+ harnessNode,
894
+ modelNode,
895
+ reasoningNode,
896
+ trailing
897
+ }
898
+ );
899
+ }
820
900
  return /* @__PURE__ */ jsxs3(
821
901
  "div",
822
902
  {
@@ -839,6 +919,91 @@ function GearControls({
839
919
  modelNode,
840
920
  reasoningNode,
841
921
  trailing
922
+ }) {
923
+ return /* @__PURE__ */ jsx3(
924
+ CollapsibleControls,
925
+ {
926
+ className,
927
+ trigger: /* @__PURE__ */ jsx3(SlidersHorizontal, { className: "h-4 w-4 text-muted-foreground" }),
928
+ triggerClassName: cn(
929
+ "inline-flex h-8 w-8 items-center justify-center rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container",
930
+ "text-foreground shadow-sm transition-colors",
931
+ "hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
932
+ "data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high"
933
+ ),
934
+ contentSide: "top",
935
+ contentClassName: cn(
936
+ "w-56 gap-2 border-[var(--md3-outline-variant)] bg-surface-container-highest p-2",
937
+ "shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]"
938
+ ),
939
+ profileNode,
940
+ harnessNode,
941
+ modelNode,
942
+ reasoningNode,
943
+ trailing
944
+ }
945
+ );
946
+ }
947
+ function GearSection({
948
+ label,
949
+ children
950
+ }) {
951
+ return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
952
+ /* @__PURE__ */ jsx3("span", { className: "px-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70", children: label }),
953
+ children
954
+ ] });
955
+ }
956
+ function SummaryControls({
957
+ className,
958
+ summary,
959
+ title,
960
+ contentSide,
961
+ profileNode,
962
+ harnessNode,
963
+ modelNode,
964
+ reasoningNode,
965
+ trailing
966
+ }) {
967
+ return /* @__PURE__ */ jsx3(
968
+ CollapsibleControls,
969
+ {
970
+ className,
971
+ trigger: /* @__PURE__ */ jsxs3(Fragment2, { children: [
972
+ summary,
973
+ /* @__PURE__ */ jsx3(ChevronDown3, { className: "h-3.5 w-3.5 shrink-0 text-muted-foreground" })
974
+ ] }),
975
+ triggerTitle: title,
976
+ triggerClassName: cn(
977
+ // Container-less trigger (Codex-style): bare label + chevron docked in
978
+ // the composer footer, no border/card/shadow. Only a subtle rounded
979
+ // hover/open tint marks it as interactive.
980
+ "inline-flex h-8 items-center gap-1.5 rounded-md px-1.5",
981
+ "whitespace-nowrap text-xs font-medium text-foreground transition-colors",
982
+ "hover:bg-muted/50 focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
983
+ "data-[state=open]:bg-muted/50"
984
+ ),
985
+ contentSide,
986
+ contentClassName: "w-64 gap-2.5 border-border bg-popover p-2.5 text-popover-foreground shadow-lg",
987
+ profileNode,
988
+ harnessNode,
989
+ modelNode,
990
+ reasoningNode,
991
+ trailing
992
+ }
993
+ );
994
+ }
995
+ function CollapsibleControls({
996
+ className,
997
+ trigger,
998
+ triggerTitle,
999
+ triggerClassName,
1000
+ contentSide,
1001
+ contentClassName,
1002
+ profileNode,
1003
+ harnessNode,
1004
+ modelNode,
1005
+ reasoningNode,
1006
+ trailing
842
1007
  }) {
843
1008
  return /* @__PURE__ */ jsxs3(
844
1009
  "div",
@@ -853,19 +1018,15 @@ function GearControls({
853
1018
  {
854
1019
  type: "button",
855
1020
  "aria-label": "Session controls",
856
- className: cn(
857
- "inline-flex h-8 w-8 items-center justify-center rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container",
858
- "text-foreground shadow-sm transition-colors",
859
- "hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
860
- "data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high"
861
- ),
862
- children: /* @__PURE__ */ jsx3(SlidersHorizontal, { className: "h-4 w-4 text-muted-foreground" })
1021
+ title: triggerTitle,
1022
+ className: triggerClassName,
1023
+ children: trigger
863
1024
  }
864
1025
  ) }),
865
1026
  /* @__PURE__ */ jsx3(DropdownMenu2.Portal, { children: /* @__PURE__ */ jsxs3(
866
1027
  DropdownMenu2.Content,
867
1028
  {
868
- side: "top",
1029
+ side: contentSide,
869
1030
  align: "end",
870
1031
  sideOffset: 8,
871
1032
  onInteractOutside: (event) => {
@@ -877,11 +1038,11 @@ function GearControls({
877
1038
  }
878
1039
  },
879
1040
  className: cn(
880
- "z-50 flex w-56 flex-col gap-2 rounded-[var(--radius-md)] border border-[var(--md3-outline-variant)] bg-surface-container-highest p-2",
881
- "shadow-[0_8px_30px_rgba(0,0,0,0.45)] ring-1 ring-[#ffffff14]",
1041
+ "z-50 flex flex-col rounded-[var(--radius-md)] border",
882
1042
  "data-[state=open]:animate-in data-[state=closed]:animate-out",
883
1043
  "data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
884
- "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95"
1044
+ "data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95",
1045
+ contentClassName
885
1046
  ),
886
1047
  children: [
887
1048
  profileNode && /* @__PURE__ */ jsx3(GearSection, { label: "Agent", children: profileNode }),
@@ -896,15 +1057,6 @@ function GearControls({
896
1057
  }
897
1058
  );
898
1059
  }
899
- function GearSection({
900
- label,
901
- children
902
- }) {
903
- return /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-1", children: [
904
- /* @__PURE__ */ jsx3("span", { className: "px-0.5 text-[10px] font-medium uppercase tracking-wide text-muted-foreground/70", children: label }),
905
- children
906
- ] });
907
- }
908
1060
 
909
1061
  // src/chat/agent-composer.tsx
910
1062
  import {
@@ -917,7 +1069,7 @@ import {
917
1069
  X
918
1070
  } from "lucide-react";
919
1071
  import * as React4 from "react";
920
- import { Fragment, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1072
+ import { Fragment as Fragment3, jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
921
1073
  function AgentComposer({
922
1074
  value,
923
1075
  onChange,
@@ -1103,7 +1255,7 @@ function AgentComposer({
1103
1255
  reasoning
1104
1256
  }
1105
1257
  ) }),
1106
- onAttach && /* @__PURE__ */ jsxs4(Fragment, { children: [
1258
+ onAttach && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1107
1259
  /* @__PURE__ */ jsx4(
1108
1260
  "button",
1109
1261
  {
@@ -1131,7 +1283,7 @@ function AgentComposer({
1131
1283
  }
1132
1284
  )
1133
1285
  ] }),
1134
- onAttachFolder && /* @__PURE__ */ jsxs4(Fragment, { children: [
1286
+ onAttachFolder && /* @__PURE__ */ jsxs4(Fragment3, { children: [
1135
1287
  /* @__PURE__ */ jsx4(
1136
1288
  "button",
1137
1289
  {
package/dist/dashboard.js CHANGED
@@ -71,7 +71,7 @@ import {
71
71
  HarnessLogo,
72
72
  HarnessPicker,
73
73
  chatCapableHarnesses
74
- } from "./chunk-HU4B2M4K.js";
74
+ } from "./chunk-IWIZ7RZE.js";
75
75
  import {
76
76
  DEFAULT_FEATURED_MODEL_IDS,
77
77
  ModelPicker,
@@ -80,7 +80,7 @@ import {
80
80
  formatContext,
81
81
  formatPricing,
82
82
  modelDedupKey
83
- } from "./chunk-SF6LPMMN.js";
83
+ } from "./chunk-L62ZT6RS.js";
84
84
  import "./chunk-EI44GEQ5.js";
85
85
  import "./chunk-U67V476Y.js";
86
86
  export {
package/dist/globals.css CHANGED
@@ -356,6 +356,9 @@
356
356
  .top-2 {
357
357
  top: calc(var(--spacing) * 2);
358
358
  }
359
+ .top-3\.5 {
360
+ top: calc(var(--spacing) * 3.5);
361
+ }
359
362
  .top-4 {
360
363
  top: calc(var(--spacing) * 4);
361
364
  }
@@ -539,9 +542,6 @@
539
542
  .mt-6 {
540
543
  margin-top: calc(var(--spacing) * 6);
541
544
  }
542
- .mt-px {
543
- margin-top: 1px;
544
- }
545
545
  .mr-1 {
546
546
  margin-right: calc(var(--spacing) * 1);
547
547
  }
@@ -808,6 +808,9 @@
808
808
  .h-\[var\(--timeline-dot-size\)\] {
809
809
  height: var(--timeline-dot-size);
810
810
  }
811
+ .h-\[var\(--timeline-dot-size\,0\.5rem\)\] {
812
+ height: var(--timeline-dot-size,0.5rem);
813
+ }
811
814
  .h-\[var\(--tool-icon-size\)\] {
812
815
  height: var(--tool-icon-size);
813
816
  }
@@ -1132,6 +1135,9 @@
1132
1135
  .w-\[var\(--timeline-dot-size\)\] {
1133
1136
  width: var(--timeline-dot-size);
1134
1137
  }
1138
+ .w-\[var\(--timeline-dot-size\,0\.5rem\)\] {
1139
+ width: var(--timeline-dot-size,0.5rem);
1140
+ }
1135
1141
  .w-\[var\(--tool-icon-size\)\] {
1136
1142
  width: var(--tool-icon-size);
1137
1143
  }
@@ -1610,6 +1616,9 @@
1610
1616
  .gap-x-2 {
1611
1617
  column-gap: calc(var(--spacing) * 2);
1612
1618
  }
1619
+ .gap-x-3 {
1620
+ column-gap: calc(var(--spacing) * 3);
1621
+ }
1613
1622
  .gap-x-4 {
1614
1623
  column-gap: calc(var(--spacing) * 4);
1615
1624
  }
@@ -1686,15 +1695,9 @@
1686
1695
  .rounded-\[22px\] {
1687
1696
  border-radius: 22px;
1688
1697
  }
1689
- .rounded-\[24px\] {
1690
- border-radius: 24px;
1691
- }
1692
1698
  .rounded-\[26px\] {
1693
1699
  border-radius: 26px;
1694
1700
  }
1695
- .rounded-\[28px\] {
1696
- border-radius: 28px;
1697
- }
1698
1701
  .rounded-\[calc\(var\(--radius-xl\)\+2px\)\] {
1699
1702
  border-radius: calc(var(--radius-xl) + 2px);
1700
1703
  }
@@ -2111,6 +2114,9 @@
2111
2114
  .bg-\[var\(--border-hover\)\] {
2112
2115
  background-color: var(--border-hover);
2113
2116
  }
2117
+ .bg-\[var\(--border-subtle\)\] {
2118
+ background-color: var(--border-subtle);
2119
+ }
2114
2120
  .bg-\[var\(--brand-cool\)\] {
2115
2121
  background-color: var(--brand-cool);
2116
2122
  }
@@ -2606,9 +2612,6 @@
2606
2612
  .p-16 {
2607
2613
  padding: calc(var(--spacing) * 16);
2608
2614
  }
2609
- .px-0 {
2610
- padding-inline: calc(var(--spacing) * 0);
2611
- }
2612
2615
  .px-0\.5 {
2613
2616
  padding-inline: calc(var(--spacing) * 0.5);
2614
2617
  }
@@ -2654,9 +2657,6 @@
2654
2657
  .px-\[var\(--tool-card-px\)\] {
2655
2658
  padding-inline: var(--tool-card-px);
2656
2659
  }
2657
- .py-0 {
2658
- padding-block: calc(var(--spacing) * 0);
2659
- }
2660
2660
  .py-0\.5 {
2661
2661
  padding-block: calc(var(--spacing) * 0.5);
2662
2662
  }
@@ -2798,6 +2798,9 @@
2798
2798
  .pl-3\.5 {
2799
2799
  padding-left: calc(var(--spacing) * 3.5);
2800
2800
  }
2801
+ .pl-6 {
2802
+ padding-left: calc(var(--spacing) * 6);
2803
+ }
2801
2804
  .pl-7 {
2802
2805
  padding-left: calc(var(--spacing) * 7);
2803
2806
  }
@@ -4002,6 +4005,16 @@
4002
4005
  }
4003
4006
  }
4004
4007
  }
4008
+ .hover\:bg-\[var\(--surface-container-high\)\]\/40 {
4009
+ &:hover {
4010
+ @media (hover: hover) {
4011
+ background-color: var(--surface-container-high);
4012
+ @supports (color: color-mix(in lab, red, red)) {
4013
+ background-color: color-mix(in oklab, var(--surface-container-high) 40%, transparent);
4014
+ }
4015
+ }
4016
+ }
4017
+ }
4005
4018
  .hover\:bg-\[var\(--surface-danger-bg\)\] {
4006
4019
  &:hover {
4007
4020
  @media (hover: hover) {
@@ -4184,6 +4197,16 @@
4184
4197
  }
4185
4198
  }
4186
4199
  }
4200
+ .hover\:bg-muted\/60 {
4201
+ &:hover {
4202
+ @media (hover: hover) {
4203
+ background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
4204
+ @supports (color: color-mix(in lab, red, red)) {
4205
+ background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
4206
+ }
4207
+ }
4208
+ }
4209
+ }
4187
4210
  .hover\:bg-muted\/80 {
4188
4211
  &:hover {
4189
4212
  @media (hover: hover) {
@@ -4272,13 +4295,6 @@
4272
4295
  }
4273
4296
  }
4274
4297
  }
4275
- .hover\:bg-transparent {
4276
- &:hover {
4277
- @media (hover: hover) {
4278
- background-color: transparent;
4279
- }
4280
- }
4281
- }
4282
4298
  .hover\:bg-white\/5 {
4283
4299
  &:hover {
4284
4300
  @media (hover: hover) {
@@ -4881,6 +4897,14 @@
4881
4897
  }
4882
4898
  }
4883
4899
  }
4900
+ .data-\[state\=open\]\:bg-muted\/60 {
4901
+ &[data-state="open"] {
4902
+ background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
4903
+ @supports (color: color-mix(in lab, red, red)) {
4904
+ background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
4905
+ }
4906
+ }
4907
+ }
4884
4908
  .data-\[state\=open\]\:bg-surface-container-high {
4885
4909
  &[data-state="open"] {
4886
4910
  background-color: var(--color-surface-container-high);
package/dist/index.js CHANGED
@@ -102,7 +102,7 @@ import {
102
102
  modelProvider,
103
103
  snapHarnessToModel,
104
104
  snapModelToHarness
105
- } from "./chunk-XL573ZOV.js";
105
+ } from "./chunk-UQXDIQWD.js";
106
106
  import {
107
107
  ExpandedToolDetail,
108
108
  InlineThinkingItem,
@@ -318,7 +318,7 @@ import {
318
318
  HarnessLogo,
319
319
  HarnessPicker,
320
320
  chatCapableHarnesses
321
- } from "./chunk-HU4B2M4K.js";
321
+ } from "./chunk-IWIZ7RZE.js";
322
322
  import {
323
323
  DEFAULT_FEATURED_MODEL_IDS,
324
324
  ModelPicker,
@@ -327,7 +327,7 @@ import {
327
327
  formatContext,
328
328
  formatPricing,
329
329
  modelDedupKey
330
- } from "./chunk-SF6LPMMN.js";
330
+ } from "./chunk-L62ZT6RS.js";
331
331
  import "./chunk-EI44GEQ5.js";
332
332
  import {
333
333
  OpenUIArtifactRenderer
package/dist/pages.js CHANGED
@@ -24,7 +24,7 @@ import {
24
24
  Switch,
25
25
  Textarea
26
26
  } from "./chunk-4ZZUMXPX.js";
27
- import "./chunk-SF6LPMMN.js";
27
+ import "./chunk-L62ZT6RS.js";
28
28
  import {
29
29
  cn
30
30
  } from "./chunk-EI44GEQ5.js";
package/dist/styles.css CHANGED
@@ -356,6 +356,9 @@
356
356
  .top-2 {
357
357
  top: calc(var(--spacing) * 2);
358
358
  }
359
+ .top-3\.5 {
360
+ top: calc(var(--spacing) * 3.5);
361
+ }
359
362
  .top-4 {
360
363
  top: calc(var(--spacing) * 4);
361
364
  }
@@ -539,9 +542,6 @@
539
542
  .mt-6 {
540
543
  margin-top: calc(var(--spacing) * 6);
541
544
  }
542
- .mt-px {
543
- margin-top: 1px;
544
- }
545
545
  .mr-1 {
546
546
  margin-right: calc(var(--spacing) * 1);
547
547
  }
@@ -808,6 +808,9 @@
808
808
  .h-\[var\(--timeline-dot-size\)\] {
809
809
  height: var(--timeline-dot-size);
810
810
  }
811
+ .h-\[var\(--timeline-dot-size\,0\.5rem\)\] {
812
+ height: var(--timeline-dot-size,0.5rem);
813
+ }
811
814
  .h-\[var\(--tool-icon-size\)\] {
812
815
  height: var(--tool-icon-size);
813
816
  }
@@ -1132,6 +1135,9 @@
1132
1135
  .w-\[var\(--timeline-dot-size\)\] {
1133
1136
  width: var(--timeline-dot-size);
1134
1137
  }
1138
+ .w-\[var\(--timeline-dot-size\,0\.5rem\)\] {
1139
+ width: var(--timeline-dot-size,0.5rem);
1140
+ }
1135
1141
  .w-\[var\(--tool-icon-size\)\] {
1136
1142
  width: var(--tool-icon-size);
1137
1143
  }
@@ -1610,6 +1616,9 @@
1610
1616
  .gap-x-2 {
1611
1617
  column-gap: calc(var(--spacing) * 2);
1612
1618
  }
1619
+ .gap-x-3 {
1620
+ column-gap: calc(var(--spacing) * 3);
1621
+ }
1613
1622
  .gap-x-4 {
1614
1623
  column-gap: calc(var(--spacing) * 4);
1615
1624
  }
@@ -1686,15 +1695,9 @@
1686
1695
  .rounded-\[22px\] {
1687
1696
  border-radius: 22px;
1688
1697
  }
1689
- .rounded-\[24px\] {
1690
- border-radius: 24px;
1691
- }
1692
1698
  .rounded-\[26px\] {
1693
1699
  border-radius: 26px;
1694
1700
  }
1695
- .rounded-\[28px\] {
1696
- border-radius: 28px;
1697
- }
1698
1701
  .rounded-\[calc\(var\(--radius-xl\)\+2px\)\] {
1699
1702
  border-radius: calc(var(--radius-xl) + 2px);
1700
1703
  }
@@ -2111,6 +2114,9 @@
2111
2114
  .bg-\[var\(--border-hover\)\] {
2112
2115
  background-color: var(--border-hover);
2113
2116
  }
2117
+ .bg-\[var\(--border-subtle\)\] {
2118
+ background-color: var(--border-subtle);
2119
+ }
2114
2120
  .bg-\[var\(--brand-cool\)\] {
2115
2121
  background-color: var(--brand-cool);
2116
2122
  }
@@ -2606,9 +2612,6 @@
2606
2612
  .p-16 {
2607
2613
  padding: calc(var(--spacing) * 16);
2608
2614
  }
2609
- .px-0 {
2610
- padding-inline: calc(var(--spacing) * 0);
2611
- }
2612
2615
  .px-0\.5 {
2613
2616
  padding-inline: calc(var(--spacing) * 0.5);
2614
2617
  }
@@ -2654,9 +2657,6 @@
2654
2657
  .px-\[var\(--tool-card-px\)\] {
2655
2658
  padding-inline: var(--tool-card-px);
2656
2659
  }
2657
- .py-0 {
2658
- padding-block: calc(var(--spacing) * 0);
2659
- }
2660
2660
  .py-0\.5 {
2661
2661
  padding-block: calc(var(--spacing) * 0.5);
2662
2662
  }
@@ -2798,6 +2798,9 @@
2798
2798
  .pl-3\.5 {
2799
2799
  padding-left: calc(var(--spacing) * 3.5);
2800
2800
  }
2801
+ .pl-6 {
2802
+ padding-left: calc(var(--spacing) * 6);
2803
+ }
2801
2804
  .pl-7 {
2802
2805
  padding-left: calc(var(--spacing) * 7);
2803
2806
  }
@@ -4002,6 +4005,16 @@
4002
4005
  }
4003
4006
  }
4004
4007
  }
4008
+ .hover\:bg-\[var\(--surface-container-high\)\]\/40 {
4009
+ &:hover {
4010
+ @media (hover: hover) {
4011
+ background-color: var(--surface-container-high);
4012
+ @supports (color: color-mix(in lab, red, red)) {
4013
+ background-color: color-mix(in oklab, var(--surface-container-high) 40%, transparent);
4014
+ }
4015
+ }
4016
+ }
4017
+ }
4005
4018
  .hover\:bg-\[var\(--surface-danger-bg\)\] {
4006
4019
  &:hover {
4007
4020
  @media (hover: hover) {
@@ -4184,6 +4197,16 @@
4184
4197
  }
4185
4198
  }
4186
4199
  }
4200
+ .hover\:bg-muted\/60 {
4201
+ &:hover {
4202
+ @media (hover: hover) {
4203
+ background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
4204
+ @supports (color: color-mix(in lab, red, red)) {
4205
+ background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
4206
+ }
4207
+ }
4208
+ }
4209
+ }
4187
4210
  .hover\:bg-muted\/80 {
4188
4211
  &:hover {
4189
4212
  @media (hover: hover) {
@@ -4272,13 +4295,6 @@
4272
4295
  }
4273
4296
  }
4274
4297
  }
4275
- .hover\:bg-transparent {
4276
- &:hover {
4277
- @media (hover: hover) {
4278
- background-color: transparent;
4279
- }
4280
- }
4281
- }
4282
4298
  .hover\:bg-white\/5 {
4283
4299
  &:hover {
4284
4300
  @media (hover: hover) {
@@ -4881,6 +4897,14 @@
4881
4897
  }
4882
4898
  }
4883
4899
  }
4900
+ .data-\[state\=open\]\:bg-muted\/60 {
4901
+ &[data-state="open"] {
4902
+ background-color: color-mix(in srgb, hsl(var(--muted)) 60%, transparent);
4903
+ @supports (color: color-mix(in lab, red, red)) {
4904
+ background-color: color-mix(in oklab, var(--color-muted) 60%, transparent);
4905
+ }
4906
+ }
4907
+ }
4884
4908
  .data-\[state\=open\]\:bg-surface-container-high {
4885
4909
  &[data-state="open"] {
4886
4910
  background-color: var(--color-surface-container-high);
package/dist/workbench.js CHANGED
@@ -19,8 +19,8 @@ import "./chunk-VIREDUBF.js";
19
19
  import "./chunk-77WVVJA4.js";
20
20
  import "./chunk-OMUIPJQZ.js";
21
21
  import "./chunk-4ZZUMXPX.js";
22
- import "./chunk-HU4B2M4K.js";
23
- import "./chunk-SF6LPMMN.js";
22
+ import "./chunk-IWIZ7RZE.js";
23
+ import "./chunk-L62ZT6RS.js";
24
24
  import "./chunk-EI44GEQ5.js";
25
25
  import "./chunk-U67V476Y.js";
26
26
  export {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.69.0",
3
+ "version": "0.71.0",
4
4
  "description": "Unified UI component library for Tangle Sandbox — primitives, chat, dashboard, terminal, editor, and workspace components",
5
5
  "repository": {
6
6
  "type": "git",
@@ -124,7 +124,7 @@
124
124
  "peerDependencies": {
125
125
  "@tangle-network/agent-interface": ">=0.17.0 <1.0.0",
126
126
  "@tangle-network/brand": "^0.8.0",
127
- "@tangle-network/ui": "^8.1.0",
127
+ "@tangle-network/ui": "^9.0.0",
128
128
  "@xyflow/react": "^12.0.0",
129
129
  "react": "^18 || ^19",
130
130
  "react-dom": "^18 || ^19"
@@ -179,7 +179,7 @@
179
179
  "@tailwindcss/vite": "^4.2.2",
180
180
  "@tangle-network/agent-interface": ">=0.17.0 <1.0.0",
181
181
  "@tangle-network/brand": "^0.8.0",
182
- "@tangle-network/ui": "^8.1.0",
182
+ "@tangle-network/ui": "^9.0.0",
183
183
  "@tanstack/react-query": "^5.91.0",
184
184
  "@testing-library/dom": "^10.4.1",
185
185
  "@testing-library/jest-dom": "^6.9.1",