@tangle-network/sandbox-ui 0.4.0 → 0.5.1
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/auth.js +3 -3
- package/dist/chat.d.ts +1 -1
- package/dist/chat.js +11 -9
- package/dist/{chunk-ZP6GSX4D.js → chunk-565V6JTN.js} +26 -50
- package/dist/chunk-5CEMHKBP.js +72 -0
- package/dist/{chunk-FOQTE67I.js → chunk-5F4NX5R2.js} +10 -5
- package/dist/{chunk-MVYFNPAH.js → chunk-7DVFZEVW.js} +298 -272
- package/dist/{chunk-MUOL44AE.js → chunk-BRBTD7RH.js} +6 -6
- package/dist/{chunk-SSKVYXCR.js → chunk-DCPYTL4W.js} +62 -79
- package/dist/chunk-DLCFZDGX.js +182 -0
- package/dist/{chunk-HXEA7L2T.js → chunk-FFOXUHOF.js} +10 -10
- package/dist/chunk-H5XYSFYE.js +228 -0
- package/dist/{chunk-TQN3VR4F.js → chunk-JP725R4W.js} +2 -2
- package/dist/{chunk-CJ2RYVZH.js → chunk-NTSRY4GW.js} +68 -10
- package/dist/{chunk-DQYODCBN.js → chunk-P24K22CV.js} +57 -66
- package/dist/{chunk-GVUW4VDD.js → chunk-R3IU37AW.js} +161 -229
- package/dist/chunk-TDYQBLL5.js +127 -0
- package/dist/{chunk-HWLX5NME.js → chunk-TSE423UF.js} +12 -12
- package/dist/{chunk-YDBXQQLC.js → chunk-VBWY44UU.js} +30 -76
- package/dist/{chunk-IW2JZCOC.js → chunk-WBQ7VULC.js} +7 -7
- package/dist/{chunk-72UEKFZ2.js → chunk-WC7QTWPN.js} +65 -42
- package/dist/{chunk-HYLTXGOI.js → chunk-WQH233GF.js} +5 -5
- package/dist/{chunk-CCKNIAS7.js → chunk-XBR3IP7B.js} +2 -2
- package/dist/{chunk-OHMO7NUX.js → chunk-XTPAWK7L.js} +20 -31
- package/dist/{chunk-SULQQJPB.js → chunk-YS66Q3RC.js} +1 -1
- package/dist/{chunk-FRGMMANX.js → chunk-YYGECNZZ.js} +3 -3
- package/dist/dashboard.d.ts +2 -2
- package/dist/dashboard.js +6 -6
- package/dist/{document-editor-pane-5TN2VWGZ.js → document-editor-pane-JNXPANWM.js} +2 -2
- package/dist/editor.js +2 -2
- package/dist/files.js +2 -2
- package/dist/globals.css +129 -95
- package/dist/hooks.d.ts +2 -2
- package/dist/hooks.js +5 -5
- package/dist/{index-tTfThG0n.d.ts → index-BT_-ecpc.d.ts} +11 -10
- package/dist/index.d.ts +16 -23
- package/dist/index.js +27 -26
- package/dist/markdown.d.ts +14 -17
- package/dist/markdown.js +1 -1
- package/dist/openui.js +5 -5
- package/dist/pages.d.ts +10 -3
- package/dist/pages.js +147 -184
- package/dist/primitives.d.ts +8 -5
- package/dist/primitives.js +8 -8
- package/dist/run.d.ts +1 -1
- package/dist/run.js +4 -4
- package/dist/sdk-hooks.d.ts +1 -1
- package/dist/sdk-hooks.js +4 -4
- package/dist/styles.css +129 -95
- package/dist/terminal.d.ts +2 -2
- package/dist/terminal.js +13 -43
- package/dist/tokens.css +299 -179
- package/dist/{tool-call-feed-D5Ume-Pt.d.ts → tool-call-feed-Bs3MyQMT.d.ts} +3 -1
- package/dist/{usage-chart-CY9xo3KX.d.ts → usage-chart-XCoB_7Xu.d.ts} +1 -2
- package/dist/{use-pty-session-DeZSxOCN.d.ts → use-pty-session-COzVkhtc.d.ts} +1 -1
- package/dist/workspace.d.ts +3 -1
- package/dist/workspace.js +11 -11
- package/package.json +14 -2
- package/dist/chunk-GRYHFH5O.js +0 -110
- package/dist/chunk-LTFK464G.js +0 -103
- package/dist/chunk-MXCSSOGH.js +0 -105
|
@@ -18,12 +18,12 @@ var Input = React.forwardRef(
|
|
|
18
18
|
type,
|
|
19
19
|
id: inputId,
|
|
20
20
|
className: cn(
|
|
21
|
-
"flex h-11 w-full rounded-lg border bg-
|
|
21
|
+
"flex h-11 w-full rounded-lg border bg-[var(--depth-2)] px-4 py-2 text-sm transition-all duration-200",
|
|
22
22
|
"placeholder:text-muted-foreground",
|
|
23
23
|
"focus:outline-none focus:ring-2 focus:ring-offset-0",
|
|
24
24
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
25
25
|
"file:border-0 file:bg-transparent file:font-medium file:text-sm",
|
|
26
|
-
error ? "border-
|
|
26
|
+
error ? "border-[var(--surface-danger-border)] focus:ring-[var(--surface-danger-border)]" : variants[variant],
|
|
27
27
|
className
|
|
28
28
|
),
|
|
29
29
|
ref,
|
|
@@ -41,7 +41,7 @@ var Input = React.forwardRef(
|
|
|
41
41
|
}
|
|
42
42
|
),
|
|
43
43
|
input,
|
|
44
|
-
error && /* @__PURE__ */ jsx("p", { className: "text-
|
|
44
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-[var(--surface-danger-text)] text-sm", children: error }),
|
|
45
45
|
hint && !error && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground/70 text-sm", children: hint })
|
|
46
46
|
] });
|
|
47
47
|
}
|
|
@@ -59,11 +59,11 @@ var Textarea = React.forwardRef(
|
|
|
59
59
|
{
|
|
60
60
|
id: textareaId,
|
|
61
61
|
className: cn(
|
|
62
|
-
"flex min-h-[120px] w-full resize-y rounded-lg border bg-
|
|
62
|
+
"flex min-h-[120px] w-full resize-y rounded-lg border bg-[var(--depth-2)] px-4 py-3 text-sm transition-all duration-200",
|
|
63
63
|
"placeholder:text-muted-foreground",
|
|
64
64
|
"focus:outline-none focus:ring-2 focus:ring-offset-0",
|
|
65
65
|
"disabled:cursor-not-allowed disabled:opacity-50",
|
|
66
|
-
error ? "border-
|
|
66
|
+
error ? "border-[var(--surface-danger-border)] focus:ring-[var(--surface-danger-border)]" : variants[variant],
|
|
67
67
|
className
|
|
68
68
|
),
|
|
69
69
|
ref,
|
|
@@ -81,7 +81,7 @@ var Textarea = React.forwardRef(
|
|
|
81
81
|
}
|
|
82
82
|
),
|
|
83
83
|
textarea,
|
|
84
|
-
error && /* @__PURE__ */ jsx("p", { className: "text-
|
|
84
|
+
error && /* @__PURE__ */ jsx("p", { className: "text-[var(--surface-danger-text)] text-sm", children: error }),
|
|
85
85
|
hint && !error && /* @__PURE__ */ jsx("p", { className: "text-muted-foreground/70 text-sm", children: hint })
|
|
86
86
|
] });
|
|
87
87
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import {
|
|
2
2
|
Card
|
|
3
|
-
} from "./chunk-
|
|
3
|
+
} from "./chunk-TDYQBLL5.js";
|
|
4
4
|
import {
|
|
5
5
|
cn
|
|
6
6
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -18,7 +18,7 @@ var SelectTrigger = React.forwardRef(({ className, children, ...props }, ref) =>
|
|
|
18
18
|
{
|
|
19
19
|
ref,
|
|
20
20
|
className: cn(
|
|
21
|
-
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-
|
|
21
|
+
"flex h-9 w-full items-center justify-between whitespace-nowrap rounded-md border border-[var(--border-subtle)] bg-[var(--depth-2)] px-3 py-2 text-sm shadow-sm placeholder:text-[var(--text-muted)] focus:outline-none focus:ring-1 focus:ring-[var(--brand-cool)] disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
|
|
22
22
|
className
|
|
23
23
|
),
|
|
24
24
|
...props,
|
|
@@ -60,7 +60,7 @@ var SelectContent = React.forwardRef(({ className, children, position = "popper"
|
|
|
60
60
|
{
|
|
61
61
|
ref,
|
|
62
62
|
className: cn(
|
|
63
|
-
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-
|
|
63
|
+
"data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2 relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border border-[var(--border-subtle)] bg-[var(--depth-2)] text-[var(--text-primary)] shadow-[var(--shadow-card)] data-[state=closed]:animate-out data-[state=open]:animate-in",
|
|
64
64
|
position === "popper" && "data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=bottom]:translate-y-1 data-[side=top]:-translate-y-1",
|
|
65
65
|
className
|
|
66
66
|
),
|
|
@@ -97,7 +97,7 @@ var SelectItem = React.forwardRef(({ className, children, ...props }, ref) => /*
|
|
|
97
97
|
{
|
|
98
98
|
ref,
|
|
99
99
|
className: cn(
|
|
100
|
-
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none focus:bg-
|
|
100
|
+
"relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pr-8 pl-2 text-sm outline-none focus:bg-[var(--depth-3)] focus:text-[var(--text-primary)] data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
|
|
101
101
|
className
|
|
102
102
|
),
|
|
103
103
|
...props,
|
|
@@ -112,7 +112,7 @@ var SelectSeparator = React.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
112
112
|
SelectPrimitive.Separator,
|
|
113
113
|
{
|
|
114
114
|
ref,
|
|
115
|
-
className: cn("-mx-1 my-1 h-px bg-
|
|
115
|
+
className: cn("-mx-1 my-1 h-px bg-[var(--border-subtle)]", className),
|
|
116
116
|
...props
|
|
117
117
|
}
|
|
118
118
|
));
|
|
@@ -160,10 +160,10 @@ var toastVariants = cva(
|
|
|
160
160
|
variants: {
|
|
161
161
|
variant: {
|
|
162
162
|
default: "border-border bg-background text-foreground",
|
|
163
|
-
success: "border-
|
|
164
|
-
error: "border-
|
|
165
|
-
warning: "border-
|
|
166
|
-
info: "border-
|
|
163
|
+
success: "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)] text-[var(--surface-success-text)]",
|
|
164
|
+
error: "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] text-[var(--surface-danger-text)]",
|
|
165
|
+
warning: "border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] text-[var(--surface-warning-text)]",
|
|
166
|
+
info: "border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)]"
|
|
167
167
|
}
|
|
168
168
|
},
|
|
169
169
|
defaultVariants: {
|
|
@@ -316,13 +316,13 @@ var StatCard = React5.forwardRef(
|
|
|
316
316
|
...props
|
|
317
317
|
}, ref) => {
|
|
318
318
|
const iconColors = {
|
|
319
|
-
default: "text-muted
|
|
319
|
+
default: "text-[var(--text-muted)]",
|
|
320
320
|
sandbox: "text-[var(--accent-text)]"
|
|
321
321
|
};
|
|
322
322
|
const trendColors = {
|
|
323
|
-
positive: "text-
|
|
324
|
-
negative: "text-
|
|
325
|
-
neutral: "text-muted
|
|
323
|
+
positive: "text-[var(--surface-success-text)]",
|
|
324
|
+
negative: "text-[var(--surface-danger-text)]",
|
|
325
|
+
neutral: "text-[var(--text-muted)]"
|
|
326
326
|
};
|
|
327
327
|
const trendStatus = trend ? trend.value > 0 ? "positive" : trend.value < 0 ? "negative" : "neutral" : null;
|
|
328
328
|
return /* @__PURE__ */ jsx5(
|
|
@@ -334,9 +334,9 @@ var StatCard = React5.forwardRef(
|
|
|
334
334
|
...props,
|
|
335
335
|
children: /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between", children: [
|
|
336
336
|
/* @__PURE__ */ jsxs3("div", { className: "space-y-1", children: [
|
|
337
|
-
/* @__PURE__ */ jsx5("p", { className: "text-muted
|
|
337
|
+
/* @__PURE__ */ jsx5("p", { className: "text-[var(--text-muted)] text-sm", children: title }),
|
|
338
338
|
/* @__PURE__ */ jsx5("p", { className: "font-bold text-3xl tracking-tight", children: value }),
|
|
339
|
-
subtitle && /* @__PURE__ */ jsx5("p", { className: "text-muted-
|
|
339
|
+
subtitle && /* @__PURE__ */ jsx5("p", { className: "text-[var(--text-muted)] opacity-70 text-xs", children: subtitle }),
|
|
340
340
|
trend && trendStatus && /* @__PURE__ */ jsxs3(
|
|
341
341
|
"div",
|
|
342
342
|
{
|
|
@@ -350,7 +350,7 @@ var StatCard = React5.forwardRef(
|
|
|
350
350
|
Math.abs(trend.value),
|
|
351
351
|
"%"
|
|
352
352
|
] }),
|
|
353
|
-
trend.label && /* @__PURE__ */ jsx5("span", { className: "text-muted
|
|
353
|
+
trend.label && /* @__PURE__ */ jsx5("span", { className: "text-[var(--text-muted)]", children: trend.label })
|
|
354
354
|
]
|
|
355
355
|
}
|
|
356
356
|
)
|
|
@@ -359,7 +359,7 @@ var StatCard = React5.forwardRef(
|
|
|
359
359
|
"div",
|
|
360
360
|
{
|
|
361
361
|
className: cn(
|
|
362
|
-
"rounded-lg bg-
|
|
362
|
+
"rounded-lg bg-[var(--depth-3)] p-2",
|
|
363
363
|
variant === "sandbox" && "bg-[var(--accent-surface-soft)]",
|
|
364
364
|
iconColors[variant]
|
|
365
365
|
),
|
|
@@ -395,34 +395,21 @@ var TerminalDisplay = React6.forwardRef(
|
|
|
395
395
|
}
|
|
396
396
|
}, [autoScroll]);
|
|
397
397
|
const variants = {
|
|
398
|
-
default: "border-border",
|
|
398
|
+
default: "border-[var(--border-subtle)]",
|
|
399
399
|
sandbox: "border-[var(--border-accent)] shadow-[var(--shadow-accent)]"
|
|
400
400
|
};
|
|
401
|
-
const dotColors = {
|
|
402
|
-
default: ["bg-red-500", "bg-yellow-500", "bg-green-500"],
|
|
403
|
-
sandbox: ["bg-red-500", "bg-yellow-500", "bg-[var(--brand-cool)]"]
|
|
404
|
-
};
|
|
405
401
|
return /* @__PURE__ */ jsxs4(
|
|
406
402
|
"div",
|
|
407
403
|
{
|
|
408
404
|
ref,
|
|
409
405
|
className: cn(
|
|
410
|
-
"overflow-hidden rounded-xl border bg-[
|
|
406
|
+
"overflow-hidden rounded-xl border bg-[var(--depth-1)] font-mono text-sm",
|
|
411
407
|
variants[variant],
|
|
412
408
|
className
|
|
413
409
|
),
|
|
414
410
|
...props,
|
|
415
411
|
children: [
|
|
416
|
-
showHeader && /* @__PURE__ */
|
|
417
|
-
/* @__PURE__ */ jsx6("div", { className: "flex gap-1.5", children: dotColors[variant].map((color) => /* @__PURE__ */ jsx6(
|
|
418
|
-
"div",
|
|
419
|
-
{
|
|
420
|
-
className: cn("h-3 w-3 rounded-full", color)
|
|
421
|
-
},
|
|
422
|
-
color
|
|
423
|
-
)) }),
|
|
424
|
-
/* @__PURE__ */ jsx6("span", { className: "ml-2 text-muted-foreground text-xs", children: title })
|
|
425
|
-
] }),
|
|
412
|
+
showHeader && /* @__PURE__ */ jsx6("div", { className: "flex items-center border-b border-[var(--border-subtle)] bg-[var(--depth-2)] px-4 py-3", children: /* @__PURE__ */ jsx6("span", { className: "text-[var(--text-muted)] text-xs", children: title }) }),
|
|
426
413
|
/* @__PURE__ */ jsx6(
|
|
427
414
|
"div",
|
|
428
415
|
{
|
|
@@ -441,14 +428,14 @@ TerminalDisplay.displayName = "TerminalDisplay";
|
|
|
441
428
|
var TerminalLine = React6.forwardRef(
|
|
442
429
|
({ className, type = "output", prompt = "$", timestamp, children, ...props }, ref) => {
|
|
443
430
|
const typeStyles = {
|
|
444
|
-
input: "text-
|
|
445
|
-
output: "text-
|
|
446
|
-
error: "text-
|
|
447
|
-
success: "text-
|
|
448
|
-
info: "text-
|
|
449
|
-
thinking: "text-
|
|
450
|
-
command: "text-
|
|
451
|
-
warning: "text-
|
|
431
|
+
input: "text-[var(--text-primary)]",
|
|
432
|
+
output: "text-[var(--text-secondary)]",
|
|
433
|
+
error: "text-[var(--surface-danger-text)]",
|
|
434
|
+
success: "text-[var(--surface-success-text)]",
|
|
435
|
+
info: "text-[var(--surface-info-text)]",
|
|
436
|
+
thinking: "text-[var(--surface-warning-text)] animate-pulse",
|
|
437
|
+
command: "text-[var(--text-primary)]",
|
|
438
|
+
warning: "text-[var(--surface-warning-text)]"
|
|
452
439
|
};
|
|
453
440
|
return /* @__PURE__ */ jsxs4(
|
|
454
441
|
"div",
|
|
@@ -461,9 +448,9 @@ var TerminalLine = React6.forwardRef(
|
|
|
461
448
|
),
|
|
462
449
|
...props,
|
|
463
450
|
children: [
|
|
464
|
-
(type === "input" || type === "command") && /* @__PURE__ */ jsx6("span", { className: "shrink-0 select-none text-
|
|
451
|
+
(type === "input" || type === "command") && /* @__PURE__ */ jsx6("span", { className: "shrink-0 select-none text-[var(--surface-success-text)]", children: prompt }),
|
|
465
452
|
type === "thinking" && /* @__PURE__ */ jsx6("span", { className: "shrink-0 select-none", children: "..." }),
|
|
466
|
-
timestamp && /* @__PURE__ */ jsxs4("span", { className: "shrink-0 select-none text-muted-
|
|
453
|
+
timestamp && /* @__PURE__ */ jsxs4("span", { className: "shrink-0 select-none text-[var(--text-muted)] opacity-50", children: [
|
|
467
454
|
"[",
|
|
468
455
|
timestamp,
|
|
469
456
|
"]"
|
|
@@ -480,7 +467,7 @@ var TerminalCursor = React6.forwardRef(({ className, ...props }, ref) => /* @__P
|
|
|
480
467
|
{
|
|
481
468
|
ref,
|
|
482
469
|
className: cn(
|
|
483
|
-
"ml-0.5 inline-block h-4 w-2 animate-pulse bg-
|
|
470
|
+
"ml-0.5 inline-block h-4 w-2 animate-pulse bg-[var(--text-primary)]",
|
|
484
471
|
className
|
|
485
472
|
),
|
|
486
473
|
...props
|
|
@@ -497,19 +484,19 @@ var TerminalInput = React6.forwardRef(
|
|
|
497
484
|
}
|
|
498
485
|
};
|
|
499
486
|
const variants = {
|
|
500
|
-
default: "border-border focus-within:border-
|
|
487
|
+
default: "border-[var(--border-subtle)] focus-within:border-[var(--border-default)]",
|
|
501
488
|
sandbox: "border-[var(--border-accent)] focus-within:border-[var(--border-accent-hover)]"
|
|
502
489
|
};
|
|
503
490
|
return /* @__PURE__ */ jsxs4(
|
|
504
491
|
"div",
|
|
505
492
|
{
|
|
506
493
|
className: cn(
|
|
507
|
-
"flex items-center rounded-lg border bg-[
|
|
494
|
+
"flex items-center rounded-lg border bg-[var(--depth-1)] px-4 py-2.5 font-mono text-sm transition-colors",
|
|
508
495
|
variants[variant],
|
|
509
496
|
className
|
|
510
497
|
),
|
|
511
498
|
children: [
|
|
512
|
-
/* @__PURE__ */ jsx6("span", { className: "mr-2 select-none text-
|
|
499
|
+
/* @__PURE__ */ jsx6("span", { className: "mr-2 select-none text-[var(--surface-success-text)]", children: "$" }),
|
|
513
500
|
/* @__PURE__ */ jsx6(
|
|
514
501
|
"input",
|
|
515
502
|
{
|
|
@@ -518,7 +505,7 @@ var TerminalInput = React6.forwardRef(
|
|
|
518
505
|
value,
|
|
519
506
|
onChange: (e) => setValue(e.target.value),
|
|
520
507
|
onKeyDown: handleKeyDown,
|
|
521
|
-
className: "flex-1 bg-transparent text-
|
|
508
|
+
className: "flex-1 bg-transparent text-[var(--text-primary)] outline-none placeholder:text-[var(--text-muted)]",
|
|
522
509
|
...props
|
|
523
510
|
}
|
|
524
511
|
),
|
|
@@ -597,10 +584,15 @@ function DropZone({
|
|
|
597
584
|
onDrop: handleDrop,
|
|
598
585
|
className: cn("relative", className),
|
|
599
586
|
children: [
|
|
600
|
-
dragOver && (overlay || /* @__PURE__ */ jsx7("div", { className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-
|
|
601
|
-
/* @__PURE__ */ jsx7("div", { className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl bg-[
|
|
602
|
-
|
|
603
|
-
|
|
587
|
+
dragOver && (overlay || /* @__PURE__ */ jsx7("div", { className: "fixed inset-0 z-[100] flex items-center justify-center pointer-events-none bg-[var(--depth-1)]", children: /* @__PURE__ */ jsxs5("div", { className: "rounded-2xl border-2 border-dashed border-[var(--border-accent)] bg-[var(--depth-2)] p-16 text-center shadow-[var(--shadow-dropdown)] max-w-lg mx-auto", children: [
|
|
588
|
+
/* @__PURE__ */ jsx7("div", { className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl border border-[var(--border-accent)] bg-[var(--accent-surface-soft)]", children: typeof icon === "string" ? /* @__PURE__ */ jsxs5("svg", { xmlns: "http://www.w3.org/2000/svg", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", className: "h-10 w-10 text-[var(--accent-text)]", children: [
|
|
589
|
+
/* @__PURE__ */ jsx7("title", { children: "Upload" }),
|
|
590
|
+
/* @__PURE__ */ jsx7("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
|
|
591
|
+
/* @__PURE__ */ jsx7("polyline", { points: "17 8 12 3 7 8" }),
|
|
592
|
+
/* @__PURE__ */ jsx7("line", { x1: "12", x2: "12", y1: "3", y2: "15" })
|
|
593
|
+
] }) : icon }),
|
|
594
|
+
/* @__PURE__ */ jsx7("h2", { className: "text-2xl font-bold text-[var(--text-primary)]", children: title }),
|
|
595
|
+
/* @__PURE__ */ jsx7("p", { className: "mt-2 text-sm text-[var(--text-muted)]", children: description })
|
|
604
596
|
] }) })),
|
|
605
597
|
children
|
|
606
598
|
]
|
|
@@ -609,6 +601,7 @@ function DropZone({
|
|
|
609
601
|
}
|
|
610
602
|
|
|
611
603
|
// src/primitives/upload-progress.tsx
|
|
604
|
+
import { AlertCircle as AlertCircle2, CheckCircle2 as CheckCircle22, FileText, Loader2, RefreshCw, X as X2 } from "lucide-react";
|
|
612
605
|
import { jsx as jsx8, jsxs as jsxs6 } from "react/jsx-runtime";
|
|
613
606
|
function formatSize(bytes) {
|
|
614
607
|
if (bytes < 1024) return `${bytes}B`;
|
|
@@ -622,45 +615,35 @@ function UploadProgress({ files, onRemove, onRetry, className }) {
|
|
|
622
615
|
{
|
|
623
616
|
className: cn(
|
|
624
617
|
"flex items-center gap-3 rounded-lg border px-3 py-2 text-sm",
|
|
625
|
-
file.status === "error" ? "border-[
|
|
618
|
+
file.status === "error" ? "border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)]" : file.status === "complete" ? "border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]" : "border-[var(--border-subtle)] bg-[var(--depth-2)]"
|
|
626
619
|
),
|
|
627
620
|
children: [
|
|
628
|
-
/* @__PURE__ */ jsx8(
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
file.status === "complete" && "text-[hsl(var(--success))]",
|
|
634
|
-
file.status === "error" && "text-[hsl(var(--destructive))]",
|
|
635
|
-
file.status === "uploading" && "text-[hsl(var(--primary))] animate-pulse",
|
|
636
|
-
file.status === "pending" && "text-[hsl(var(--muted-foreground))]"
|
|
637
|
-
),
|
|
638
|
-
style: file.status === "complete" ? { fontVariationSettings: "'FILL' 1" } : void 0,
|
|
639
|
-
children: file.status === "complete" ? "check_circle" : file.status === "error" ? "error" : file.status === "uploading" ? "progress_activity" : "description"
|
|
640
|
-
}
|
|
641
|
-
),
|
|
642
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex-1 min-w-0", children: [
|
|
621
|
+
file.status === "complete" && /* @__PURE__ */ jsx8(CheckCircle22, { className: "h-4 w-4 shrink-0 text-[var(--surface-success-text)]" }),
|
|
622
|
+
file.status === "error" && /* @__PURE__ */ jsx8(AlertCircle2, { className: "h-4 w-4 shrink-0 text-[var(--surface-danger-text)]" }),
|
|
623
|
+
file.status === "uploading" && /* @__PURE__ */ jsx8(Loader2, { className: "h-4 w-4 shrink-0 animate-spin text-[var(--brand-cool)]" }),
|
|
624
|
+
file.status === "pending" && /* @__PURE__ */ jsx8(FileText, { className: "h-4 w-4 shrink-0 text-[var(--text-muted)]" }),
|
|
625
|
+
/* @__PURE__ */ jsxs6("div", { className: "min-w-0 flex-1", children: [
|
|
643
626
|
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
|
|
644
|
-
/* @__PURE__ */ jsx8("span", { className: "truncate font-medium text-[
|
|
645
|
-
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-xs text-[
|
|
627
|
+
/* @__PURE__ */ jsx8("span", { className: "truncate font-medium text-[var(--text-primary)]", children: file.name }),
|
|
628
|
+
/* @__PURE__ */ jsx8("span", { className: "shrink-0 text-xs text-[var(--text-muted)]", children: formatSize(file.size) })
|
|
646
629
|
] }),
|
|
647
|
-
file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */ jsx8("div", { className: "mt-1 h-1 w-full rounded-full bg-[
|
|
630
|
+
file.status === "uploading" && file.progress !== void 0 && /* @__PURE__ */ jsx8("div", { className: "mt-1 h-1 w-full overflow-hidden rounded-full bg-[var(--depth-3)]", children: /* @__PURE__ */ jsx8(
|
|
648
631
|
"div",
|
|
649
632
|
{
|
|
650
|
-
className: "h-full rounded-full bg-[
|
|
633
|
+
className: "h-full rounded-full bg-[var(--brand-cool)] transition-all",
|
|
651
634
|
style: { width: `${file.progress}%` }
|
|
652
635
|
}
|
|
653
636
|
) }),
|
|
654
|
-
file.status === "error" && file.error && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-[
|
|
637
|
+
file.status === "error" && file.error && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-[var(--surface-danger-text)]", children: file.error })
|
|
655
638
|
] }),
|
|
656
|
-
/* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-1
|
|
639
|
+
/* @__PURE__ */ jsxs6("div", { className: "flex shrink-0 items-center gap-1", children: [
|
|
657
640
|
file.status === "error" && onRetry && /* @__PURE__ */ jsx8(
|
|
658
641
|
"button",
|
|
659
642
|
{
|
|
660
643
|
type: "button",
|
|
661
644
|
onClick: () => onRetry(file.id),
|
|
662
|
-
className: "rounded p-1 text-[
|
|
663
|
-
children: /* @__PURE__ */ jsx8(
|
|
645
|
+
className: "rounded p-1 text-[var(--text-muted)] transition-colors hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)]",
|
|
646
|
+
children: /* @__PURE__ */ jsx8(RefreshCw, { className: "h-3.5 w-3.5" })
|
|
664
647
|
}
|
|
665
648
|
),
|
|
666
649
|
onRemove && /* @__PURE__ */ jsx8(
|
|
@@ -668,8 +651,8 @@ function UploadProgress({ files, onRemove, onRetry, className }) {
|
|
|
668
651
|
{
|
|
669
652
|
type: "button",
|
|
670
653
|
onClick: () => onRemove(file.id),
|
|
671
|
-
className: "rounded p-1 text-[
|
|
672
|
-
children: /* @__PURE__ */ jsx8(
|
|
654
|
+
className: "rounded p-1 text-[var(--text-muted)] transition-colors hover:bg-[var(--bg-hover)] hover:text-[var(--text-primary)]",
|
|
655
|
+
children: /* @__PURE__ */ jsx8(X2, { className: "h-3.5 w-3.5" })
|
|
673
656
|
}
|
|
674
657
|
)
|
|
675
658
|
] })
|
|
@@ -752,7 +735,7 @@ function SidebarDropZone({
|
|
|
752
735
|
className: cn(
|
|
753
736
|
"rounded-lg border-2 border-dashed transition-all duration-150",
|
|
754
737
|
isVisible ? "p-4" : "p-0 border-transparent",
|
|
755
|
-
dragOver ? "border-[var(--brand-cool,hsl(var(--ring)))] bg-[var(--
|
|
738
|
+
dragOver ? "border-[var(--brand-cool,hsl(var(--ring)))] bg-[var(--accent-surface-soft)]" : persistent ? "border-[var(--border-subtle,hsl(var(--border)))] bg-transparent hover:border-[var(--border-default,hsl(var(--border)))] hover:bg-[var(--bg-hover,hsl(var(--accent)))]" : "",
|
|
756
739
|
disabled && "opacity-50 pointer-events-none",
|
|
757
740
|
className
|
|
758
741
|
),
|
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
// src/hooks/use-pty-session.ts
|
|
2
|
+
import { useState, useEffect, useRef, useCallback } from "react";
|
|
3
|
+
function usePtySession({ apiUrl, token, onData }) {
|
|
4
|
+
const [isConnected, setIsConnected] = useState(false);
|
|
5
|
+
const [error, setError] = useState(null);
|
|
6
|
+
const sessionIdRef = useRef(null);
|
|
7
|
+
const abortRef = useRef(null);
|
|
8
|
+
const retryTimerRef = useRef(void 0);
|
|
9
|
+
const retryCountRef = useRef(0);
|
|
10
|
+
const mountedRef = useRef(true);
|
|
11
|
+
const onDataRef = useRef(onData);
|
|
12
|
+
onDataRef.current = onData;
|
|
13
|
+
const connectStreamRef = useRef(null);
|
|
14
|
+
const abortStream = useCallback(() => {
|
|
15
|
+
if (retryTimerRef.current) {
|
|
16
|
+
clearTimeout(retryTimerRef.current);
|
|
17
|
+
retryTimerRef.current = void 0;
|
|
18
|
+
}
|
|
19
|
+
if (abortRef.current) {
|
|
20
|
+
abortRef.current.abort();
|
|
21
|
+
abortRef.current = null;
|
|
22
|
+
}
|
|
23
|
+
}, []);
|
|
24
|
+
const cleanup = useCallback(() => {
|
|
25
|
+
abortStream();
|
|
26
|
+
if (sessionIdRef.current) {
|
|
27
|
+
const sid = sessionIdRef.current;
|
|
28
|
+
sessionIdRef.current = null;
|
|
29
|
+
fetch(`${apiUrl}/terminals/${sid}`, {
|
|
30
|
+
method: "DELETE",
|
|
31
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
32
|
+
credentials: "include"
|
|
33
|
+
}).catch(() => {
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
setIsConnected(false);
|
|
37
|
+
}, [apiUrl, token, abortStream]);
|
|
38
|
+
const connectStream = useCallback(async (sessionId) => {
|
|
39
|
+
abortStream();
|
|
40
|
+
setError(null);
|
|
41
|
+
try {
|
|
42
|
+
const controller = new AbortController();
|
|
43
|
+
abortRef.current = controller;
|
|
44
|
+
const streamRes = await fetch(`${apiUrl}/terminals/${sessionId}/stream`, {
|
|
45
|
+
headers: { Authorization: `Bearer ${token}` },
|
|
46
|
+
credentials: "include",
|
|
47
|
+
signal: controller.signal
|
|
48
|
+
});
|
|
49
|
+
if (!streamRes.ok || !streamRes.body) {
|
|
50
|
+
const err = new Error(`SSE stream failed: ${streamRes.status}`);
|
|
51
|
+
err.httpStatus = streamRes.status;
|
|
52
|
+
throw err;
|
|
53
|
+
}
|
|
54
|
+
if (mountedRef.current) {
|
|
55
|
+
setIsConnected(true);
|
|
56
|
+
setError(null);
|
|
57
|
+
retryCountRef.current = 0;
|
|
58
|
+
}
|
|
59
|
+
const reader = streamRes.body.getReader();
|
|
60
|
+
const decoder = new TextDecoder();
|
|
61
|
+
let buffer = "";
|
|
62
|
+
while (true) {
|
|
63
|
+
const { done, value } = await reader.read();
|
|
64
|
+
if (done) break;
|
|
65
|
+
buffer += decoder.decode(value, { stream: true });
|
|
66
|
+
const frames = buffer.split("\n\n");
|
|
67
|
+
buffer = frames.pop() ?? "";
|
|
68
|
+
for (const frame of frames) {
|
|
69
|
+
if (!frame.trim()) continue;
|
|
70
|
+
for (const line of frame.split("\n")) {
|
|
71
|
+
if (line.startsWith("data:")) {
|
|
72
|
+
const raw = line.slice(5).trim();
|
|
73
|
+
if (!raw) continue;
|
|
74
|
+
try {
|
|
75
|
+
const event = JSON.parse(raw);
|
|
76
|
+
if (event.type === "data.stdout" || event.type === "data.stderr") {
|
|
77
|
+
const text = event.properties?.text ?? "";
|
|
78
|
+
if (text && mountedRef.current) {
|
|
79
|
+
onDataRef.current(text);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
} catch {
|
|
83
|
+
if (mountedRef.current) {
|
|
84
|
+
onDataRef.current(raw);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
}
|
|
90
|
+
}
|
|
91
|
+
if (mountedRef.current) {
|
|
92
|
+
setIsConnected(false);
|
|
93
|
+
retryTimerRef.current = setTimeout(() => {
|
|
94
|
+
if (mountedRef.current && sessionIdRef.current) {
|
|
95
|
+
connectStreamRef.current?.(sessionIdRef.current);
|
|
96
|
+
}
|
|
97
|
+
}, 1e3);
|
|
98
|
+
}
|
|
99
|
+
} catch (err) {
|
|
100
|
+
if (err.name === "AbortError") return;
|
|
101
|
+
if (mountedRef.current) {
|
|
102
|
+
const message = err instanceof Error ? err.message : "Stream connection failed";
|
|
103
|
+
setError(message);
|
|
104
|
+
setIsConnected(false);
|
|
105
|
+
const httpStatus = err.httpStatus;
|
|
106
|
+
const is4xx = httpStatus !== void 0 && httpStatus >= 400 && httpStatus < 500;
|
|
107
|
+
const MAX_RETRIES = 8;
|
|
108
|
+
if (!is4xx && retryCountRef.current < MAX_RETRIES) {
|
|
109
|
+
const delay = Math.min(3e3 * Math.pow(2, retryCountRef.current), 3e4);
|
|
110
|
+
retryCountRef.current++;
|
|
111
|
+
retryTimerRef.current = setTimeout(() => {
|
|
112
|
+
if (mountedRef.current && sessionIdRef.current) {
|
|
113
|
+
connectStreamRef.current?.(sessionIdRef.current);
|
|
114
|
+
}
|
|
115
|
+
}, delay);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
}, [apiUrl, token, abortStream]);
|
|
120
|
+
connectStreamRef.current = connectStream;
|
|
121
|
+
const connect = useCallback(async () => {
|
|
122
|
+
cleanup();
|
|
123
|
+
retryCountRef.current = 0;
|
|
124
|
+
setError(null);
|
|
125
|
+
try {
|
|
126
|
+
const res = await fetch(`${apiUrl}/terminals`, {
|
|
127
|
+
method: "POST",
|
|
128
|
+
headers: {
|
|
129
|
+
Authorization: `Bearer ${token}`,
|
|
130
|
+
"Content-Type": "application/json"
|
|
131
|
+
},
|
|
132
|
+
credentials: "include"
|
|
133
|
+
});
|
|
134
|
+
if (!res.ok) {
|
|
135
|
+
throw new Error(`Failed to create terminal: ${res.status}`);
|
|
136
|
+
}
|
|
137
|
+
const body = await res.json();
|
|
138
|
+
const sessionId = body.data?.sessionId ?? body.sessionId;
|
|
139
|
+
if (!sessionId) throw new Error("No sessionId in response");
|
|
140
|
+
if (!mountedRef.current) return;
|
|
141
|
+
sessionIdRef.current = sessionId;
|
|
142
|
+
await connectStream(sessionId);
|
|
143
|
+
} catch (err) {
|
|
144
|
+
if (err.name === "AbortError") return;
|
|
145
|
+
if (mountedRef.current) {
|
|
146
|
+
const message = err instanceof Error ? err.message : "Terminal connection failed";
|
|
147
|
+
setError(message);
|
|
148
|
+
setIsConnected(false);
|
|
149
|
+
}
|
|
150
|
+
}
|
|
151
|
+
}, [apiUrl, token, cleanup, connectStream]);
|
|
152
|
+
const sendCommand = useCallback(async (command) => {
|
|
153
|
+
const sid = sessionIdRef.current;
|
|
154
|
+
if (!sid) return;
|
|
155
|
+
const res = await fetch(`${apiUrl}/terminals/${sid}/input`, {
|
|
156
|
+
method: "POST",
|
|
157
|
+
headers: {
|
|
158
|
+
Authorization: `Bearer ${token}`,
|
|
159
|
+
"Content-Type": "application/json"
|
|
160
|
+
},
|
|
161
|
+
credentials: "include",
|
|
162
|
+
body: JSON.stringify({ data: command })
|
|
163
|
+
});
|
|
164
|
+
if (!res.ok) {
|
|
165
|
+
const text = await res.text();
|
|
166
|
+
throw new Error(text || `Input failed: ${res.status}`);
|
|
167
|
+
}
|
|
168
|
+
}, [apiUrl, token]);
|
|
169
|
+
useEffect(() => {
|
|
170
|
+
mountedRef.current = true;
|
|
171
|
+
connect();
|
|
172
|
+
return () => {
|
|
173
|
+
mountedRef.current = false;
|
|
174
|
+
cleanup();
|
|
175
|
+
};
|
|
176
|
+
}, [connect, cleanup]);
|
|
177
|
+
return { isConnected, error, sendCommand, reconnect: connect };
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
export {
|
|
181
|
+
usePtySession
|
|
182
|
+
};
|
|
@@ -9,7 +9,7 @@ import {
|
|
|
9
9
|
} from "./chunk-W4LM3QYZ.js";
|
|
10
10
|
import {
|
|
11
11
|
Markdown
|
|
12
|
-
} from "./chunk-
|
|
12
|
+
} from "./chunk-H5XYSFYE.js";
|
|
13
13
|
import {
|
|
14
14
|
cn
|
|
15
15
|
} from "./chunk-RQHJBTEU.js";
|
|
@@ -21,7 +21,7 @@ import { PencilLine, Save, Users, Wifi, WifiOff } from "lucide-react";
|
|
|
21
21
|
// src/editor/tiptap-editor.tsx
|
|
22
22
|
import Collaboration from "@tiptap/extension-collaboration";
|
|
23
23
|
|
|
24
|
-
// node_modules/@tiptap/extension-collaboration-caret/dist/index.js
|
|
24
|
+
// node_modules/.pnpm/@tiptap+extension-collaboration-caret@3.21.0_@tiptap+core@3.20.4_@tiptap+pm@3.20.4__@ti_795f003f8529614c8766f32d0d0747ee/node_modules/@tiptap/extension-collaboration-caret/dist/index.js
|
|
25
25
|
import { Extension } from "@tiptap/core";
|
|
26
26
|
import { defaultSelectionBuilder, yCursorPlugin } from "@tiptap/y-tiptap";
|
|
27
27
|
var awarenessStatesToArray = (states) => {
|
|
@@ -701,7 +701,7 @@ function EditorToolbar({
|
|
|
701
701
|
"div",
|
|
702
702
|
{
|
|
703
703
|
className: cn(
|
|
704
|
-
"flex items-center gap-1 border-border border-b bg-
|
|
704
|
+
"flex items-center gap-1 border-border border-b bg-[var(--depth-2)] p-2",
|
|
705
705
|
className
|
|
706
706
|
),
|
|
707
707
|
children: buttons.map((button) => {
|
|
@@ -820,7 +820,7 @@ function EditorToolbar2({
|
|
|
820
820
|
"div",
|
|
821
821
|
{
|
|
822
822
|
className: cn(
|
|
823
|
-
"flex items-center gap-1 border-border border-b bg-
|
|
823
|
+
"flex items-center gap-1 border-border border-b bg-[var(--depth-2)] p-2",
|
|
824
824
|
className
|
|
825
825
|
),
|
|
826
826
|
children: buttons.map((button) => {
|
|
@@ -941,7 +941,7 @@ function MarkdownDocumentEditor({
|
|
|
941
941
|
EditorToolbar2,
|
|
942
942
|
{
|
|
943
943
|
editor,
|
|
944
|
-
className: "border-[var(--border-subtle)] bg-[var(--
|
|
944
|
+
className: "border-[var(--border-subtle)] bg-[var(--depth-2)] px-2 py-2"
|
|
945
945
|
}
|
|
946
946
|
),
|
|
947
947
|
/* @__PURE__ */ jsx4("div", { className: "min-h-0 flex-1 overflow-auto px-5 py-4", children: /* @__PURE__ */ jsx4(EditorContent2, { editor }) }),
|
|
@@ -963,7 +963,7 @@ function MarkdownDocumentEditor({
|
|
|
963
963
|
}
|
|
964
964
|
|
|
965
965
|
.ProseMirror code {
|
|
966
|
-
background: var(--
|
|
966
|
+
background: var(--depth-3);
|
|
967
967
|
border-radius: 0.35rem;
|
|
968
968
|
padding: 0.12rem 0.3rem;
|
|
969
969
|
}
|
|
@@ -1131,13 +1131,13 @@ import { jsx as jsx5, jsxs as jsxs3 } from "react/jsx-runtime";
|
|
|
1131
1131
|
function connectionTone(state) {
|
|
1132
1132
|
switch (state) {
|
|
1133
1133
|
case "synced":
|
|
1134
|
-
return "text-
|
|
1134
|
+
return "text-[var(--surface-success-text)] border-[var(--surface-success-border)] bg-[var(--surface-success-bg)]";
|
|
1135
1135
|
case "connected":
|
|
1136
1136
|
case "connecting":
|
|
1137
|
-
return "text-
|
|
1137
|
+
return "text-[var(--surface-info-text)] border-[var(--surface-info-border)] bg-[var(--surface-info-bg)]";
|
|
1138
1138
|
case "disconnected":
|
|
1139
1139
|
default:
|
|
1140
|
-
return "text-
|
|
1140
|
+
return "text-[var(--surface-warning-text)] border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)]";
|
|
1141
1141
|
}
|
|
1142
1142
|
}
|
|
1143
1143
|
function connectionLabel(state) {
|
|
@@ -1181,7 +1181,7 @@ function CollaborativeDocumentSurface({
|
|
|
1181
1181
|
const initialContent = useMemo4(() => markdownToHtml(markdown), [markdown]);
|
|
1182
1182
|
const collaboratorCount = collaborators.length + 1;
|
|
1183
1183
|
return /* @__PURE__ */ jsxs3("div", { className: cn("flex h-full min-h-0 flex-col gap-3", className), children: [
|
|
1184
|
-
/* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center justify-between gap-3 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--
|
|
1184
|
+
/* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center justify-between gap-3 rounded-[var(--radius-lg)] border border-[var(--border-subtle)] bg-[var(--depth-2)] px-3 py-2", children: [
|
|
1185
1185
|
/* @__PURE__ */ jsxs3("div", { className: "min-w-0 space-y-2", children: [
|
|
1186
1186
|
/* @__PURE__ */ jsxs3("div", { className: "flex flex-wrap items-center gap-2 text-xs text-[var(--text-muted)]", children: [
|
|
1187
1187
|
/* @__PURE__ */ jsxs3(
|