@tangle-network/sandbox-ui 0.31.0 → 0.33.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/pages.js CHANGED
@@ -4,7 +4,7 @@ import {
4
4
  PricingPage,
5
5
  TemplateCard,
6
6
  UsageChart
7
- } from "./chunk-DNZ4DTNA.js";
7
+ } from "./chunk-2XNT74ZX.js";
8
8
  import {
9
9
  Badge,
10
10
  Button,
@@ -23,7 +23,7 @@ import {
23
23
  Switch,
24
24
  Textarea
25
25
  } from "./chunk-7ZA5SEK3.js";
26
- import "./chunk-6NQBODYV.js";
26
+ import "./chunk-NMR2CTGP.js";
27
27
  import {
28
28
  cn
29
29
  } from "./chunk-EI44GEQ5.js";
@@ -583,7 +583,7 @@ function AddSshKeyDialog({
583
583
  placeholder: "My laptop",
584
584
  autoComplete: "off",
585
585
  "aria-invalid": errors.name ? true : void 0,
586
- className: "w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
586
+ className: "w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
587
587
  }
588
588
  ),
589
589
  errors.name && /* @__PURE__ */ jsx3("p", { className: "text-xs text-destructive", children: errors.name })
@@ -608,7 +608,7 @@ function AddSshKeyDialog({
608
608
  autoComplete: "off",
609
609
  spellCheck: false,
610
610
  "aria-invalid": errors.publicKey ? true : void 0,
611
- className: "min-h-24 w-full resize-y rounded-md border border-border bg-card px-3 py-2 font-mono text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
611
+ className: "min-h-24 w-full resize-y rounded-md border border-border bg-card px-3 py-2 font-mono text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
612
612
  }
613
613
  ),
614
614
  errors.publicKey && /* @__PURE__ */ jsx3("p", { className: "text-xs text-destructive", children: errors.publicKey })
@@ -2840,7 +2840,7 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2840
2840
  onChange: (e) => setNewName(e.target.value.toUpperCase().replace(/[^A-Z0-9_]/g, "_")),
2841
2841
  placeholder: "MY_SECRET_KEY",
2842
2842
  autoComplete: "off",
2843
- className: "w-full rounded-md border border-border bg-card px-3 py-2.5 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2843
+ className: "w-full rounded-md border border-border bg-card px-3 py-2.5 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
2844
2844
  }
2845
2845
  )
2846
2846
  ] }),
@@ -2857,7 +2857,7 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2857
2857
  onChange: (e) => setNewValue(e.target.value),
2858
2858
  placeholder: "Enter secret value...",
2859
2859
  autoComplete: "new-password",
2860
- className: "w-full rounded-md border border-border bg-card px-3 py-2.5 pr-10 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2860
+ className: "w-full rounded-md border border-border bg-card px-3 py-2.5 pr-10 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
2861
2861
  }
2862
2862
  ),
2863
2863
  /* @__PURE__ */ jsx7(
@@ -2965,7 +2965,7 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2965
2965
  onChange: (e) => setImportText(e.target.value),
2966
2966
  rows: 6,
2967
2967
  spellCheck: false,
2968
- className: "w-full rounded-md border border-border bg-card px-3 py-2 font-mono text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2968
+ className: "w-full rounded-md border border-border bg-card px-3 py-2 font-mono text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
2969
2969
  }
2970
2970
  ),
