@tangle-network/sandbox-ui 0.95.1 → 0.96.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.
@@ -17,7 +17,7 @@ import {
17
17
  providerLabel,
18
18
  shortModel,
19
19
  triggerNodeIndex
20
- } from "./chunk-O7MHUR4U.js";
20
+ } from "./chunk-LHUBJPZR.js";
21
21
  import {
22
22
  ModelBrandStack,
23
23
  modelBrandFor
package/dist/chat.d.ts CHANGED
@@ -160,6 +160,15 @@ interface AgentSessionModelControl {
160
160
  popular?: ReadonlyArray<string>;
161
161
  recents?: ReadonlyArray<string>;
162
162
  disabled?: boolean;
163
+ /**
164
+ * Restrict the catalog to these architecture modalities (forwarded to
165
+ * `ModelPicker`'s `modalities`). Supplying this — even `[]` — replaces the
166
+ * chat surface's default text-chat filter: the caller owns modality
167
+ * filtering entirely.
168
+ */
169
+ modalities?: ReadonlyArray<string>;
170
+ /** Drop providers from the picker entirely (forwarded to `ModelPicker`). */
171
+ excludeProviders?: ReadonlyArray<string>;
163
172
  }
164
173
  interface AgentSessionReasoningControl {
165
174
  value: ReasoningLevel;
package/dist/chat.js CHANGED
@@ -19,13 +19,13 @@ import {
19
19
  snapHarnessToModel,
20
20
  snapModelToHarness,
21
21
  validateComposerFiles
22
- } from "./chunk-GUULFESL.js";
22
+ } from "./chunk-I5HGKZCB.js";
23
23
  import "./chunk-TK46XFLM.js";
24
24
  import {
25
25
  MENTION_PILL_CLASS
26
26
  } from "./chunk-WGOOQAW3.js";
27
27
  import "./chunk-WSN2RZC6.js";
28
- import "./chunk-FWSBQLFG.js";
28
+ import "./chunk-WMVUJ5SA.js";
29
29
  import "./chunk-5XRAKVIV.js";
30
30
  import "./chunk-EI44GEQ5.js";
31
31
  import "./chunk-CZ7CSFO4.js";
@@ -13,11 +13,12 @@ import {
13
13
  PickerMenuSearch,
14
14
  PickerMenuSection,
15
15
  PickerMenuTag,
16
+ isTextChatModel,
16
17
  pickerMenuBodyClass,
17
18
  pickerMenuContentClass,
18
19
  pickerMenuItemClass,
19
20
  stripBrandPrefix
20
- } from "./chunk-FWSBQLFG.js";
21
+ } from "./chunk-WMVUJ5SA.js";
21
22
  import {
22
23
  ModelBrandStack,
23
24
  canonicalModelId,
@@ -525,7 +526,8 @@ function InformativeLock({
525
526
  lockTitle,
526
527
  lockBody,
527
528
  newChatLabel,
528
- onNewChat
529
+ onNewChat,
530
+ triggerClassName
529
531
  }) {
530
532
  const [open, setOpen] = React3.useState(false);
531
533
  const closeTimer = React3.useRef(null);
@@ -571,7 +573,8 @@ function InformativeLock({
571
573
  "inline-flex h-8 items-center gap-1.5 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container px-2.5 opacity-60",
572
574
  "text-xs font-medium text-foreground shadow-sm transition-colors",
573
575
  "hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
574
- "data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high"
576
+ "data-[state=open]:border-[var(--md3-outline-variant)] data-[state=open]:bg-surface-container-high",
577
+ triggerClassName
575
578
  ),
576
579
  children: [
577
580
  /* @__PURE__ */ jsx3(HarnessLogo, { type, size: 16 }),
@@ -672,7 +675,8 @@ function HarnessDropdown({
672
675
  lockTitle,
673
676
  lockBody,
674
677
  newChatLabel,
675
- onNewChat
678
+ onNewChat,
679
+ triggerClassName
676
680
  }
677
681
  );
678
682
  }
@@ -826,17 +830,24 @@ function AgentSessionControls({
826
830
  }
827
831
  if (nextHarness) clampEffort(nextHarness, nextModelId);
828
832
  };
829
- const visibleModels = model && restrictModelsToHarness && harness ? model.models.filter(
833
+ const chatModels = model && context === "chat" && model.modalities === void 0 ? model.models.filter(isTextChatModel) : model?.models;
834
+ const visibleModels = model && restrictModelsToHarness && harness ? (chatModels ?? []).filter(
830
835
  (entry) => isModelCompatibleWithHarness(
831
836
  harness.value,
832
837
  canonicalModelId(entry)
833
838
  )
834
- ) : model?.models;
839
+ ) : chatModels;
835
840
  const harnessAvailable = harness?.available ?? (context === "chat" ? chatCapableHarnesses : void 0);
836
841
  const collapsed = layout === "gear" || layout === "combined";
837
842
  const menuSide = collapsed ? "left" : "bottom";
838
843
  const menuAlign = collapsed ? "end" : "start";
839
844
  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;
845
+ const secondaryTriggerClass = collapsed ? collapsedTriggerClass : cn(
846
+ "border-transparent bg-transparent text-muted-foreground shadow-none",
847
+ "hover:border-transparent hover:bg-muted/50 hover:text-foreground",
848
+ "data-[state=open]:border-transparent data-[state=open]:bg-muted/50 data-[state=open]:text-foreground"
849
+ );
850
+ const modelTriggerClass = collapsed ? cn(collapsedTriggerClass, "h-8 rounded-lg px-2.5 text-xs") : void 0;
840
851
  const inlineForceDown = menuPlacement === "down" && layout === "inline";
841
852
  const avoidCollisions = inlineForceDown ? false : void 0;
842
853
  const harnessNode = harness && /* @__PURE__ */ jsx3(
@@ -848,7 +859,7 @@ function AgentSessionControls({
848
859
  side: menuSide,
849
860
  align: menuAlign,
850
861
  avoidCollisions,
851
- triggerClassName: collapsedTriggerClass
862
+ triggerClassName: secondaryTriggerClass
852
863
  }
853
864
  );
854
865
  const profileNode = profile && /* @__PURE__ */ jsx3(
@@ -876,10 +887,12 @@ function AgentSessionControls({
876
887
  loading: model.loading,
877
888
  popular: model.popular,
878
889
  recents: model.recents,
890
+ modalities: model.modalities,
891
+ excludeProviders: model.excludeProviders,
879
892
  disabled: model.disabled || (visibleModels ?? []).length === 0 || !selectorHonorsModel,
880
893
  side: collapsed ? void 0 : "bottom",
881
894
  avoidCollisions,
882
- triggerClassName: collapsedTriggerClass
895
+ triggerClassName: modelTriggerClass
883
896
  }
884
897
  );
885
898
  const modelReasoning = modelReasoningCapability(model?.models, model?.value);
@@ -894,7 +907,7 @@ function AgentSessionControls({
894
907
  available: harness ? reasoningEffortsFor(harness.value, modelReasoning) : reasoning.available,
895
908
  side: collapsed ? void 0 : "bottom",
896
909
  avoidCollisions,
897
- triggerClassName: collapsedTriggerClass
910
+ triggerClassName: secondaryTriggerClass
898
911
  }
899
912
  );
900
913
  if (layout === "gear") {
@@ -515,6 +515,29 @@ function describeAction(action) {
515
515
  }
516
516
  return Object.keys(config).length > 0 ? { ...base, config } : base;
517
517
  }
518
+ function describeScope(scope) {
519
+ const rec = asRecord(scope);
520
+ const parts = [];
521
+ for (const [dimension, raw] of Object.entries(rec).sort(
522
+ ([a], [b]) => a < b ? -1 : a > b ? 1 : 0
523
+ )) {
524
+ const selection = asRecord(raw);
525
+ const except = Array.isArray(selection.except) ? [
526
+ ...new Set(
527
+ selection.except.filter((entry) => typeof entry === "string").map((entry) => entry.trim()).filter((entry) => entry !== "")
528
+ )
529
+ ] : [];
530
+ if (except.length === 0) {
531
+ if (selection.default === "exclude") parts.push(`${dimension}: none`);
532
+ continue;
533
+ }
534
+ const named = except.length <= 2 ? except.join(", ") : `${except.length} selected`;
535
+ parts.push(
536
+ selection.default === "exclude" ? `${dimension}: ${named}` : `${dimension}: all but ${named}`
537
+ );
538
+ }
539
+ return parts.length > 0 ? parts.join(" \xB7 ") : void 0;
540
+ }
518
541
  function describeTrigger(on) {
519
542
  const rec = asRecord(on);
520
543
  if (rec.provider_event) {
@@ -524,7 +547,11 @@ function describeTrigger(on) {
524
547
  const actions = Array.isArray(ev.actions) ? ev.actions.filter((a) => typeof a === "string") : [];
525
548
  const repo = str(ev.repo);
526
549
  const description = describeText(
527
- [actions.length > 0 ? actions.join(", ") : void 0, repo].filter(Boolean).join(" \xB7 ")
550
+ [
551
+ actions.length > 0 ? actions.join(", ") : void 0,
552
+ repo,
553
+ describeScope(ev.scope)
554
+ ].filter(Boolean).join(" \xB7 ")
528
555
  );
529
556
  return withConfig(
530
557
  {
@@ -133,12 +133,30 @@ function dedupeModels(models) {
133
133
  return result;
134
134
  }
135
135
  var DEFAULT_FEATURED_MODEL_IDS = [
136
- "anthropic/claude-opus-4-8",
137
- "anthropic/claude-sonnet-4-6",
138
- "openai/gpt-5.4",
139
- "google/gemini-2.5-pro",
140
- "deepseek/deepseek-v3"
136
+ "anthropic/claude-fable-5",
137
+ "anthropic/claude-opus-5",
138
+ "openai/gpt-5.6-sol",
139
+ "google/gemini-3.1-pro-preview",
140
+ "deepseek/deepseek-v4-flash"
141
141
  ];
142
+ function isTextChatModel(model) {
143
+ const arch = model.architecture;
144
+ if (!arch) return true;
145
+ const inputs = arch.input_modalities;
146
+ const outputs = arch.output_modalities;
147
+ if (inputs?.length || outputs?.length) {
148
+ const inOk = !inputs?.length || inputs.includes("text");
149
+ const outOk = !outputs?.length || outputs.includes("text");
150
+ return inOk && outOk;
151
+ }
152
+ const modality = arch.modality;
153
+ if (!modality) return true;
154
+ const arrow = modality.split("->");
155
+ if (arrow.length === 2) {
156
+ return arrow[0].split("+").includes("text") && arrow[1].split("+").includes("text");
157
+ }
158
+ return modality === "text" || modality === "multimodal";
159
+ }
142
160
  function formatPricing(pricing) {
143
161
  const prompt = Number(pricing?.prompt ?? 0);
144
162
  const completion = Number(pricing?.completion ?? 0);
@@ -226,31 +244,31 @@ function ModelPicker({
226
244
  return () => cancelAnimationFrame(frame);
227
245
  }, [open]);
228
246
  const deduped = React2.useMemo(() => dedupeModels(models), [models]);
229
- const filtered = React2.useMemo(() => {
247
+ const passesCatalogFilters = React2.useMemo(() => {
230
248
  const excluded = new Set((excludeProviders ?? []).map((p) => p.toLowerCase()));
231
249
  const allowedModalities = modalities ? new Set(modalities) : null;
232
- const q = query.trim().toLowerCase();
233
- return deduped.filter((m) => {
250
+ return (m) => {
234
251
  const provider = (m._provider ?? m.provider ?? "").toLowerCase();
235
252
  if (excluded.has(provider)) return false;
236
253
  if (allowedModalities && m.architecture?.modality && !allowedModalities.has(m.architecture.modality)) return false;
237
- if (!q) return true;
254
+ return true;
255
+ };
256
+ }, [modalities, excludeProviders]);
257
+ const eligible = React2.useMemo(
258
+ () => deduped.filter(passesCatalogFilters),
259
+ [deduped, passesCatalogFilters]
260
+ );
261
+ const filtered = React2.useMemo(() => {
262
+ const q = query.trim().toLowerCase();
263
+ if (!q) return eligible;
264
+ return eligible.filter((m) => {
265
+ const provider = (m._provider ?? m.provider ?? "").toLowerCase();
238
266
  const id = canonicalModelId(m).toLowerCase();
239
267
  const name = (m.name ?? "").toLowerCase();
240
268
  const identity = resolveModelBrandIdentity(m);
241
269
  return id.includes(q) || name.includes(q) || provider.includes(q) || identity.host.label.toLowerCase().includes(q) || identity.lab.label.toLowerCase().includes(q);
242
270
  });
243
- }, [deduped, query, modalities, excludeProviders]);
244
- const grouped = React2.useMemo(() => {
245
- const groups = /* @__PURE__ */ new Map();
246
- for (const m of filtered) {
247
- const key = modelGroupKey(m);
248
- const list = groups.get(key);
249
- if (list) list.push(m);
250
- else groups.set(key, [m]);
251
- }
252
- return Array.from(groups.entries()).map(([key, list]) => [key, [...list].sort(compareModelsByDisplayName)]).sort(([a], [b]) => compareModelGroups(a, b));
253
- }, [filtered]);
271
+ }, [eligible, query]);
254
272
  const current = React2.useMemo(
255
273
  () => models.find((m) => canonicalModelId(m) === value),
256
274
  [models, value]
@@ -263,25 +281,41 @@ function ModelPicker({
263
281
  const recentIds = React2.useMemo(() => {
264
282
  if (!recents?.length) return [];
265
283
  const lookup = new Map(models.map((m) => [canonicalModelId(m), m]));
266
- return recents.map((id) => lookup.get(id)).filter((m) => Boolean(m)).slice(0, 4);
267
- }, [recents, models]);
284
+ return recents.map((id) => lookup.get(id)).filter((m) => Boolean(m)).filter(passesCatalogFilters).slice(0, 4);
285
+ }, [recents, models, passesCatalogFilters]);
268
286
  const popularModels = React2.useMemo(() => {
269
287
  if (!popular?.length) return [];
270
288
  const lookup = new Map(models.map((m) => [canonicalModelId(m), m]));
271
- return popular.map((id) => lookup.get(id)).filter((m) => Boolean(m));
272
- }, [popular, models]);
289
+ return popular.map((id) => lookup.get(id)).filter((m) => Boolean(m)).filter(passesCatalogFilters);
290
+ }, [popular, models, passesCatalogFilters]);
273
291
  const featuredModels = React2.useMemo(() => {
274
- const flagged = deduped.filter((m) => m.featured);
292
+ const flagged = eligible.filter((m) => m.featured);
275
293
  if (flagged.length > 0) return flagged;
276
294
  const seedKeys = new Set(
277
295
  DEFAULT_FEATURED_MODEL_IDS.map((id) => modelDedupKey({ id }))
278
296
  );
279
- const seeded = deduped.filter((m) => seedKeys.has(modelDedupKey(m)));
297
+ const seeded = eligible.filter((m) => seedKeys.has(modelDedupKey(m)));
280
298
  const order = DEFAULT_FEATURED_MODEL_IDS.map((id) => modelDedupKey({ id }));
281
299
  return seeded.sort(
282
300
  (a, b) => order.indexOf(modelDedupKey(a)) - order.indexOf(modelDedupKey(b))
283
301
  );
284
- }, [deduped]);
302
+ }, [eligible]);
303
+ const grouped = React2.useMemo(() => {
304
+ const curatedKeys = new Set(
305
+ [...featuredModels, ...popularModels, ...recentIds].map(
306
+ (m) => modelDedupKey(m)
307
+ )
308
+ );
309
+ const groups = /* @__PURE__ */ new Map();
310
+ for (const m of filtered) {
311
+ if (!query.trim() && curatedKeys.has(modelDedupKey(m))) continue;
312
+ const key = modelGroupKey(m);
313
+ const list = groups.get(key);
314
+ if (list) list.push(m);
315
+ else groups.set(key, [m]);
316
+ }
317
+ return Array.from(groups.entries()).map(([key, list]) => [key, [...list].sort(compareModelsByDisplayName)]).sort(([a], [b]) => compareModelGroups(a, b));
318
+ }, [filtered, featuredModels, popularModels, recentIds, query]);
285
319
  const handleSelect = (id) => {
286
320
  onChange(id);
287
321
  setOpen(false);
@@ -295,8 +329,8 @@ function ModelPicker({
295
329
  "aria-label": triggerLabel,
296
330
  disabled,
297
331
  className: cn(
298
- "inline-flex h-8 items-center gap-1.5 rounded-lg border border-[var(--md3-outline-variant)] bg-surface-container",
299
- "px-2.5 text-xs font-medium text-foreground shadow-sm",
332
+ "inline-flex h-9 items-center gap-1.5 rounded-full border border-[var(--md3-outline-variant)] bg-surface-container",
333
+ "px-3 text-sm font-medium text-foreground shadow-sm",
300
334
  "transition-colors duration-[var(--transition-fast)]",
301
335
  "hover:border-[var(--md3-outline-variant)] hover:bg-surface-container-high",
302
336
  "focus:outline-none focus-visible:ring-1 focus-visible:ring-ring",
@@ -306,9 +340,9 @@ function ModelPicker({
306
340
  triggerClassName
307
341
  ),
308
342
  children: [
309
- currentIdentity ? /* @__PURE__ */ jsx2(ModelBrandStack, { identity: currentIdentity, size: "sm" }) : /* @__PURE__ */ jsx2(Sparkles, { className: "h-3 w-3 text-muted-foreground" }),
310
- /* @__PURE__ */ jsx2("span", { className: "truncate max-w-[160px]", children: currentLabel || placeholder }),
311
- /* @__PURE__ */ jsx2(ChevronDown, { className: "ml-auto h-3 w-3 shrink-0 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
343
+ currentIdentity ? /* @__PURE__ */ jsx2(ModelBrandStack, { identity: currentIdentity, size: "sm" }) : /* @__PURE__ */ jsx2(Sparkles, { className: "h-3.5 w-3.5 text-muted-foreground" }),
344
+ /* @__PURE__ */ jsx2("span", { className: "truncate max-w-[180px]", children: currentLabel || placeholder }),
345
+ /* @__PURE__ */ jsx2(ChevronDown, { className: "ml-auto h-3.5 w-3.5 shrink-0 text-muted-foreground transition-transform data-[state=open]:rotate-180" })
312
346
  ]
313
347
  }
314
348
  ) : /* @__PURE__ */ jsxs2(
@@ -404,9 +438,9 @@ function ModelPicker({
404
438
  /* @__PURE__ */ jsxs2(PickerMenuFooter, { children: [
405
439
  filtered.length,
406
440
  " of ",
407
- deduped.length,
441
+ eligible.length,
408
442
  " model",
409
- deduped.length === 1 ? "" : "s"
443
+ eligible.length === 1 ? "" : "s"
410
444
  ] })
411
445
  ]
412
446
  }
@@ -487,6 +521,7 @@ export {
487
521
  modelDedupKey,
488
522
  dedupeModels,
489
523
  DEFAULT_FEATURED_MODEL_IDS,
524
+ isTextChatModel,
490
525
  formatPricing,
491
526
  formatContext,
492
527
  stripBrandPrefix,
package/dist/dashboard.js CHANGED
@@ -79,7 +79,7 @@ import {
79
79
  formatContext,
80
80
  formatPricing,
81
81
  modelDedupKey
82
- } from "./chunk-FWSBQLFG.js";
82
+ } from "./chunk-WMVUJ5SA.js";
83
83
  import {
84
84
  ModelBrandStack,
85
85
  canonicalModelId,
package/dist/globals.css CHANGED
@@ -1276,8 +1276,8 @@
1276
1276
  .max-w-\[150px\] {
1277
1277
  max-width: 150px;
1278
1278
  }
1279
- .max-w-\[160px\] {
1280
- max-width: 160px;
1279
+ .max-w-\[180px\] {
1280
+ max-width: 180px;
1281
1281
  }
1282
1282
  .max-w-\[250px\] {
1283
1283
  max-width: 250px;
@@ -3441,6 +3441,9 @@
3441
3441
  .capitalize {
3442
3442
  text-transform: capitalize;
3443
3443
  }
3444
+ .lowercase {
3445
+ text-transform: lowercase;
3446
+ }
3444
3447
  .normal-case {
3445
3448
  text-transform: none;
3446
3449
  }
@@ -3954,6 +3957,9 @@
3954
3957
  border-color: color-mix(in oklab, var(--color-primary) 50%, transparent);
3955
3958
  }
3956
3959
  }
3960
+ .hover\:border-transparent:hover {
3961
+ border-color: transparent;
3962
+ }
3957
3963
  .hover\:\!bg-primary:hover {
3958
3964
  background-color: var(--color-primary) !important;
3959
3965
  }
@@ -4538,6 +4544,9 @@
4538
4544
  .data-\[state\=open\]\:border-\[var\(--md3-outline-variant\)\][data-state="open"] {
4539
4545
  border-color: var(--md3-outline-variant);
4540
4546
  }
4547
+ .data-\[state\=open\]\:border-transparent[data-state="open"] {
4548
+ border-color: transparent;
4549
+ }
4541
4550
  .data-\[state\=open\]\:bg-\[var\(--accent-surface-strong\)\][data-state="open"] {
4542
4551
  background-color: var(--accent-surface-strong);
4543
4552
  }
@@ -4559,6 +4568,9 @@
4559
4568
  .data-\[state\=open\]\:bg-surface-container-high[data-state="open"] {
4560
4569
  background-color: var(--color-surface-container-high);
4561
4570
  }
4571
+ .data-\[state\=open\]\:text-foreground[data-state="open"] {
4572
+ color: var(--color-foreground);
4573
+ }
4562
4574
  .data-\[state\=open\]\:text-muted-foreground[data-state="open"] {
4563
4575
  color: var(--color-muted-foreground);
4564
4576
  }
package/dist/index.js CHANGED
@@ -91,7 +91,7 @@ import {
91
91
  snapHarnessToModel,
92
92
  snapModelToHarness,
93
93
  validateComposerFiles
94
- } from "./chunk-GUULFESL.js";
94
+ } from "./chunk-I5HGKZCB.js";
95
95
  import {
96
96
  TOOL_CATEGORY_ICONS,
97
97
  cn,
@@ -332,7 +332,7 @@ import {
332
332
  formatContext,
333
333
  formatPricing,
334
334
  modelDedupKey
335
- } from "./chunk-FWSBQLFG.js";
335
+ } from "./chunk-WMVUJ5SA.js";
336
336
  import {
337
337
  ModelBrandStack,
338
338
  canonicalModelId,
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-FWSBQLFG.js";
27
+ import "./chunk-WMVUJ5SA.js";
28
28
  import "./chunk-5XRAKVIV.js";
29
29
  import {
30
30
  cn
package/dist/styles.css CHANGED
@@ -1276,8 +1276,8 @@
1276
1276
  .max-w-\[150px\] {
1277
1277
  max-width: 150px;
1278
1278
  }
1279
- .max-w-\[160px\] {
1280
- max-width: 160px;
1279
+ .max-w-\[180px\] {
1280
+ max-width: 180px;
1281
1281
  }
1282
1282
  .max-w-\[250px\] {
1283
1283
  max-width: 250px;
@@ -3441,6 +3441,9 @@
3441
3441
  .capitalize {
3442
3442
  text-transform: capitalize;
3443
3443
  }
3444
+ .lowercase {
3445
+ text-transform: lowercase;
3446
+ }
3444
3447
  .normal-case {
3445
3448
  text-transform: none;
3446
3449
  }
@@ -3954,6 +3957,9 @@
3954
3957
  border-color: color-mix(in oklab, var(--color-primary) 50%, transparent);
3955
3958
  }
3956
3959
  }
3960
+ .hover\:border-transparent:hover {
3961
+ border-color: transparent;
3962
+ }
3957
3963
  .hover\:\!bg-primary:hover {
3958
3964
  background-color: var(--color-primary) !important;
3959
3965
  }
@@ -4538,6 +4544,9 @@
4538
4544
  .data-\[state\=open\]\:border-\[var\(--md3-outline-variant\)\][data-state="open"] {
4539
4545
  border-color: var(--md3-outline-variant);
4540
4546
  }
4547
+ .data-\[state\=open\]\:border-transparent[data-state="open"] {
4548
+ border-color: transparent;
4549
+ }
4541
4550
  .data-\[state\=open\]\:bg-\[var\(--accent-surface-strong\)\][data-state="open"] {
4542
4551
  background-color: var(--accent-surface-strong);
4543
4552
  }
@@ -4559,6 +4568,9 @@
4559
4568
  .data-\[state\=open\]\:bg-surface-container-high[data-state="open"] {
4560
4569
  background-color: var(--color-surface-container-high);
4561
4570
  }
4571
+ .data-\[state\=open\]\:text-foreground[data-state="open"] {
4572
+ color: var(--color-foreground);
4573
+ }
4562
4574
  .data-\[state\=open\]\:text-muted-foreground[data-state="open"] {
4563
4575
  color: var(--color-muted-foreground);
4564
4576
  }
package/dist/workbench.js CHANGED
@@ -20,7 +20,7 @@ import "./chunk-WYMAC3T3.js";
20
20
  import "./chunk-KEYPUGS3.js";
21
21
  import "./chunk-4ZZUMXPX.js";
22
22
  import "./chunk-WSN2RZC6.js";
23
- import "./chunk-FWSBQLFG.js";
23
+ import "./chunk-WMVUJ5SA.js";
24
24
  import "./chunk-5XRAKVIV.js";
25
25
  import "./chunk-EI44GEQ5.js";
26
26
  import "./chunk-CZ7CSFO4.js";
package/dist/workflows.js CHANGED
@@ -5,7 +5,7 @@ import {
5
5
  buildWorkflowGraph,
6
6
  triggerNodeId,
7
7
  triggerNodeIndex
8
- } from "./chunk-O7MHUR4U.js";
8
+ } from "./chunk-LHUBJPZR.js";
9
9
  import {
10
10
  ModelBrandStack,
11
11
  modelBrandFor
@@ -36,7 +36,7 @@ function retryImport(factory, retries = 2, delayMs = 350) {
36
36
  function lazyWorkflowGraph() {
37
37
  return lazy(
38
38
  () => retryImport(
39
- () => import("./WorkflowGraph-MPNVC5FE.js").then((m) => ({ default: m.WorkflowGraph }))
39
+ () => import("./WorkflowGraph-OPLQFAJK.js").then((m) => ({ default: m.WorkflowGraph }))
40
40
  )
41
41
  );
42
42
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.95.1",
3
+ "version": "0.96.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",