@tangle-network/sandbox-ui 0.28.0 → 0.30.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/{chunk-I3IVCGND.js → chunk-AUFV7766.js} +118 -26
- package/dist/{chunk-F2M5MN7K.js → chunk-YPBFIETY.js} +16 -16
- package/dist/dashboard.d.ts +3 -3
- package/dist/dashboard.js +1 -1
- package/dist/globals.css +132 -123
- package/dist/index.d.ts +1 -1
- package/dist/index.js +13 -3
- package/dist/styles.css +132 -123
- package/dist/tokens.css +145 -141
- package/dist/workspace.d.ts +153 -3
- package/dist/workspace.js +13 -3
- package/package.json +3 -3
package/dist/tokens.css
CHANGED
|
@@ -45,25 +45,25 @@
|
|
|
45
45
|
--md3-inverse-on-surface: #000000;
|
|
46
46
|
--md3-surface-tint: #818CF8;
|
|
47
47
|
|
|
48
|
-
/* Semantic HSL bridge */
|
|
49
|
-
--hsl-background:
|
|
50
|
-
--hsl-foreground: 240
|
|
51
|
-
--hsl-card:
|
|
52
|
-
--hsl-card-foreground: 240
|
|
53
|
-
--hsl-popover:
|
|
54
|
-
--hsl-popover-foreground: 240
|
|
48
|
+
/* Semantic HSL bridge — flat neutral spine (Tangle Quiet) */
|
|
49
|
+
--hsl-background: 240 8% 5%; /* #0b0b0d */
|
|
50
|
+
--hsl-foreground: 240 6% 93%; /* #ececee */
|
|
51
|
+
--hsl-card: 240 5% 8%; /* #141416 surface */
|
|
52
|
+
--hsl-card-foreground: 240 6% 93%;
|
|
53
|
+
--hsl-popover: 240 4% 13%; /* #202023 elevated */
|
|
54
|
+
--hsl-popover-foreground: 240 6% 93%;
|
|
55
55
|
--hsl-primary: 239 84% 67%;
|
|
56
56
|
--hsl-primary-foreground: 0 0% 100%;
|
|
57
|
-
--hsl-secondary:
|
|
58
|
-
--hsl-secondary-foreground: 240
|
|
59
|
-
--hsl-muted:
|
|
60
|
-
--hsl-muted-foreground: 240
|
|
61
|
-
--hsl-accent:
|
|
62
|
-
--hsl-accent-foreground: 240
|
|
57
|
+
--hsl-secondary: 240 5% 11%; /* #1a1a1d surface-2 */
|
|
58
|
+
--hsl-secondary-foreground: 240 6% 93%;
|
|
59
|
+
--hsl-muted: 240 5% 11%; /* #1a1a1d — neutral hover well */
|
|
60
|
+
--hsl-muted-foreground: 240 4% 62%; /* #9a9aa2 text-muted */
|
|
61
|
+
--hsl-accent: 240 5% 11%; /* neutral hover (indigo lives in accent-surface-strong) */
|
|
62
|
+
--hsl-accent-foreground: 240 6% 93%;
|
|
63
63
|
--hsl-destructive: 348 90% 60%;
|
|
64
64
|
--hsl-destructive-foreground: 0 0% 100%;
|
|
65
|
-
--hsl-border:
|
|
66
|
-
--hsl-input:
|
|
65
|
+
--hsl-border: 240 3% 13%; /* hairline ≈ rgba(255,255,255,0.07) */
|
|
66
|
+
--hsl-input: 240 5% 11%;
|
|
67
67
|
--hsl-ring: 239 84% 67%;
|
|
68
68
|
--hsl-success: 160 84% 39%;
|
|
69
69
|
--hsl-warning: 40 94% 56%;
|
|
@@ -94,21 +94,21 @@
|
|
|
94
94
|
--error: var(--hsl-destructive);
|
|
95
95
|
--info: var(--hsl-info);
|
|
96
96
|
|
|
97
|
-
/* Sidebar tokens */
|
|
98
|
-
--sidebar-background:
|
|
99
|
-
--sidebar-foreground: 240
|
|
97
|
+
/* Sidebar tokens — flat surface + hairline */
|
|
98
|
+
--sidebar-background: 240 5% 8%; /* #141416 surface */
|
|
99
|
+
--sidebar-foreground: 240 6% 93%;
|
|
100
100
|
--sidebar-primary: 239 84% 67%;
|
|
101
101
|
--sidebar-primary-foreground: 0 0% 100%;
|
|
102
|
-
--sidebar-accent:
|
|
103
|
-
--sidebar-accent-foreground: 240
|
|
104
|
-
--sidebar-border:
|
|
102
|
+
--sidebar-accent: 240 5% 11%; /* neutral hover */
|
|
103
|
+
--sidebar-accent-foreground: 240 6% 93%;
|
|
104
|
+
--sidebar-border: 240 3% 13%; /* hairline */
|
|
105
105
|
--sidebar-ring: 239 84% 67%;
|
|
106
106
|
|
|
107
|
-
/* Depth scale —
|
|
108
|
-
--depth-1: #
|
|
109
|
-
--depth-2: #
|
|
110
|
-
--depth-3: #
|
|
111
|
-
--depth-4: #
|
|
107
|
+
/* Depth scale — flat neutral spine (Tangle Quiet) */
|
|
108
|
+
--depth-1: #0b0b0d;
|
|
109
|
+
--depth-2: #141416;
|
|
110
|
+
--depth-3: #1a1a1d;
|
|
111
|
+
--depth-4: #202023;
|
|
112
112
|
|
|
113
113
|
/* Status colors */
|
|
114
114
|
--status-running: #10B981;
|
|
@@ -152,36 +152,35 @@
|
|
|
152
152
|
--glass-border-hover: var(--border-default);
|
|
153
153
|
--glass-blur: 0px;
|
|
154
154
|
|
|
155
|
-
/* Mesh
|
|
156
|
-
--mesh-teal:
|
|
157
|
-
--mesh-violet:
|
|
158
|
-
--mesh-blue:
|
|
155
|
+
/* Mesh glows — quieted to off; chrome is flat in Tangle Quiet */
|
|
156
|
+
--mesh-teal: transparent;
|
|
157
|
+
--mesh-violet: transparent;
|
|
158
|
+
--mesh-blue: transparent;
|
|
159
159
|
|
|
160
|
-
/* Brand gradients —
|
|
160
|
+
/* Brand gradients — the indigo spark, kept ONLY for the logo mark + send button */
|
|
161
161
|
--tangle-gradient: linear-gradient(135deg, #6366F1, #818CF8);
|
|
162
162
|
--tangle-gradient-text: linear-gradient(135deg, #A5AAFC, #818CF8);
|
|
163
163
|
--accent-gradient-strong: linear-gradient(135deg, #6366F1, #818CF8);
|
|
164
|
-
|
|
165
|
-
--accent-surface-
|
|
166
|
-
--accent-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
linear-gradient(180deg, var(--depth-1), #0D0C1E 100%);
|
|
164
|
+
/* Accent wells — soft = hover neutral, strong = active/selected row (indigo) */
|
|
165
|
+
--accent-surface-soft: rgba(255, 255, 255, 0.04);
|
|
166
|
+
--accent-surface-strong: rgba(129, 140, 248, 0.14);
|
|
167
|
+
--accent-text: #b9bffb;
|
|
168
|
+
|
|
169
|
+
/* Surfaces — flat single-neutral (no radial mesh) */
|
|
170
|
+
--bg-root: #0b0b0d;
|
|
172
171
|
--bg-dark: var(--depth-1);
|
|
173
|
-
--bg-card:
|
|
174
|
-
--bg-elevated:
|
|
175
|
-
--bg-section:
|
|
176
|
-
--bg-input:
|
|
177
|
-
--bg-hover: rgba(
|
|
178
|
-
--bg-selection: rgba(
|
|
179
|
-
|
|
180
|
-
/* Text */
|
|
181
|
-
--text-primary:
|
|
182
|
-
--text-secondary:
|
|
183
|
-
--text-muted: #
|
|
184
|
-
--text-dim: #
|
|
172
|
+
--bg-card: var(--depth-2);
|
|
173
|
+
--bg-elevated: var(--depth-4);
|
|
174
|
+
--bg-section: var(--depth-1);
|
|
175
|
+
--bg-input: var(--depth-3);
|
|
176
|
+
--bg-hover: rgba(255, 255, 255, 0.04);
|
|
177
|
+
--bg-selection: rgba(129, 140, 248, 0.14);
|
|
178
|
+
|
|
179
|
+
/* Text — neutral */
|
|
180
|
+
--text-primary: #ececee;
|
|
181
|
+
--text-secondary: #c8c8cd;
|
|
182
|
+
--text-muted: #9a9aa2;
|
|
183
|
+
--text-dim: #6b6b73;
|
|
185
184
|
|
|
186
185
|
/* Brand accents — Tangle */
|
|
187
186
|
--brand-primary: #6366F1;
|
|
@@ -195,12 +194,12 @@
|
|
|
195
194
|
--brand-vibrant: #6366F1;
|
|
196
195
|
--brand-emerald: #10B981;
|
|
197
196
|
|
|
198
|
-
/* Borders */
|
|
199
|
-
--border-subtle: rgba(
|
|
200
|
-
--border-default: rgba(
|
|
201
|
-
--border-hover: rgba(
|
|
202
|
-
--border-accent: rgba(
|
|
203
|
-
--border-accent-hover: rgba(
|
|
197
|
+
/* Borders — neutral hairlines */
|
|
198
|
+
--border-subtle: rgba(255, 255, 255, 0.05);
|
|
199
|
+
--border-default: rgba(255, 255, 255, 0.07);
|
|
200
|
+
--border-hover: rgba(255, 255, 255, 0.12);
|
|
201
|
+
--border-accent: rgba(129, 140, 248, 0.20);
|
|
202
|
+
--border-accent-hover: rgba(129, 140, 248, 0.35);
|
|
204
203
|
|
|
205
204
|
/* Buttons */
|
|
206
205
|
--btn-primary-bg: #6366F1;
|
|
@@ -218,11 +217,11 @@
|
|
|
218
217
|
--code-comment: #606294;
|
|
219
218
|
--code-error: #FF4D6D;
|
|
220
219
|
|
|
221
|
-
/* Shadows */
|
|
222
|
-
--shadow-card: 0 1px
|
|
223
|
-
--shadow-dropdown: 0 8px
|
|
224
|
-
--shadow-glow:
|
|
225
|
-
--shadow-accent: 0 1px
|
|
220
|
+
/* Shadows — flat, no inner ring, no indigo glow */
|
|
221
|
+
--shadow-card: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
222
|
+
--shadow-dropdown: 0 8px 30px rgba(0, 0, 0, 0.45);
|
|
223
|
+
--shadow-glow: none;
|
|
224
|
+
--shadow-accent: 0 1px 2px rgba(0, 0, 0, 0.3);
|
|
226
225
|
--shadow-status-running: 0 0 6px rgba(16, 185, 129, 0.5);
|
|
227
226
|
--shadow-status-creating: 0 0 6px rgba(99, 102, 241, 0.5);
|
|
228
227
|
--shadow-status-error: 0 0 6px rgba(255, 77, 109, 0.5);
|
|
@@ -230,11 +229,12 @@
|
|
|
230
229
|
/* Radii */
|
|
231
230
|
--radius-sm: 6px;
|
|
232
231
|
--radius-md: 8px;
|
|
233
|
-
--radius-lg:
|
|
234
|
-
--radius-xl: 16px
|
|
232
|
+
--radius-lg: 10px;
|
|
233
|
+
--radius-xl: 12px; /* chrome stays tight (was 16px) */
|
|
235
234
|
--radius-pill: 999px;
|
|
236
235
|
--radius-full: 999px;
|
|
237
|
-
--radius:
|
|
236
|
+
--radius-composer: 26px; /* centered composer pill */
|
|
237
|
+
--radius: 0.5rem; /* 8px chrome default (was 10px) */
|
|
238
238
|
|
|
239
239
|
/* Density */
|
|
240
240
|
--control-height: 2.25rem;
|
|
@@ -249,8 +249,8 @@
|
|
|
249
249
|
--font-size-lg: 1rem; /* 16px — emphasized text */
|
|
250
250
|
--font-size-xl: 1.25rem; /* 20px — section headers */
|
|
251
251
|
--line-height-tight: 1.3;
|
|
252
|
-
--line-height-base: 1.
|
|
253
|
-
--line-height-relaxed: 1.
|
|
252
|
+
--line-height-base: 1.6; /* tighter body rhythm (was 1.75) */
|
|
253
|
+
--line-height-relaxed: 1.75;
|
|
254
254
|
|
|
255
255
|
/* Component spacing — override per-app for tighter/looser layouts */
|
|
256
256
|
--avatar-size: 2rem; /* 32px — chat avatars */
|
|
@@ -284,9 +284,9 @@
|
|
|
284
284
|
--transition-default: 0.16s ease;
|
|
285
285
|
--transition-medium: 0.24s ease;
|
|
286
286
|
|
|
287
|
-
/* Fonts */
|
|
288
|
-
--font-sans: "
|
|
289
|
-
--font-display: "
|
|
287
|
+
/* Fonts — unified on Inter (dark + light) */
|
|
288
|
+
--font-sans: "Inter", "Geist", ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
289
|
+
--font-display: "Inter", "Geist", sans-serif;
|
|
290
290
|
--font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
|
|
291
291
|
}
|
|
292
292
|
|
|
@@ -336,34 +336,34 @@
|
|
|
336
336
|
--md3-inverse-on-surface: #f0f1f4;
|
|
337
337
|
--md3-surface-tint: #6366F1;
|
|
338
338
|
|
|
339
|
-
/* Semantic HSL bridge */
|
|
340
|
-
--hsl-background:
|
|
341
|
-
--hsl-foreground:
|
|
342
|
-
--hsl-card:
|
|
343
|
-
--hsl-card-foreground:
|
|
339
|
+
/* Semantic HSL bridge — flat neutral light (Tangle Quiet) */
|
|
340
|
+
--hsl-background: 0 0% 100%; /* #ffffff */
|
|
341
|
+
--hsl-foreground: 0 0% 5%; /* #0d0d0d */
|
|
342
|
+
--hsl-card: 240 7% 97%; /* #f7f7f8 surface */
|
|
343
|
+
--hsl-card-foreground: 0 0% 5%;
|
|
344
344
|
--hsl-popover: 0 0% 100%;
|
|
345
|
-
--hsl-popover-foreground:
|
|
346
|
-
--hsl-primary:
|
|
345
|
+
--hsl-popover-foreground: 0 0% 5%;
|
|
346
|
+
--hsl-primary: 245 62% 57%; /* #5B4ED4 light accent */
|
|
347
347
|
--hsl-primary-foreground: 0 0% 100%;
|
|
348
|
-
--hsl-secondary:
|
|
349
|
-
--hsl-secondary-foreground: 0 0%
|
|
350
|
-
--hsl-muted: 240
|
|
351
|
-
--hsl-muted-foreground: 240
|
|
352
|
-
--hsl-accent:
|
|
353
|
-
--hsl-accent-foreground:
|
|
348
|
+
--hsl-secondary: 240 6% 93%; /* #ececee surface-2 */
|
|
349
|
+
--hsl-secondary-foreground: 0 0% 10%;
|
|
350
|
+
--hsl-muted: 240 6% 93%; /* #ececee neutral hover */
|
|
351
|
+
--hsl-muted-foreground: 240 5% 38%; /* #5d5d66 text-muted */
|
|
352
|
+
--hsl-accent: 240 6% 93%; /* neutral hover */
|
|
353
|
+
--hsl-accent-foreground: 0 0% 10%;
|
|
354
354
|
--hsl-destructive: 0 72% 41%;
|
|
355
355
|
--hsl-destructive-foreground: 0 0% 100%;
|
|
356
|
-
--hsl-border:
|
|
357
|
-
--hsl-input:
|
|
358
|
-
--hsl-ring:
|
|
356
|
+
--hsl-border: 240 6% 89%; /* hairline ≈ rgba(0,0,0,0.08) */
|
|
357
|
+
--hsl-input: 240 6% 89%;
|
|
358
|
+
--hsl-ring: 245 62% 57%;
|
|
359
359
|
--hsl-success: 160 84% 30%;
|
|
360
360
|
--hsl-warning: 41 96% 50%;
|
|
361
361
|
--hsl-info: 212 80% 50%;
|
|
362
362
|
|
|
363
|
-
--depth-1: #
|
|
364
|
-
--depth-2: #
|
|
365
|
-
--depth-3: #
|
|
366
|
-
--depth-4: #
|
|
363
|
+
--depth-1: #ffffff;
|
|
364
|
+
--depth-2: #f7f7f8;
|
|
365
|
+
--depth-3: #ececee;
|
|
366
|
+
--depth-4: #e3e3e6;
|
|
367
367
|
|
|
368
368
|
--status-running: #059669;
|
|
369
369
|
--status-creating: #3E349E;
|
|
@@ -404,33 +404,34 @@
|
|
|
404
404
|
--surface-neutral-border: var(--border-subtle);
|
|
405
405
|
--surface-neutral-text: var(--text-muted);
|
|
406
406
|
|
|
407
|
-
/* Sidebar — light */
|
|
408
|
-
--sidebar-background:
|
|
409
|
-
--sidebar-foreground:
|
|
410
|
-
--sidebar-primary:
|
|
407
|
+
/* Sidebar — light, flat surface + hairline */
|
|
408
|
+
--sidebar-background: 240 7% 97%; /* #f7f7f8 surface */
|
|
409
|
+
--sidebar-foreground: 0 0% 5%;
|
|
410
|
+
--sidebar-primary: 245 62% 57%; /* #5B4ED4 */
|
|
411
411
|
--sidebar-primary-foreground: 0 0% 100%;
|
|
412
|
-
--sidebar-accent: 240
|
|
413
|
-
--sidebar-accent-foreground:
|
|
414
|
-
--sidebar-border:
|
|
415
|
-
--sidebar-ring:
|
|
416
|
-
|
|
417
|
-
--mesh-teal:
|
|
418
|
-
--mesh-violet:
|
|
419
|
-
--mesh-blue:
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
--bg-
|
|
423
|
-
--bg-
|
|
424
|
-
--bg-
|
|
425
|
-
--bg-
|
|
426
|
-
--bg-
|
|
427
|
-
--bg-
|
|
428
|
-
--bg-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
--text-
|
|
432
|
-
--text-
|
|
433
|
-
--text-
|
|
412
|
+
--sidebar-accent: 240 6% 93%; /* neutral hover */
|
|
413
|
+
--sidebar-accent-foreground: 0 0% 10%;
|
|
414
|
+
--sidebar-border: 240 6% 89%; /* hairline */
|
|
415
|
+
--sidebar-ring: 245 62% 57%;
|
|
416
|
+
|
|
417
|
+
--mesh-teal: transparent;
|
|
418
|
+
--mesh-violet: transparent;
|
|
419
|
+
--mesh-blue: transparent;
|
|
420
|
+
|
|
421
|
+
/* Surfaces — flat single-neutral light */
|
|
422
|
+
--bg-root: #ffffff;
|
|
423
|
+
--bg-dark: #f7f7f8;
|
|
424
|
+
--bg-card: #f7f7f8;
|
|
425
|
+
--bg-elevated: #ffffff;
|
|
426
|
+
--bg-section: #f7f7f8;
|
|
427
|
+
--bg-input: #ececee;
|
|
428
|
+
--bg-hover: rgba(0, 0, 0, 0.04);
|
|
429
|
+
--bg-selection: rgba(91, 78, 212, 0.10);
|
|
430
|
+
|
|
431
|
+
--text-primary: #0d0d0d;
|
|
432
|
+
--text-secondary: #2a2a30;
|
|
433
|
+
--text-muted: #5d5d66;
|
|
434
|
+
--text-dim: #8e8e98;
|
|
434
435
|
|
|
435
436
|
--brand-primary: #6366F1;
|
|
436
437
|
--brand-strong: #2E2A5E;
|
|
@@ -443,16 +444,16 @@
|
|
|
443
444
|
--brand-vibrant: #6366F1;
|
|
444
445
|
--brand-emerald: #059669;
|
|
445
446
|
|
|
446
|
-
--border-subtle: rgba(
|
|
447
|
-
--border-default: rgba(
|
|
448
|
-
--border-hover: rgba(
|
|
449
|
-
--border-accent: rgba(
|
|
450
|
-
--border-accent-hover: rgba(
|
|
447
|
+
--border-subtle: rgba(0, 0, 0, 0.06);
|
|
448
|
+
--border-default: rgba(0, 0, 0, 0.08);
|
|
449
|
+
--border-hover: rgba(0, 0, 0, 0.13);
|
|
450
|
+
--border-accent: rgba(91, 78, 212, 0.18);
|
|
451
|
+
--border-accent-hover: rgba(91, 78, 212, 0.35);
|
|
451
452
|
|
|
452
|
-
--btn-primary-bg: #
|
|
453
|
+
--btn-primary-bg: #5B4ED4;
|
|
453
454
|
--btn-primary-hover: #4F46E5;
|
|
454
455
|
--btn-primary-text: #ffffff;
|
|
455
|
-
--btn-cta-bg: #
|
|
456
|
+
--btn-cta-bg: #5B4ED4;
|
|
456
457
|
--btn-cta-text: #ffffff;
|
|
457
458
|
|
|
458
459
|
--code-keyword: #3E349E;
|
|
@@ -463,30 +464,33 @@
|
|
|
463
464
|
--code-comment: #6B6E8A;
|
|
464
465
|
--code-error: #ba1a1a;
|
|
465
466
|
|
|
466
|
-
|
|
467
|
-
--shadow-
|
|
467
|
+
/* Shadows — flat, no inner ring, no glow */
|
|
468
|
+
--shadow-card: 0 1px 2px rgba(25, 28, 36, 0.06);
|
|
469
|
+
--shadow-dropdown: 0 8px 30px rgba(25, 28, 36, 0.10);
|
|
468
470
|
--shadow-glow: none;
|
|
469
|
-
--shadow-accent: 0 1px
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
--tangle-gradient
|
|
473
|
-
--
|
|
474
|
-
--accent-
|
|
475
|
-
--accent-surface-
|
|
471
|
+
--shadow-accent: 0 1px 2px rgba(25, 28, 36, 0.06);
|
|
472
|
+
|
|
473
|
+
/* Indigo spark kept for logo + send; accent-fill is the active row well */
|
|
474
|
+
--tangle-gradient: linear-gradient(135deg, #4F46E5, #5B4ED4);
|
|
475
|
+
--tangle-gradient-text: linear-gradient(135deg, #4F46E5, #5B4ED4);
|
|
476
|
+
--accent-gradient-strong: linear-gradient(135deg, #4F46E5, #5B4ED4);
|
|
477
|
+
--accent-surface-soft: rgba(0, 0, 0, 0.04);
|
|
478
|
+
--accent-surface-strong: rgba(91, 78, 212, 0.10);
|
|
476
479
|
--accent-text: #4F46E5;
|
|
477
480
|
|
|
478
|
-
/* Typography —
|
|
479
|
-
--font-sans: "Inter", "Geist", ui-sans-serif, system-ui, sans-serif;
|
|
480
|
-
--font-display: "
|
|
481
|
+
/* Typography — unified on Inter */
|
|
482
|
+
--font-sans: "Inter", "Geist", ui-sans-serif, system-ui, -apple-system, sans-serif;
|
|
483
|
+
--font-display: "Inter", "Geist", sans-serif;
|
|
481
484
|
--font-mono: "Geist Mono", "JetBrains Mono", ui-monospace, monospace;
|
|
482
485
|
|
|
483
|
-
/*
|
|
484
|
-
--radius: 0.
|
|
485
|
-
--radius-sm:
|
|
486
|
-
--radius-md:
|
|
487
|
-
--radius-lg:
|
|
488
|
-
--radius-xl:
|
|
486
|
+
/* Radius — unified chrome scale (matches dark; 8px md) */
|
|
487
|
+
--radius: 0.5rem;
|
|
488
|
+
--radius-sm: 6px;
|
|
489
|
+
--radius-md: 8px;
|
|
490
|
+
--radius-lg: 10px;
|
|
491
|
+
--radius-xl: 12px;
|
|
489
492
|
--radius-pill: 999px;
|
|
490
493
|
--radius-full: 999px;
|
|
494
|
+
--radius-composer: 26px;
|
|
491
495
|
}
|
|
492
496
|
|
package/dist/workspace.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode } from 'react';
|
|
2
|
+
import { ReactNode, Ref } from 'react';
|
|
3
3
|
export { ArtifactPane, ArtifactPaneProps } from '@tangle-network/ui/primitives';
|
|
4
4
|
import { FileNode, FileTreeVisibilityOptions, FileTabData } from '@tangle-network/ui/files';
|
|
5
5
|
import { SessionProjectKey, ActiveSessionStatus, ActiveSessionRecord } from '@tangle-network/ui/stores';
|
|
@@ -160,6 +160,67 @@ interface RuntimePaneProps {
|
|
|
160
160
|
*/
|
|
161
161
|
declare function RuntimePane({ title, subtitle, statusBanner, statusBar, content, terminal, audit, inspector, footer, className, }: RuntimePaneProps): react_jsx_runtime.JSX.Element;
|
|
162
162
|
|
|
163
|
+
/**
|
|
164
|
+
* Optimistic session/thread list: reflect a just-created / renamed / deleted
|
|
165
|
+
* item in the sidebar INSTANTLY, before the server loader round-trips.
|
|
166
|
+
*
|
|
167
|
+
* The shell loader is the source of truth and reconciles in the background
|
|
168
|
+
* (typically the app calls `useRevalidator().revalidate()` after its mutation
|
|
169
|
+
* fetch settles). Until that lands, a local mirror of the loader items carries
|
|
170
|
+
* the optimistic edit so a delete / rename / new-thread does not feel broken
|
|
171
|
+
* for the duration of a D1 round-trip.
|
|
172
|
+
*
|
|
173
|
+
* Two ways to drive it, usable together:
|
|
174
|
+
* 1. A window `CustomEvent` (default name {@link SESSION_CREATED_EVENT}) — the
|
|
175
|
+
* surface that creates a thread (often a different route from the sidebar's
|
|
176
|
+
* route) dispatches it; the sidebar prepends the item with no prop wiring.
|
|
177
|
+
* 2. The imperative {@link SessionOptimisticController} returned here — the
|
|
178
|
+
* sidebar's own action handlers (rename / delete / pin) call it directly.
|
|
179
|
+
*/
|
|
180
|
+
/** Default window-event name for "a session/thread was just created". */
|
|
181
|
+
declare const SESSION_CREATED_EVENT = "sandbox-thread-created";
|
|
182
|
+
/**
|
|
183
|
+
* Payload of a {@link SESSION_CREATED_EVENT}. Only `id` + `title` are required;
|
|
184
|
+
* everything else mirrors {@link SessionSidebarItem}. `updatedAt` defaults to
|
|
185
|
+
* now so the new item sorts to the top.
|
|
186
|
+
*/
|
|
187
|
+
interface SessionCreatedDetail extends Partial<Omit<SessionSidebarItem, "id" | "title">> {
|
|
188
|
+
id: string;
|
|
189
|
+
title: string;
|
|
190
|
+
}
|
|
191
|
+
/** Dispatch the shared "session created" event so any mounted sidebar updates. */
|
|
192
|
+
declare function dispatchSessionCreated(detail: SessionCreatedDetail, eventName?: string): void;
|
|
193
|
+
/** Imperative handle for driving optimistic edits from a mutation handler. */
|
|
194
|
+
interface SessionOptimisticController {
|
|
195
|
+
/** Prepend (or move to top) an item — call before the create fetch settles. */
|
|
196
|
+
add: (item: SessionCreatedDetail) => void;
|
|
197
|
+
/** Patch an existing item in place — e.g. a rename or category change. */
|
|
198
|
+
update: (id: string, patch: Partial<SessionSidebarItem>) => void;
|
|
199
|
+
/** Drop an item — call before the delete fetch settles. */
|
|
200
|
+
remove: (id: string) => void;
|
|
201
|
+
/** Discard all optimistic edits and snap back to the loader items. */
|
|
202
|
+
reset: () => void;
|
|
203
|
+
}
|
|
204
|
+
interface UseOptimisticSessionItemsOptions {
|
|
205
|
+
/**
|
|
206
|
+
* Listen for the shared window create-event and prepend its item. Set `false`
|
|
207
|
+
* to drive optimistic state purely through the imperative controller.
|
|
208
|
+
* Defaults to `true`.
|
|
209
|
+
*/
|
|
210
|
+
listenForCreate?: boolean;
|
|
211
|
+
/** Override the window event name to listen for. */
|
|
212
|
+
eventName?: string;
|
|
213
|
+
}
|
|
214
|
+
/**
|
|
215
|
+
* Mirror `items` with optimistic add/update/remove on top. The mirror re-syncs
|
|
216
|
+
* whenever `items` changes (the loader is authoritative), so an optimistic edit
|
|
217
|
+
* is naturally superseded once the server result arrives.
|
|
218
|
+
*/
|
|
219
|
+
declare function useOptimisticSessionItems(items: SessionSidebarItem[], options?: UseOptimisticSessionItemsOptions): {
|
|
220
|
+
items: SessionSidebarItem[];
|
|
221
|
+
controller: SessionOptimisticController;
|
|
222
|
+
};
|
|
223
|
+
|
|
163
224
|
interface SessionSidebarItem {
|
|
164
225
|
id: string;
|
|
165
226
|
title: string;
|
|
@@ -218,8 +279,97 @@ interface SessionSidebarProps {
|
|
|
218
279
|
session: ActiveSessionRecord | null;
|
|
219
280
|
isActive: boolean;
|
|
220
281
|
}) => ReactNode;
|
|
282
|
+
/**
|
|
283
|
+
* Opt into optimistic item updates: the sidebar keeps a local mirror of
|
|
284
|
+
* `items` so a just-created / renamed / deleted thread shows instantly,
|
|
285
|
+
* before the loader round-trips. Pass `true` for defaults, or an options
|
|
286
|
+
* object to tune the window create-event. Off by default — existing callers
|
|
287
|
+
* render `items` verbatim and are unaffected.
|
|
288
|
+
*/
|
|
289
|
+
optimistic?: boolean | UseOptimisticSessionItemsOptions;
|
|
290
|
+
/**
|
|
291
|
+
* Ref to the imperative optimistic controller (`add` / `update` / `remove` /
|
|
292
|
+
* `reset`). Drive optimistic edits from the consumer's own rename/delete/pin
|
|
293
|
+
* handlers. Only populated when `optimistic` is enabled.
|
|
294
|
+
*/
|
|
295
|
+
optimisticRef?: Ref<SessionOptimisticController | null>;
|
|
221
296
|
}
|
|
222
|
-
declare function SessionSidebar({ title, subtitle, projectId, items, currentItemId, createLabel, onCreate, onSelectItem, onSelectLink, links, className, emptyMessage, searchPlaceholder, enableSearch, activityMonitor, filters, defaultFilterId, resizable, defaultWidth, minWidth, maxWidth, onWidthChange, renderItemActions, }: SessionSidebarProps): react_jsx_runtime.JSX.Element;
|
|
297
|
+
declare function SessionSidebar({ title, subtitle, projectId, items, currentItemId, createLabel, onCreate, onSelectItem, onSelectLink, links, className, emptyMessage, searchPlaceholder, enableSearch, activityMonitor, filters, defaultFilterId, resizable, defaultWidth, minWidth, maxWidth, onWidthChange, renderItemActions, optimistic, optimisticRef, }: SessionSidebarProps): react_jsx_runtime.JSX.Element;
|
|
298
|
+
|
|
299
|
+
/**
|
|
300
|
+
* Snappy in-app navigation: a shared `shouldRevalidate` rule for the agent-app
|
|
301
|
+
* shell route(s) that own the workspace-list / sidebar loader.
|
|
302
|
+
*
|
|
303
|
+
* The shell loader (user + workspace list, sidebar state) runs on every
|
|
304
|
+
* navigation, but its data does not change just by moving between in-app pages.
|
|
305
|
+
* Refetching it on every internal GET nav adds a loader round-trip to each
|
|
306
|
+
* click — on Cloudflare Workers + D1 (HTTP-proxied) that is a visible stall.
|
|
307
|
+
*
|
|
308
|
+
* This helper encodes the rule that makes nav feel instant WITHOUT stranding
|
|
309
|
+
* freshly-mutated data:
|
|
310
|
+
*
|
|
311
|
+
* - Non-GET navigation (form submit / action) → always revalidate.
|
|
312
|
+
* - Internal app→app navigation that CHANGES the path → skip revalidation.
|
|
313
|
+
* - Imperative `useRevalidator().revalidate()` (which targets the SAME url,
|
|
314
|
+
* so `currentUrl.pathname === nextUrl.pathname`) → revalidate. Creating a
|
|
315
|
+
* project / thread typically goes through a raw `fetch`, so a same-url
|
|
316
|
+
* revalidate is the ONLY way the new row reaches the shell loader; the
|
|
317
|
+
* same-path carve-out below is what keeps that working. Suppressing it is
|
|
318
|
+
* the project-switcher regression — do not "simplify" it away.
|
|
319
|
+
* - Anything else (cross-path-prefix nav, entering/leaving the app) →
|
|
320
|
+
* defer to `defaultShouldRevalidate`.
|
|
321
|
+
*
|
|
322
|
+
* Framework-agnostic by design: sandbox-ui does not depend on react-router, so
|
|
323
|
+
* this takes a plain args object. The shape is a structural subset of
|
|
324
|
+
* react-router's `ShouldRevalidateFunctionArgs`, so an app can wire it as a
|
|
325
|
+
* route export with no adapter:
|
|
326
|
+
*
|
|
327
|
+
* ```ts
|
|
328
|
+
* // app/routes/app.tsx
|
|
329
|
+
* import { shellShouldRevalidate } from "@tangle-network/sandbox-ui/workspace";
|
|
330
|
+
* export const shouldRevalidate = shellShouldRevalidate;
|
|
331
|
+
* ```
|
|
332
|
+
*
|
|
333
|
+
* `shouldRevalidate` MUST be a per-app react-router route export — it cannot be
|
|
334
|
+
* exported FROM a library on the app's behalf — so the "out of the box" win is
|
|
335
|
+
* the one-line re-export above instead of every app re-deriving the rule (and
|
|
336
|
+
* re-introducing the same-url bug).
|
|
337
|
+
*/
|
|
338
|
+
/**
|
|
339
|
+
* The subset of react-router's `ShouldRevalidateFunctionArgs` this rule reads.
|
|
340
|
+
* Kept structural so callers can pass the full react-router args object as-is.
|
|
341
|
+
*/
|
|
342
|
+
interface ShellShouldRevalidateArgs {
|
|
343
|
+
currentUrl: URL;
|
|
344
|
+
nextUrl: URL;
|
|
345
|
+
formMethod?: string;
|
|
346
|
+
defaultShouldRevalidate: boolean;
|
|
347
|
+
}
|
|
348
|
+
interface ShellShouldRevalidateOptions {
|
|
349
|
+
/**
|
|
350
|
+
* Path prefix that marks "inside the app shell". Internal navigation between
|
|
351
|
+
* two paths under this prefix skips the shell-loader refetch. Defaults to
|
|
352
|
+
* `"/app"`.
|
|
353
|
+
*/
|
|
354
|
+
appPathPrefix?: string;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* Build a `shouldRevalidate` function for the shell route under `appPathPrefix`.
|
|
358
|
+
* Use this when the app mounts under a non-default prefix; otherwise prefer the
|
|
359
|
+
* ready-made {@link shellShouldRevalidate} export.
|
|
360
|
+
*/
|
|
361
|
+
declare function createShellShouldRevalidate(options?: ShellShouldRevalidateOptions): (args: ShellShouldRevalidateArgs) => boolean;
|
|
362
|
+
/**
|
|
363
|
+
* Ready-made shell `shouldRevalidate` for apps mounted under `/app`. Wire it as
|
|
364
|
+
* a one-line route export:
|
|
365
|
+
*
|
|
366
|
+
* ```ts
|
|
367
|
+
* export const shouldRevalidate = shellShouldRevalidate;
|
|
368
|
+
* ```
|
|
369
|
+
*
|
|
370
|
+
* For a non-`/app` prefix, use {@link createShellShouldRevalidate}.
|
|
371
|
+
*/
|
|
372
|
+
declare const shellShouldRevalidate: (args: ShellShouldRevalidateArgs) => boolean;
|
|
223
373
|
|
|
224
374
|
interface SessionActivityMonitorProps {
|
|
225
375
|
className?: string;
|
|
@@ -478,4 +628,4 @@ interface ApprovalQueueProps {
|
|
|
478
628
|
*/
|
|
479
629
|
declare function ApprovalQueue({ items, className, onApprove, onReject, renderItemDetail, renderTypeBadge, renderStats, canResolve, header, emptyState, showResolved: controlledShowResolved, }: ApprovalQueueProps): react_jsx_runtime.JSX.Element;
|
|
480
630
|
|
|
481
|
-
export { AgentWorkbench, type ApprovalConfidenceStat, type ApprovalItem, ApprovalQueue, type ApprovalQueueProps, type AuditCheck, AuditResults, type AuditResultsProps, type BannerType, type CalendarEvent, CalendarView, type CalendarViewProps, type ContextBadge, DirectoryPane, type DirectoryPaneProps, type FormAudit, RuntimePane, type RuntimePaneProps, SandboxWorkbench, type SandboxWorkbenchArtifact, type SandboxWorkbenchCustomArtifact, type SandboxWorkbenchFileArtifact, type SandboxWorkbenchLayoutOptions, type SandboxWorkbenchMarkdownArtifact, type SandboxWorkbenchOpenUIArtifact, type SandboxWorkbenchProps, type SandboxWorkbenchSessionProps, SessionActivityMonitor, type SessionActivityMonitorProps, SessionSidebar, type SessionSidebarBadge, type SessionSidebarFilter, type SessionSidebarItem, type SessionSidebarLink, type SessionSidebarProps, StatusBanner, type StatusBannerProps, StatusBar, type StatusBarProps, TaskBoard, type TaskBoardColumn, type TaskBoardItem, type TaskBoardProps, type TerminalLine, TerminalPanel, type TerminalProps, WorkspaceLayout, type WorkspaceLayoutProps };
|
|
631
|
+
export { AgentWorkbench, type ApprovalConfidenceStat, type ApprovalItem, ApprovalQueue, type ApprovalQueueProps, type AuditCheck, AuditResults, type AuditResultsProps, type BannerType, type CalendarEvent, CalendarView, type CalendarViewProps, type ContextBadge, DirectoryPane, type DirectoryPaneProps, type FormAudit, RuntimePane, type RuntimePaneProps, SESSION_CREATED_EVENT, SandboxWorkbench, type SandboxWorkbenchArtifact, type SandboxWorkbenchCustomArtifact, type SandboxWorkbenchFileArtifact, type SandboxWorkbenchLayoutOptions, type SandboxWorkbenchMarkdownArtifact, type SandboxWorkbenchOpenUIArtifact, type SandboxWorkbenchProps, type SandboxWorkbenchSessionProps, SessionActivityMonitor, type SessionActivityMonitorProps, type SessionCreatedDetail, type SessionOptimisticController, SessionSidebar, type SessionSidebarBadge, type SessionSidebarFilter, type SessionSidebarItem, type SessionSidebarLink, type SessionSidebarProps, type ShellShouldRevalidateArgs, type ShellShouldRevalidateOptions, StatusBanner, type StatusBannerProps, StatusBar, type StatusBarProps, TaskBoard, type TaskBoardColumn, type TaskBoardItem, type TaskBoardProps, type TerminalLine, TerminalPanel, type TerminalProps, type UseOptimisticSessionItemsOptions, WorkspaceLayout, type WorkspaceLayoutProps, createShellShouldRevalidate, dispatchSessionCreated, shellShouldRevalidate, useOptimisticSessionItems };
|
package/dist/workspace.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
CalendarView,
|
|
7
7
|
DirectoryPane,
|
|
8
8
|
RuntimePane,
|
|
9
|
+
SESSION_CREATED_EVENT,
|
|
9
10
|
SandboxWorkbench,
|
|
10
11
|
SessionActivityMonitor,
|
|
11
12
|
SessionSidebar,
|
|
@@ -13,8 +14,12 @@ import {
|
|
|
13
14
|
StatusBar,
|
|
14
15
|
TaskBoard,
|
|
15
16
|
TerminalPanel,
|
|
16
|
-
WorkspaceLayout
|
|
17
|
-
|
|
17
|
+
WorkspaceLayout,
|
|
18
|
+
createShellShouldRevalidate,
|
|
19
|
+
dispatchSessionCreated,
|
|
20
|
+
shellShouldRevalidate,
|
|
21
|
+
useOptimisticSessionItems
|
|
22
|
+
} from "./chunk-AUFV7766.js";
|
|
18
23
|
import "./chunk-EI44GEQ5.js";
|
|
19
24
|
export {
|
|
20
25
|
AgentWorkbench,
|
|
@@ -24,6 +29,7 @@ export {
|
|
|
24
29
|
CalendarView,
|
|
25
30
|
DirectoryPane,
|
|
26
31
|
RuntimePane,
|
|
32
|
+
SESSION_CREATED_EVENT,
|
|
27
33
|
SandboxWorkbench,
|
|
28
34
|
SessionActivityMonitor,
|
|
29
35
|
SessionSidebar,
|
|
@@ -31,5 +37,9 @@ export {
|
|
|
31
37
|
StatusBar,
|
|
32
38
|
TaskBoard,
|
|
33
39
|
TerminalPanel,
|
|
34
|
-
WorkspaceLayout
|
|
40
|
+
WorkspaceLayout,
|
|
41
|
+
createShellShouldRevalidate,
|
|
42
|
+
dispatchSessionCreated,
|
|
43
|
+
shellShouldRevalidate,
|
|
44
|
+
useOptimisticSessionItems
|
|
35
45
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/sandbox-ui",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.30.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",
|
|
@@ -114,7 +114,7 @@
|
|
|
114
114
|
"test:bridge": "pnpm build && vitest run src/__tests__/re-export-identity.test.ts"
|
|
115
115
|
},
|
|
116
116
|
"peerDependencies": {
|
|
117
|
-
"@tangle-network/brand": "^0.
|
|
117
|
+
"@tangle-network/brand": "^0.4.0",
|
|
118
118
|
"@tangle-network/ui": "^1.0.1",
|
|
119
119
|
"react": "^18 || ^19",
|
|
120
120
|
"react-dom": "^18 || ^19"
|
|
@@ -161,7 +161,7 @@
|
|
|
161
161
|
"@storybook/react-vite": "^8.6.18",
|
|
162
162
|
"@tailwindcss/postcss": "^4.2.2",
|
|
163
163
|
"@tailwindcss/vite": "^4.2.2",
|
|
164
|
-
"@tangle-network/brand": "^0.
|
|
164
|
+
"@tangle-network/brand": "^0.4.0",
|
|
165
165
|
"@tangle-network/ui": "^1.0.1",
|
|
166
166
|
"@tanstack/react-query": "^5.91.0",
|
|
167
167
|
"@testing-library/dom": "^10.4.1",
|