2971
2971
  /* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-muted-foreground", children: [
@@ -3699,7 +3699,7 @@ function StartupScriptsPage({ apiClient, className }) {
3699
3699
  onChange: (e) => setFormData((p) => ({ ...p, name: e.target.value })),
3700
3700
  placeholder: "Install Claude Code",
3701
3701
  maxLength: 64,
3702
- className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
3702
+ className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
3703
3703
  }
3704
3704
  )
3705
3705
  ] }),
@@ -3713,7 +3713,7 @@ function StartupScriptsPage({ apiClient, className }) {
3713
3713
  onChange: (e) => setFormData((p) => ({ ...p, description: e.target.value })),
3714
3714
  placeholder: "Sets up Claude Code with authentication",
3715
3715
  maxLength: 256,
3716
- className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
3716
+ className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
3717
3717
  }
3718
3718
  )
3719
3719
  ] }),
@@ -3750,7 +3750,7 @@ function StartupScriptsPage({ apiClient, className }) {
3750
3750
  onChange: (e) => setFormData((p) => ({ ...p, content: e.target.value })),
3751
3751
  rows: 12,
3752
3752
  spellCheck: false,
3753
- className: "mt-1.5 w-full rounded-lg border border-border bg-[var(--depth-1,hsl(var(--muted)))] px-4 py-3 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 resize-y"
3753
+ className: "mt-1.5 w-full rounded-lg border border-border bg-[var(--depth-1,hsl(var(--muted)))] px-4 py-3 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring resize-y"
3754
3754
  }
3755
3755
  ),
3756
3756
  /* @__PURE__ */ jsxs9("p", { className: "mt-1 text-xs text-muted-foreground", children: [
@@ -3838,7 +3838,7 @@ function StartupScriptsPage({ apiClient, className }) {
3838
3838
  placeholder: "Any",
3839
3839
  min: 0.5,
3840
3840
  step: 0.5,
3841
- className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
3841
+ className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
3842
3842
  }
3843
3843
  )
3844
3844
  ] }),
@@ -3859,7 +3859,7 @@ function StartupScriptsPage({ apiClient, className }) {
3859
3859
  placeholder: "Any",
3860
3860
  min: 1,
3861
3861
  step: 1,
3862
- className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
3862
+ className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
3863
3863
  }
3864
3864
  )
3865
3865
  ] })
@@ -3878,7 +3878,7 @@ function StartupScriptsPage({ apiClient, className }) {
3878
3878
  onChange: (e) => setFormData((p) => ({ ...p, runOrder: e.target.value ? Math.max(0, Number(e.target.value)) : 0 })),
3879
3879
  min: 0,
3880
3880
  max: 9999,
3881
- className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
3881
+ className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
3882
3882
  }
3883
3883
  ),
3884
3884
  /* @__PURE__ */ jsx9("p", { className: "mt-1 text-xs text-muted-foreground", children: "Lower runs first" })
@@ -3896,7 +3896,7 @@ function StartupScriptsPage({ apiClient, className }) {
3896
3896
  onChange: (e) => setFormData((p) => ({ ...p, timeoutSeconds: e.target.value ? Math.max(5, Number(e.target.value)) : 300 })),
3897
3897
  min: 5,
3898
3898
  max: 3600,
3899
- className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
3899
+ className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus-visible:ring-1 focus-visible:ring-ring"
3900
3900
  }
3901
3901
  )
3902
3902
  ] })
@@ -1,4 +1,5 @@
1
1
  import '@tangle-network/ui/sdk-hooks';
2
+ import { ReasoningEffort } from '@tangle-network/agent-interface';
2
3
  import { SessionMessage, SessionPart } from '@tangle-network/ui/types';
3
4
 
4
5
  /** Minimal session info returned by the listing API. */
@@ -32,8 +33,10 @@ interface SendMessageOptions {
32
33
  };
33
34
  /** Per-turn system prompt override. */
34
35
  system?: string;
35
- /** Thinking-effort hint; the sidecar maps it to a thinking-token budget. */
36
- reasoningEffort?: 'low' | 'medium' | 'high';
36
+ /** Thinking-effort hint; the sidecar maps it to a thinking-token budget. The full canonical
37
+ * `ReasoningEffort` (`@tangle-network/agent-interface`) — the UI shows only the levels the
38
+ * selected harness/model actually supports (a capability filter), never a hard-coded subset. */
39
+ reasoningEffort?: ReasoningEffort;
37
40
  }
