@tangle-network/sandbox-ui 0.4.0 → 0.5.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.
Files changed (61) hide show
  1. package/dist/auth.js +3 -3
  2. package/dist/chat.d.ts +1 -1
  3. package/dist/chat.js +11 -9
  4. package/dist/{chunk-ZP6GSX4D.js → chunk-565V6JTN.js} +26 -50
  5. package/dist/chunk-5CEMHKBP.js +72 -0
  6. package/dist/{chunk-FOQTE67I.js → chunk-5F4NX5R2.js} +10 -5
  7. package/dist/{chunk-MUOL44AE.js → chunk-BRBTD7RH.js} +6 -6
  8. package/dist/{chunk-SSKVYXCR.js → chunk-DCPYTL4W.js} +62 -79
  9. package/dist/chunk-DLCFZDGX.js +182 -0
  10. package/dist/{chunk-HXEA7L2T.js → chunk-FFOXUHOF.js} +10 -10
  11. package/dist/chunk-H5XYSFYE.js +228 -0
  12. package/dist/{chunk-TQN3VR4F.js → chunk-JP725R4W.js} +2 -2
  13. package/dist/{chunk-CJ2RYVZH.js → chunk-NTSRY4GW.js} +68 -10
  14. package/dist/{chunk-DQYODCBN.js → chunk-P24K22CV.js} +57 -66
  15. package/dist/{chunk-GVUW4VDD.js → chunk-R3IU37AW.js} +161 -229
  16. package/dist/chunk-TDYQBLL5.js +127 -0
  17. package/dist/{chunk-HWLX5NME.js → chunk-TSE423UF.js} +12 -12
  18. package/dist/{chunk-YDBXQQLC.js → chunk-VBWY44UU.js} +30 -76
  19. package/dist/{chunk-IW2JZCOC.js → chunk-WBQ7VULC.js} +7 -7
  20. package/dist/{chunk-72UEKFZ2.js → chunk-WC7QTWPN.js} +65 -42
  21. package/dist/{chunk-HYLTXGOI.js → chunk-WQH233GF.js} +5 -5
  22. package/dist/{chunk-CCKNIAS7.js → chunk-XBR3IP7B.js} +2 -2
  23. package/dist/{chunk-OHMO7NUX.js → chunk-XTPAWK7L.js} +20 -31
  24. package/dist/{chunk-SULQQJPB.js → chunk-YS66Q3RC.js} +1 -1
  25. package/dist/{chunk-FRGMMANX.js → chunk-YYGECNZZ.js} +3 -3
  26. package/dist/{chunk-MVYFNPAH.js → chunk-ZOZX2U6I.js} +285 -271
  27. package/dist/dashboard.d.ts +2 -2
  28. package/dist/dashboard.js +6 -6
  29. package/dist/{document-editor-pane-5TN2VWGZ.js → document-editor-pane-JNXPANWM.js} +2 -2
  30. package/dist/editor.js +2 -2
  31. package/dist/files.js +2 -2
  32. package/dist/globals.css +129 -95
  33. package/dist/hooks.d.ts +2 -2
  34. package/dist/hooks.js +5 -5
  35. package/dist/{index-tTfThG0n.d.ts → index-CDt0GE4A.d.ts} +7 -8
  36. package/dist/index.d.ts +16 -23
  37. package/dist/index.js +27 -26
  38. package/dist/markdown.d.ts +14 -17
  39. package/dist/markdown.js +1 -1
  40. package/dist/openui.js +5 -5
  41. package/dist/pages.d.ts +10 -3
  42. package/dist/pages.js +147 -184
  43. package/dist/primitives.d.ts +8 -5
  44. package/dist/primitives.js +8 -8
  45. package/dist/run.d.ts +1 -1
  46. package/dist/run.js +4 -4
  47. package/dist/sdk-hooks.d.ts +1 -1
  48. package/dist/sdk-hooks.js +4 -4
  49. package/dist/styles.css +129 -95
  50. package/dist/terminal.d.ts +2 -2
  51. package/dist/terminal.js +13 -43
  52. package/dist/tokens.css +299 -179
  53. package/dist/{tool-call-feed-D5Ume-Pt.d.ts → tool-call-feed-Bs3MyQMT.d.ts} +3 -1
  54. package/dist/{usage-chart-CY9xo3KX.d.ts → usage-chart-XCoB_7Xu.d.ts} +1 -2
  55. package/dist/{use-pty-session-DeZSxOCN.d.ts → use-pty-session-COzVkhtc.d.ts} +1 -1
  56. package/dist/workspace.d.ts +3 -1
  57. package/dist/workspace.js +11 -11
  58. package/package.json +14 -2
  59. package/dist/chunk-GRYHFH5O.js +0 -110
  60. package/dist/chunk-LTFK464G.js +0 -103
  61. package/dist/chunk-MXCSSOGH.js +0 -105
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  Card
3
- } from "./chunk-MXCSSOGH.js";
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-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",
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-popover text-popover-foreground shadow-md data-[state=closed]:animate-out data-[state=open]:animate-in",
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-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",
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-muted", className),
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-green-500/20 bg-green-500/10 text-green-400",
164
- error: "border-red-500/20 bg-red-500/10 text-red-400",
165
- warning: "border-yellow-500/20 bg-yellow-500/10 text-yellow-400",
166
- info: "border-blue-500/20 bg-blue-500/10 text-blue-400"
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-foreground",
319
+ default: "text-[var(--text-muted)]",
320
320
  sandbox: "text-[var(--accent-text)]"