38
41
  interface UseSessionStreamResult {
39
42
  /** All messages in the session (fetched + streaming). */
@@ -1,3 +1,4 @@
1
1
  export { AgentStreamEvent, AppendUserMessageOptions, ApplySdkEventOptions, AutomationStreamEvent, BeginAssistantMessageOptions, BotStreamEvent, CompleteAssistantMessageOptions, ConnectionState, RealtimeSessionOptions, RealtimeSessionRegistry, RealtimeSessionRegistryProps, RealtimeSessionState, RealtimeSessionTarget, SSEEvent, SdkSessionAttachment, SdkSessionEvent, SdkSessionSeed, TaskStreamEvent, TerminalStreamEvent, UseRunGroupsOptions, UseSSEStreamOptions, UseSSEStreamResult, UseSdkSessionOptions, UseSdkSessionReturn, UseToolCallStreamReturn, useAutoScroll, useDropdownMenu, useRealtimeSession, useRunCollapseState, useRunGroups, useSSEStream, useSdkSession, useToolCallStream } from '@tangle-network/ui/sdk-hooks';
2
- export { S as SessionInfo, a as SidecarAuth, U as UseSessionStreamOptions, b as UseSessionStreamResult, c as UseSidecarAuthOptions, u as useSessionStream, d as useSidecarAuth } from './sdk-hooks-jUbIngSV.js';
2
+ export { S as SessionInfo, a as SidecarAuth, U as UseSessionStreamOptions, b as UseSessionStreamResult, c as UseSidecarAuthOptions, u as useSessionStream, d as useSidecarAuth } from './sdk-hooks-VtiMwKa6.js';
3
+ import '@tangle-network/agent-interface';
3
4
  import '@tangle-network/ui/types';
package/dist/styles.css CHANGED
@@ -301,9 +301,6 @@
301
301
  .end {
302
302
  inset-inline-end: var(--spacing);
303
303
  }
304
- .-top-1 {
305
- top: calc(var(--spacing) * -1);
306
- }
307
304
  .-top-1\.5 {
308
305
  top: calc(var(--spacing) * -1.5);
309
306
  }
@@ -346,9 +343,6 @@
346
343
  .top-full {
347
344
  top: 100%;
348
345
  }
349
- .-right-1 {
350
- right: calc(var(--spacing) * -1);
351
- }
352
346
  .-right-1\.5 {
353
347
  right: calc(var(--spacing) * -1.5);
354
348
  }
@@ -2268,6 +2262,9 @@
2268
2262
  .py-8 {
2269
2263
  padding-block: calc(var(--spacing) * 8);
2270
2264
  }
2265
+ .py-10 {
2266
+ padding-block: calc(var(--spacing) * 10);
2267
+ }
2271
2268
  .py-12 {
2272
2269
  padding-block: calc(var(--spacing) * 12);
2273
2270
  }
@@ -2904,10 +2901,6 @@
2904
2901
  --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));
2905
2902
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2906
2903
  }
2907
- .shadow-xl {
2908
- --tw-shadow: 0 20px 25px -5px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 8px 10px -6px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
2909
- box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
2910
- }
2911
2904
  .ring {
2912
2905
  --tw-ring-shadow: var(--tw-ring-inset,) 0 0 0 calc(1px + var(--tw-ring-offset-width)) var(--tw-ring-color, currentcolor);
2913
2906
  box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
@@ -2977,6 +2970,11 @@
2977
2970
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
2978
2971
  transition-duration: var(--tw-duration, var(--default-transition-duration));
2979
2972
  }
2973
+ .transition-\[opacity\,transform\] {
2974
+ transition-property: opacity,transform;
2975
+ transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
2976
+ transition-duration: var(--tw-duration, var(--default-transition-duration));
2977
+ }
2980
2978
  .transition-\[opacity\] {
2981
2979
  transition-property: opacity;
2982
2980
  transition-timing-function: var(--tw-ease, var(--default-transition-timing-function));
@@ -3064,6 +3062,17 @@
3064
3062
  rotate: 180deg;
3065
3063
  }
3066
3064
  }
3065
+ .group-focus-within\/tip\:translate-x-0 {
3066
+ &:is(:where(.group\/tip):focus-within *) {
3067
+ --tw-translate-x: calc(var(--spacing) * 0);
3068
+ translate: var(--tw-translate-x) var(--tw-translate-y);
3069
+ }
3070
+ }
3071
+ .group-focus-within\/tip\:opacity-100 {
3072
+ &:is(:where(.group\/tip):focus-within *) {
3073
+ opacity: 100%;
3074
+ }
3075
+ }
3067
3076
  .group-hover\:translate-x-0\.5 {
3068
3077
  &:is(:where(.group):hover *) {
3069
3078
  @media (hover: hover) {
@@ -3079,6 +3088,28 @@
3079
3088
  }
3080
3089
  }
3081
3090
  }
3091
+ .group-hover\/tip\:translate-x-0 {
3092
+ &:is(:where(.group\/tip):hover *) {
3093
+ @media (hover: hover) {
3094
+ --tw-translate-x: calc(var(--spacing) * 0);
3095
+ translate: var(--tw-translate-x) var(--tw-translate-y);
3096
+ }
3097
+ }
3098
+ }
3099
+ .group-hover\/tip\:opacity-100 {
3100
+ &:is(:where(.group\/tip):hover *) {
3101
+ @media (hover: hover) {
3102
+ opacity: 100%;
3103
+ }
3104
+ }
3105
+ }
3106
+ .group-hover\/tip\:delay-300 {
3107
+ &:is(:where(.group\/tip):hover *) {
3108
+ @media (hover: hover) {
3109
+ transition-delay: 300ms;
3110
+ }
3111
+ }
3112
+ }
3082
3113
  .peer-disabled\:cursor-not-allowed {
3083
3114
  &:is(:where(.peer):disabled ~ *) {
3084
3115
  cursor: not-allowed;
@@ -3402,14 +3433,6 @@
3402
3433
  }
3403
3434
  }
3404
3435
  }
3405
- .hover\:shadow-md {
3406
- &:hover {
3407
- @media (hover: hover) {
3408
- --tw-shadow: 0 4px 6px -1px var(--tw-shadow-color, rgb(0 0 0 / 0.1)), 0 2px 4px -2px var(--tw-shadow-color, rgb(0 0 0 / 0.1));
3409
- box-shadow: var(--tw-inset-shadow), var(--tw-inset-ring-shadow), var(--tw-ring-offset-shadow), var(--tw-ring-shadow), var(--tw-shadow);
3410
- }
3411
- }
3412
- }
3413
3436
  .hover\:shadow-sm {
3414
3437
  &:hover {
3415
3438
  @media (hover: hover) {
@@ -3433,6 +3456,11 @@
3433
3456
  }
3434
3457
  }
3435
3458
  }
3459
+ .focus\:border-\[var\(--border-accent\)\] {
3460
+ &:focus {
3461
+ border-color: var(--border-accent);
3462
+ }
3463
+ }
3436
3464
  .focus\:border-\[var\(--border-accent-hover\)\] {
3437
3465
  &:focus {
3438
3466
  border-color: var(--border-accent-hover);
@@ -3494,6 +3522,16 @@
3494
3522
  outline-style: none;
3495
3523
  }
3496
3524
  }