321
321
  };
322
322
  const trendColors = {
323
- positive: "text-green-400",
324
- negative: "text-red-400",
325
- neutral: "text-muted-foreground"
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-foreground text-sm", children: title }),
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-foreground/70 text-xs", children: subtitle }),
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-foreground", children: trend.label })
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-muted/50 p-2",
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-[#0a0a0a] font-mono text-sm",
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__ */ jsxs4("div", { className: "flex items-center gap-2 border-border/50 border-b bg-card/30 px-4 py-3", children: [
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-foreground",
445
- output: "text-muted-foreground",
446
- error: "text-red-400",
447
- success: "text-green-400",
448
- info: "text-blue-400",
449
- thinking: "text-yellow-400 animate-pulse",
450
- command: "text-foreground",
451
- warning: "text-yellow-400"
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-green-400", children: prompt }),
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-foreground/50", children: [
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-foreground",
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-muted-foreground",
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-[#0a0a0a] px-4 py-2.5 font-mono text-sm transition-colors",
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-green-400", children: "$" }),
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-foreground outline-none placeholder:text-muted-foreground",
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-black/20 backdrop-blur-sm", children: /* @__PURE__ */ jsxs5("div", { className: "rounded-3xl border-2 border-dashed border-[hsl(var(--ring))] bg-[hsl(var(--card))] p-16 text-center shadow-2xl max-w-lg mx-auto", children: [
601
- /* @__PURE__ */ jsx7("div", { className: "mx-auto mb-6 flex h-20 w-20 items-center justify-center rounded-2xl bg-[hsl(var(--primary))]/10", children: typeof icon === "string" ? /* @__PURE__ */ jsx7("span", { className: "material-symbols-outlined text-5xl text-[hsl(var(--primary))]", children: icon }) : icon }),
602
- /* @__PURE__ */ jsx7("h2", { className: "text-2xl font-extrabold text-[hsl(var(--foreground))]", children: title }),
603
- /* @__PURE__ */ jsx7("p", { className: "mt-2 text-[hsl(var(--muted-foreground))]", children: description })
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-[hsl(var(--destructive))]/20 bg-[hsl(var(--destructive))]/5" : file.status === "complete" ? "border-[hsl(var(--success))]/20 bg-[hsl(var(--success))]/5" : "border-[hsl(var(--border))] bg-[hsl(var(--card))]"
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
- "span",
630
- {
631
- className: cn(
632
- "material-symbols-outlined text-base shrink-0",
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-[hsl(var(--foreground))]", children: file.name }),
645
- /* @__PURE__ */ jsx8("span", { className: "shrink-0 text-xs text-[hsl(var(--muted-foreground))]", children: formatSize(file.size) })
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-[hsl(var(--muted))] overflow-hidden", children: /* @__PURE__ */ jsx8(
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-[hsl(var(--primary))] transition-all",
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-[hsl(var(--destructive))]", children: file.error })
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 shrink-0", children: [
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-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] transition-colors",
663
- children: /* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-sm", children: "refresh" })
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-[hsl(var(--muted-foreground))] hover:bg-[hsl(var(--accent))] hover:text-[hsl(var(--foreground))] transition-colors",
672
- children: /* @__PURE__ */ jsx8("span", { className: "material-symbols-outlined text-sm", children: "close" })
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(--brand-cool,hsl(var(--primary)))]/8" : 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)))]/50" : "",
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-LTFK464G.js";
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-muted/50 p-2",
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-muted/50 p-2",
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(--bg-card)]/80 px-2 py-2"
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(--bg-hover, rgba(255,255,255,0.05));
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-emerald-300 border-emerald-400/30 bg-emerald-400/10";
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-sky-300 border-sky-400/30 bg-sky-400/10";
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-amber-200 border-amber-300/30 bg-amber-300/10";
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(--bg-card)]/80 px-3 py-2", 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(--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(