3525
+ .focus-visible\:border-\[var\(--border-accent\)\] {
3526
+ &:focus-visible {
3527
+ border-color: var(--border-accent);
3528
+ }
3529
+ }
3530
+ .focus-visible\:bg-transparent {
3531
+ &:focus-visible {
3532
+ background-color: transparent;
3533
+ }
3534
+ }
3497
3535
  .focus-visible\:opacity-100 {
3498
3536
  &:focus-visible {
3499
3537
  opacity: 100%;
@@ -4455,7 +4493,7 @@
4455
4493
  "ss01" 1;
4456
4494
  }
4457
4495
  ::selection {
4458
- background: rgba(56, 178, 172, 0.22);
4496
+ background: var(--bg-selection);
4459
4497
  color: hsl(var(--hsl-foreground));
4460
4498
  }
4461
4499
  ::-webkit-scrollbar {
@@ -4466,12 +4504,16 @@
4466
4504
  background: transparent;
4467
4505
  }
4468
4506
  ::-webkit-scrollbar-thumb {
4469
- background: hsl(var(--border) / 0.7);
4470
- border-radius: 3px;
4507
+ background: hsl(var(--border) / 0.6);
4508
+ border-radius: 9999px;
4471
4509
  }
4472
4510
  ::-webkit-scrollbar-thumb:hover {
4473
4511
  background: hsl(var(--muted-foreground) / 0.4);
4474
4512
  }
4513
+ * {
4514
+ scrollbar-width: thin;
4515
+ scrollbar-color: hsl(var(--border) / 0.6) transparent;
4516
+ }
4475
4517
  }
4476
4518
  @layer utilities {
4477
4519
  .text-gradient-sandbox {
@@ -4481,7 +4523,7 @@
4481
4523
  color: transparent;
4482
4524
  }
4483
4525
  .glow-sandbox {
4484
- box-shadow: 0 0 48px -10px hsl(var(--sandbox) / 0.45);
4526
+ box-shadow: none;
4485
4527
  }
4486
4528
  .glass-card {
4487
4529
  background: hsl(var(--card));
@@ -4496,31 +4538,26 @@
4496
4538
  border: 1px solid hsl(var(--border));
4497
4539
  }
4498
4540
  .glass-panel {
4499
- background: hsl(var(--card) / 0.4);
4500
- backdrop-filter: blur(20px);
4501
- -webkit-backdrop-filter: blur(20px);
4502
- border: 1px solid hsl(var(--primary) / 0.1);
4503
- box-shadow: 0 4px 30px hsl(var(--background) / 0.3);
4541
+ background: hsl(var(--card));
4542
+ border: 1px solid hsl(var(--border));
4543
+ box-shadow: var(--shadow-card);
4504
4544
  }
4505
4545
  .glass-panel-heavy {
4506
- background: hsl(var(--card) / 0.7);
4507
- backdrop-filter: blur(24px);
4508
- -webkit-backdrop-filter: blur(24px);
4509
- border: 1px solid hsl(var(--primary) / 0.12);
4510
- box-shadow: 0 8px 32px hsl(var(--background) / 0.5);
4546
+ background: hsl(var(--card));
4547
+ border: 1px solid hsl(var(--border));
4548
+ box-shadow: var(--shadow-card);
4511
4549
  }
4512
4550
  .glass-panel:hover {
4513
- border-color: hsl(var(--primary) / 0.25);
4551
+ border-color: hsl(var(--border));
4514
4552
  }
4515
4553
  .glow-primary {
4516
- box-shadow: 0 0 40px hsl(var(--primary) / 0.25);
4517
- transition: box-shadow 0.4s ease-in-out;
4554
+ box-shadow: none;
4518
4555
  }
4519
4556
  .glow-primary:hover {
4520
- box-shadow: 0 0 60px hsl(var(--primary) / 0.4);
4557
+ box-shadow: none;
4521
4558
  }
4522
4559
  .text-glow {
4523
- text-shadow: 0 0 16px hsl(var(--primary) / 0.6);
4560
+ text-shadow: none;
4524
4561
  }
4525
4562
  .gradient-text {
4526
4563
  background: linear-gradient(135deg, hsl(var(--primary) / 0.7) 0%, hsl(var(--primary)) 100%);
@@ -4532,12 +4569,7 @@
4532
4569
  background: linear-gradient(135deg, hsl(var(--primary) / 0.1) 0%, hsl(var(--primary) / 0.05) 100%);
4533
4570
  }
4534
4571
  .neural-mesh {
4535
- background-image: radial-gradient(
4536
- circle at 2px 2px,
4537
- hsl(var(--primary) / 0.07) 1px,
4538
- transparent 0
4539
- );
4540
- background-size: 32px 32px;
4572
+ background-image: none;
4541
4573
  }
4542
4574
  .nav-active-indicator {
4543
4575
  position: relative;
@@ -4552,7 +4584,6 @@
4552
4584
  width: 3px;
4553
4585
  background-color: hsl(var(--primary));
4554
4586
  border-radius: 0 4px 4px 0;
4555
- box-shadow: 0 0 10px hsl(var(--primary));
4556
4587
  }
4557
4588
  .glass {
4558
4589
  background-color: var(--depth-2);
@@ -4562,17 +4593,10 @@
4562
4593
  position: relative;
4563
4594
  }
4564
4595
  .bg-mesh::before {
4565
- content: '';
4566
- position: absolute;
4567
- inset: 0;
4568
- background: radial-gradient(ellipse 80% 50% at 20% 40%, var(--mesh-teal), transparent),
4569
- radial-gradient(ellipse 60% 40% at 80% 20%, var(--mesh-violet), transparent),
4570
- radial-gradient(ellipse 50% 60% at 50% 80%, var(--mesh-blue), transparent);
4571
- pointer-events: none;
4572
- z-index: 0;
4596
+ content: none;
4573
4597
  }
4574
4598
  .noise {
4575
- background-image: url("data:image/svg+xml,%3Csvg viewBox='0 0 256 256' xmlns='http://www.w3.org/2000/svg'%3E%3Cfilter id='noise'%3E%3CfeTurbulence type='fractalNoise' baseFrequency='0.9' numOctaves='4' stitchTiles='stitch'/%3E%3C/filter%3E%3Crect width='100%25' height='100%25' filter='url(%23noise)' opacity='0.025'/%3E%3C/svg%3E");
4599
+ background-image: none;
4576
4600
  pointer-events: none;
4577
4601
  }
4578
4602
  .status-dot {
@@ -4584,7 +4608,6 @@
4584
4608
  }
4585
4609
  .status-dot-running {
4586
4610
  background: var(--status-running);
4587
- box-shadow: var(--shadow-status-running);
4588
4611
  }
4589
4612
  .status-dot-creating {
4590
4613
  background: var(--status-creating);
@@ -4601,7 +4624,6 @@
4601
4624
  }
4602
4625
  .status-dot-error {
4603
4626
  background: var(--status-error);
4604
- box-shadow: var(--shadow-status-error);
4605
4627
  }
4606
4628
  .status-dot-deleted {
4607
4629
  background: var(--status-deleted);
@@ -4627,6 +4649,19 @@
4627
4649
  .animate-in {
4628
4650
  animation: fade-in 0.25s ease-out;
4629
4651
  }
4652
+ .animate-row-in {
4653
+ animation: row-in 0.18s ease-out;
4654
+ }
4655
+ @keyframes row-in {
4656
+ from {
4657
+ opacity: 0;
4658
+ transform: translateY(-4px);
4659
+ }
4660
+ to {
4661
+ opacity: 1;
4662
+ transform: translateY(0);
4663
+ }
4664
+ }
4630
4665
  .pulse-ring {
4631
4666
  position: relative;
4632
4667
  }
package/dist/workspace.js CHANGED
@@ -19,7 +19,7 @@ import {
19
19
  dispatchSessionCreated,
20
20
  shellShouldRevalidate,
21
21
  useOptimisticSessionItems
22
- } from "./chunk-AUFV7766.js";
22
+ } from "./chunk-6NDOA4SB.js";
23
23
  import "./chunk-EI44GEQ5.js";
24
24
  export {
25
25
  AgentWorkbench,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/sandbox-ui",
3
- "version": "0.31.0",
3
+ "version": "0.33.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",
@@ -117,7 +117,8 @@
117
117
  "@tangle-network/brand": "^0.4.0",
118
118
  "@tangle-network/ui": "^1.0.1",
119
119
  "react": "^18 || ^19",
120
- "react-dom": "^18 || ^19"
120
+ "react-dom": "^18 || ^19",
121
+ "@tangle-network/agent-interface": "^0.9.0"
121
122
  },
122
123
  "peerDependenciesMeta": {
123
124
  "@xterm/xterm": {
@@ -197,6 +198,7 @@
197
198
  "typescript": "^5.8.3",
198
199
  "vite": "^8.0.5",
199
200
  "vitest": "^4.1.3",
200
- "yjs": "^13.6.30"
201
+ "yjs": "^13.6.30",
202
+ "@tangle-network/agent-interface": "^0.9.0"
201
203
  }
202
204
  }
@@ -1,63 +0,0 @@
1
- import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode } from 'react';
3
-
4
- interface Backend {
5
- type: string;
6
- label: string;
7
- description?: string;
8
- /** Optional leading brand glyph (e.g. a HarnessLogo) shown in the trigger and rows. */
9
- icon?: ReactNode;
10
- }
11
- interface BackendSelectorProps {
12
- backends: Backend[];
13
- selected: string;
14
- onChange: (selected: string) => void;
15
- label?: string;
16
- placeholder?: string;
17
- className?: string;
18
- }
19
- declare function BackendSelector({ backends, selected, onChange, label, placeholder, className, }: BackendSelectorProps): react_jsx_runtime.JSX.Element;
20
-
21
- /**
22
- * Sandbox agent harness types — mirrors `BackendType` from
23
- * `@tangle-network/sandbox` SDK. Kept in lockstep with that enum:
24
- * if the SDK adds a backend, add it here too. The SDK's `pi`, `forge`,
25
- * `acp`, and `cursor` backends are deliberately deferred (not yet
26
- * surfaced in the picker) until their copy and compat policies land.
27
- */
28
- type HarnessType = "opencode" | "claude-code" | "codex" | "amp" | "factory-droids" | "cli-base" | "kimi-code" | "openclaw" | "nanoclaw" | "hermes";
29
- interface HarnessOption extends Backend {
30
- type: HarnessType;
31
- /**
32
- * Whether this harness can drive an interactive chat session. `false` for
33
- * shell-only backends (`cli-base`) that have no conversational agent — the
34
- * chat composer filters these out (see {@link chatCapableHarnesses}) while
35
- * scheduled/non-chat surfaces keep them.
36
- */
37
- chatCapable: boolean;
38
- }
39
- /**
40
- * Default option list with human-readable copy. Order is curated so the
41
- * recommended choice (`opencode`) appears first; `cli-base` (no agent) last.
42
- */
43
- declare const HARNESS_OPTIONS: readonly HarnessOption[];
44
- /** Harness types that can drive an interactive chat session. */
45
- declare const chatCapableHarnesses: ReadonlyArray<HarnessType>;
46
- interface HarnessPickerProps extends Omit<BackendSelectorProps, "backends" | "selected" | "onChange"> {
47
- value: HarnessType;
48
- onChange: (next: HarnessType) => void;
49
- /** Filter the available harnesses (e.g. by plan tier). Defaults to all. */
50
- available?: ReadonlyArray<HarnessType>;
51
- /** Override or extend the option metadata. Keys are HarnessType. */
52
- optionsOverride?: Partial<Record<HarnessType, Partial<Omit<HarnessOption, "type">>>>;
53
- }
54
- /**
55
- * Type-safe harness/backend selector for sandbox-backed agent products.
56
- *
57
- * Wraps the generic {@link BackendSelector} with the canonical harness list
58
- * baked in, so consumers don't have to re-declare it (or risk drifting from
59
- * the SDK enum).
60
- */
61
- declare function HarnessPicker({ value, onChange, available, optionsOverride, label, ...rest }: HarnessPickerProps): react_jsx_runtime.JSX.Element;
62
-
63
- export { type Backend as B, HARNESS_OPTIONS as H, BackendSelector as a, type BackendSelectorProps as b, HarnessPicker as c, type HarnessPickerProps as d, type HarnessType as e, chatCapableHarnesses as f };