@tangle-network/sandbox-ui 0.24.0 → 0.24.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/pages.js CHANGED
@@ -8,6 +8,12 @@ import {
8
8
  import {
9
9
  Badge,
10
10
  Button,
11
+ Dialog,
12
+ DialogContent,
13
+ DialogDescription,
14
+ DialogFooter,
15
+ DialogHeader,
16
+ DialogTitle,
11
17
  Input,
12
18
  Switch,
13
19
  Textarea
@@ -50,6 +56,7 @@ function AuthPage({
50
56
  providers = ["github", "google"],
51
57
  socialHref = (p) => `/api/auth/sign-in/social?provider=${p}&callbackURL=/app`,
52
58
  onEmailSubmit,
59
+ collectName,
53
60
  altHref,
54
61
  accent = "#0f172a",
55
62
  accentHover = "#1e293b",
@@ -58,11 +65,13 @@ function AuthPage({
58
65
  style,
59
66
  children
60
67
  }) {
68
+ const [name, setName] = useState("");
61
69
  const [email, setEmail] = useState("");
62
70
  const [password, setPassword] = useState("");
63
71
  const [error, setError] = useState("");
64
72
  const [loading, setLoading] = useState(false);
65
73
  const isSignup = mode === "signup";
74
+ const showName = collectName ?? isSignup;
66
75
  const tangleLabel = isSignup ? "Sign up with Tangle" : "Continue with Tangle";
67
76
  const emailLabel = isSignup ? "Create account with email" : "Sign in with email";
68
77
  const handleSubmit = async (e) => {
@@ -71,7 +80,7 @@ function AuthPage({
71
80
  setLoading(true);
72
81
  setError("");
73
82
  try {
74
- const err = await onEmailSubmit(email, password);
83
+ const err = await onEmailSubmit(email, password, name);
75
84
  if (err) setError(err);
76
85
  } catch {
77
86
  setError("Connection error \u2014 please try again");
@@ -181,6 +190,7 @@ function AuthPage({
181
190
  /* @__PURE__ */ jsx("div", { style: { flex: 1, height: 1, background: C.border } })
182
191
  ] }),
183
192
  /* @__PURE__ */ jsxs("form", { onSubmit: handleSubmit, style: { display: "flex", flexDirection: "column", gap: 12 }, children: [
193
+ showName && /* @__PURE__ */ jsx("input", { type: "text", required: true, "aria-label": "Name", placeholder: "Name", autoComplete: "name", value: name, onChange: (e) => setName(e.target.value), style: inputStyle }),
184
194
  /* @__PURE__ */ jsx("input", { type: "email", required: true, "aria-label": "Email", placeholder: "Email", value: email, onChange: (e) => setEmail(e.target.value), style: inputStyle }),
185
195
  /* @__PURE__ */ jsx("input", { type: "password", required: true, "aria-label": "Password", placeholder: "Password", value: password, onChange: (e) => setPassword(e.target.value), style: inputStyle }),
186
196
  error && /* @__PURE__ */ jsx("p", { role: "alert", style: { fontSize: 14, color: "#b91c1c" }, children: error }),
@@ -458,19 +468,177 @@ function BillingPage({
458
468
  }
459
469
 
460
470
  // src/pages/provisioning-wizard.tsx
461
- import * as React2 from "react";
471
+ import * as React3 from "react";
462
472
  import {
463
473
  ArrowLeft,
464
474
  Layers,
465
475
  Cpu,
466
476
  Info,
467
- Loader2,
477
+ Loader2 as Loader22,
468
478
  Settings,
469
479
  Plus,
470
480
  Trash2,
471
481
  Check
472
482
  } from "lucide-react";
473
- import { Fragment as Fragment3, jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
483
+
484
+ // src/pages/add-ssh-key-dialog.tsx
485
+ import * as React2 from "react";
486
+ import { Loader2 } from "lucide-react";
487
+ import { jsx as jsx3, jsxs as jsxs3 } from "react/jsx-runtime";
488
+ var NAME_INPUT_ID = "add-ssh-key-name";
489
+ var KEY_INPUT_ID = "add-ssh-key-public-key";
490
+ var SSH_PUBLIC_KEY_PATTERN = /^(ssh-rsa|ssh-dss|ssh-ed25519|ecdsa-sha2-nistp256|ecdsa-sha2-nistp384|ecdsa-sha2-nistp521|sk-ecdsa-sha2-nistp256@openssh\.com|sk-ssh-ed25519@openssh\.com)\s+[A-Za-z0-9+/]+={0,3}(\s+.+)?$/;
491
+ function validateSshPublicKey(value) {
492
+ const trimmed = value.trim();
493
+ if (!trimmed) return "Public key is required";
494
+ if (!SSH_PUBLIC_KEY_PATTERN.test(trimmed))
495
+ return "Enter a valid public key, e.g. ssh-ed25519 AAAAC3NzaC1lZDI1NTE5...";
496
+ return null;
497
+ }
498
+ function AddSshKeyDialog({
499
+ open,
500
+ onOpenChange,
501
+ onCreateKey,
502
+ onRefreshKeys,
503
+ onCreatedKeyId
504
+ }) {
505
+ const [name, setName] = React2.useState("");
506
+ const [publicKey, setPublicKey] = React2.useState("");
507
+ const [errors, setErrors] = React2.useState({
508
+ name: null,
509
+ publicKey: null
510
+ });
511
+ const [submitError, setSubmitError] = React2.useState(null);
512
+ const [isSaving, setIsSaving] = React2.useState(false);
513
+ const resetForm = React2.useCallback(() => {
514
+ setName("");
515
+ setPublicKey("");
516
+ setErrors({ name: null, publicKey: null });
517
+ setSubmitError(null);
518
+ }, []);
519
+ const handleSave = async () => {
520
+ const nameError = name.trim() ? null : "Name is required";
521
+ const keyError = validateSshPublicKey(publicKey);
522
+ if (nameError || keyError) {
523
+ setErrors({ name: nameError, publicKey: keyError });
524
+ return;
525
+ }
526
+ setIsSaving(true);
527
+ setSubmitError(null);
528
+ try {
529
+ const created = await onCreateKey({
530
+ name: name.trim(),
531
+ publicKey: publicKey.trim()
532
+ });
533
+ if (onRefreshKeys) {
534
+ await onRefreshKeys();
535
+ }
536
+ if (created && created.id) {
537
+ onCreatedKeyId?.(created.id);
538
+ }
539
+ resetForm();
540
+ onOpenChange(false);
541
+ } catch (err) {
542
+ setSubmitError(
543
+ err instanceof Error ? err.message : "Failed to add SSH key"
544
+ );
545
+ } finally {
546
+ setIsSaving(false);
547
+ }
548
+ };
549
+ const handleSubmit = (e) => {
550
+ e.preventDefault();
551
+ if (!isSaving) handleSave();
552
+ };
553
+ return /* @__PURE__ */ jsx3(Dialog, { open, onOpenChange, children: /* @__PURE__ */ jsxs3(DialogContent, { className: "max-w-md", children: [
554
+ /* @__PURE__ */ jsxs3(DialogHeader, { children: [
555
+ /* @__PURE__ */ jsx3(DialogTitle, { children: "Add SSH key" }),
556
+ /* @__PURE__ */ jsx3(DialogDescription, { children: "Save a public key to your account. It will be available to select for this and future sandboxes." })
557
+ ] }),
558
+ /* @__PURE__ */ jsxs3("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
559
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-1.5", children: [
560
+ /* @__PURE__ */ jsx3(
561
+ "label",
562
+ {
563
+ htmlFor: NAME_INPUT_ID,
564
+ className: "block text-xs font-medium uppercase tracking-[0.06em] text-muted-foreground",
565
+ children: "Name"
566
+ }
567
+ ),
568
+ /* @__PURE__ */ jsx3(
569
+ "input",
570
+ {
571
+ id: NAME_INPUT_ID,
572
+ name: "name",
573
+ type: "text",
574
+ value: name,
575
+ onChange: (e) => setName(e.target.value),
576
+ placeholder: "My laptop",
577
+ autoComplete: "off",
578
+ "aria-invalid": errors.name ? true : void 0,
579
+ className: "w-full rounded-md border border-border bg-card px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
580
+ }
581
+ ),
582
+ errors.name && /* @__PURE__ */ jsx3("p", { className: "text-xs text-destructive", children: errors.name })
583
+ ] }),
584
+ /* @__PURE__ */ jsxs3("div", { className: "space-y-1.5", children: [
585
+ /* @__PURE__ */ jsx3(
586
+ "label",
587
+ {
588
+ htmlFor: KEY_INPUT_ID,
589
+ className: "block text-xs font-medium uppercase tracking-[0.06em] text-muted-foreground",
590
+ children: "Public key"
591
+ }
592
+ ),
593
+ /* @__PURE__ */ jsx3(
594
+ "textarea",
595
+ {
596
+ id: KEY_INPUT_ID,
597
+ name: "public-key",
598
+ value: publicKey,
599
+ onChange: (e) => setPublicKey(e.target.value),
600
+ placeholder: "ssh-ed25519 AAAAC3NzaC1lZDI1NTE5AAAAI...",
601
+ autoComplete: "off",
602
+ spellCheck: false,
603
+ "aria-invalid": errors.publicKey ? true : void 0,
604
+ className: "min-h-24 w-full resize-y rounded-md border border-border bg-card px-3 py-2 font-mono text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
605
+ }
606
+ ),
607
+ errors.publicKey && /* @__PURE__ */ jsx3("p", { className: "text-xs text-destructive", children: errors.publicKey })
608
+ ] }),
609
+ submitError && /* @__PURE__ */ jsx3("p", { role: "alert", className: "text-sm text-destructive", children: submitError }),
610
+ /* @__PURE__ */ jsx3("button", { type: "submit", className: "hidden", tabIndex: -1, "aria-hidden": "true", children: "Submit" })
611
+ ] }),
612
+ /* @__PURE__ */ jsxs3(DialogFooter, { children: [
613
+ /* @__PURE__ */ jsx3(
614
+ "button",
615
+ {
616
+ type: "button",
617
+ onClick: () => onOpenChange(false),
618
+ disabled: isSaving,
619
+ className: "rounded-md border border-border bg-card px-4 py-2 text-sm font-medium text-foreground hover:bg-muted transition-colors disabled:opacity-50",
620
+ children: "Cancel"
621
+ }
622
+ ),
623
+ /* @__PURE__ */ jsxs3(
624
+ "button",
625
+ {
626
+ type: "button",
627
+ onClick: handleSave,
628
+ disabled: isSaving,
629
+ className: "inline-flex items-center gap-2 rounded-md bg-primary px-4 py-2 text-sm font-bold text-primary-foreground hover:bg-primary/90 transition-colors disabled:opacity-50 active:scale-[0.97]",
630
+ children: [
631
+ isSaving && /* @__PURE__ */ jsx3(Loader2, { className: "h-4 w-4 animate-spin" }),
632
+ isSaving ? "Saving..." : "Add key"
633
+ ]
634
+ }
635
+ )
636
+ ] })
637
+ ] }) });
638
+ }
639
+
640
+ // src/pages/provisioning-wizard.tsx
641
+ import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
474
642
  var VALID_DRIVERS = /* @__PURE__ */ new Set([
475
643
  "docker",
476
644
  "firecracker",
@@ -523,7 +691,7 @@ function resolveEnvironment(env) {
523
691
  id: env.id,
524
692
  name: templateName,
525
693
  description: env.description ?? "User template from snapshot",
526
- icon: /* @__PURE__ */ jsx3("span", { className: "text-[var(--surface-success-text)] text-2xl font-bold", children: "T" }),
694
+ icon: /* @__PURE__ */ jsx4("span", { className: "text-[var(--surface-success-text)] text-2xl font-bold", children: "T" }),
527
695
  color: "green"
528
696
  };
529
697
  }
@@ -536,7 +704,7 @@ function resolveEnvironment(env) {
536
704
  id: env.id,
537
705
  name,
538
706
  description: env.description ?? `${name} development environment`,
539
- icon: /* @__PURE__ */ jsx3("span", { className: `${textClass} text-2xl font-bold`, children: abbr }),
707
+ icon: /* @__PURE__ */ jsx4("span", { className: `${textClass} text-2xl font-bold`, children: abbr }),
540
708
  color
541
709
  };
542
710
  }
@@ -545,21 +713,21 @@ var defaultEnvironments = [
545
713
  id: "node",
546
714
  name: "Node.js",
547
715
  description: "v20.x LTS with optimized runtime for asynchronous event-driven agents.",
548
- icon: /* @__PURE__ */ jsx3("span", { className: "text-[var(--code-success)] text-2xl font-bold", children: "N" }),
716
+ icon: /* @__PURE__ */ jsx4("span", { className: "text-[var(--code-success)] text-2xl font-bold", children: "N" }),
549
717
  color: "green"
550
718
  },
551
719
  {
552
720
  id: "python",
553
721
  name: "Python",
554
722
  description: "v3.11 pre-installed with PyTorch and common data science libraries.",
555
- icon: /* @__PURE__ */ jsx3("span", { className: "text-sky-400 text-2xl font-bold", children: "Py" }),
723
+ icon: /* @__PURE__ */ jsx4("span", { className: "text-sky-400 text-2xl font-bold", children: "Py" }),
556
724
  color: "blue"
557
725
  },
558
726
  {
559
727
  id: "ubuntu",
560
728
  name: "Ubuntu",
561
729
  description: "Full 22.04 LTS terminal access for custom containerized workloads.",
562
- icon: /* @__PURE__ */ jsx3("span", { className: "text-orange-400 text-2xl font-bold", children: "U" }),
730
+ icon: /* @__PURE__ */ jsx4("span", { className: "text-orange-400 text-2xl font-bold", children: "U" }),
563
731
  color: "orange"
564
732
  }
565
733
  ];
@@ -630,47 +798,79 @@ function computeHourlyCost(cpu, ram, storage, rates) {
630
798
  }
631
799
  function SshAccessStep({ config }) {
632
800
  const keys = config.keys ?? [];
801
+ const canAddKey = typeof config.onCreateKey === "function";
802
+ const [isAddKeyOpen, setIsAddKeyOpen] = React3.useState(false);
633
803
  const inlineKeyCount = config.inlinePublicKeys.split(/\r?\n/).map((key) => key.trim()).filter(Boolean).length;
634
804
  const totalKeyCount = config.selectedKeyIds.length + inlineKeyCount;
635
- return /* @__PURE__ */ jsxs3("div", { className: "space-y-4", children: [
636
- /* @__PURE__ */ jsxs3("div", { className: "flex items-start justify-between gap-4", children: [
637
- /* @__PURE__ */ jsxs3("div", { children: [
638
- /* @__PURE__ */ jsx3("p", { className: "font-medium text-foreground text-sm", children: "SSH Access" }),
639
- /* @__PURE__ */ jsx3("p", { className: "mt-1 text-muted-foreground text-xs", children: "Select stored keys or paste public keys for authorized_keys." })
805
+ return /* @__PURE__ */ jsxs4("div", { className: "space-y-4", children: [
806
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-start justify-between gap-4", children: [
807
+ /* @__PURE__ */ jsxs4("div", { children: [
808
+ /* @__PURE__ */ jsx4("p", { className: "font-medium text-foreground text-sm", children: "SSH Access" }),
809
+ /* @__PURE__ */ jsx4("p", { className: "mt-1 text-muted-foreground text-xs", children: "Select stored keys or paste public keys for authorized_keys." })
640
810
  ] }),
641
- /* @__PURE__ */ jsxs3(Badge, { variant: "outline", children: [
642
- totalKeyCount,
643
- " key",
644
- totalKeyCount === 1 ? "" : "s"
811
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2", children: [
812
+ canAddKey && /* @__PURE__ */ jsxs4(
813
+ Button,
814
+ {
815
+ type: "button",
816
+ variant: "outline",
817
+ size: "sm",
818
+ onClick: () => setIsAddKeyOpen(true),
819
+ children: [
820
+ /* @__PURE__ */ jsx4(Plus, { className: "h-3.5 w-3.5" }),
821
+ "Add SSH key"
822
+ ]
823
+ }
824
+ ),
825
+ /* @__PURE__ */ jsxs4(Badge, { variant: "outline", children: [
826
+ totalKeyCount,
827
+ " key",
828
+ totalKeyCount === 1 ? "" : "s"
829
+ ] })
645
830
  ] })
646
831
  ] }),
647
- keys.length > 0 && /* @__PURE__ */ jsx3("div", { className: "grid gap-2 sm:grid-cols-2", children: keys.map((key) => {
832
+ keys.length > 0 && /* @__PURE__ */ jsx4("div", { className: "grid gap-2 sm:grid-cols-2", children: keys.map((key) => {
648
833
  const selected = config.selectedKeyIds.includes(key.id);
649
- return /* @__PURE__ */ jsx3(
650
- Button,
834
+ return /* @__PURE__ */ jsx4(
835
+ "button",
651
836
  {
652
837
  type: "button",
653
- variant: selected ? "sandbox" : "outline",
654
- className: "h-auto justify-start p-3 text-left",
655
838
  "aria-pressed": selected,
656
839
  onClick: () => {
657
840
  config.onSelectedKeyIdsChange(
658
841
  selected ? config.selectedKeyIds.filter((id) => id !== key.id) : [...config.selectedKeyIds, key.id]
659
842
  );
660
843
  },
661
- children: /* @__PURE__ */ jsxs3("span", { className: "min-w-0", children: [
662
- /* @__PURE__ */ jsx3("span", { className: "block font-medium text-foreground", children: key.name }),
663
- /* @__PURE__ */ jsxs3("span", { className: "block truncate font-mono text-muted-foreground text-xs", children: [
664
- key.keyType,
665
- " \xB7 ",
666
- key.fingerprint
667
- ] })
844
+ className: cn(
845
+ "group p-3 text-left rounded-lg border transition-colors duration-200",
846
+ selected ? "bg-primary/5 border-primary ring-1 ring-primary/20" : "bg-card border-border hover:border-primary/30 active:scale-[0.99]"
847
+ ),
848
+ children: /* @__PURE__ */ jsxs4("div", { className: "flex items-start justify-between gap-2", children: [
849
+ /* @__PURE__ */ jsxs4("span", { className: "min-w-0", children: [
850
+ /* @__PURE__ */ jsx4("span", { className: "block font-medium text-sm text-foreground", children: key.name }),
851
+ /* @__PURE__ */ jsxs4("span", { className: "block truncate font-mono text-muted-foreground text-xs", children: [
852
+ key.keyType,
853
+ " \xB7 ",
854
+ key.fingerprint
855
+ ] })
856
+ ] }),
857
+ /* @__PURE__ */ jsx4(
858
+ "span",
859
+ {
860
+ "aria-hidden": "true",
861
+ className: cn(
862
+ "flex h-4 w-4 shrink-0 items-center justify-center rounded-[4px] border-2 transition-colors duration-200",
863
+ selected ? "border-primary bg-primary" : "border-border group-hover:border-primary/40"
864
+ ),
865
+ children: selected && /* @__PURE__ */ jsx4(Check, { className: "h-2.5 w-2.5 text-primary-foreground" })
866
+ }
867
+ )
668
868
  ] })
669
869
  },
670
870
  key.id
671
871
  );
672
872
  }) }),
673
- /* @__PURE__ */ jsx3(
873
+ /* @__PURE__ */ jsx4(
674
874
  Textarea,
675
875
  {
676
876
  className: "min-h-24 font-mono text-xs",
@@ -678,6 +878,18 @@ function SshAccessStep({ config }) {
678
878
  value: config.inlinePublicKeys,
679
879
  onChange: (event) => config.onInlinePublicKeysChange(event.target.value)
680
880
  }
881
+ ),
882
+ canAddKey && /* @__PURE__ */ jsx4(
883
+ AddSshKeyDialog,
884
+ {
885
+ open: isAddKeyOpen,
886
+ onOpenChange: setIsAddKeyOpen,
887
+ onCreateKey: config.onCreateKey,
888
+ onRefreshKeys: config.onRefreshKeys,
889
+ onCreatedKeyId: (id) => config.onSelectedKeyIdsChange(
890
+ config.selectedKeyIds.includes(id) ? config.selectedKeyIds : [...config.selectedKeyIds, id]
891
+ )
892
+ }
681
893
  )
682
894
  ] });
683
895
  }
@@ -687,10 +899,8 @@ function ProvisioningWizard({
687
899
  onSubmit,
688
900
  onBack,
689
901
  className,
690
- variant = "flat",
691
902
  defaultEnvironment,
692
903
  defaultConfig,
693
- skipToReview,
694
904
  onLoadStartupScripts,
695
905
  resourceLimits,
696
906
  sshAccess,
@@ -713,17 +923,17 @@ function ProvisioningWizard({
713
923
  const ramStep = alignSliderStep(RAM_MIN, ramMax, RAM_STEP);
714
924
  const storageStep = alignSliderStep(STORAGE_MIN, storageMax, STORAGE_STEP);
715
925
  const dc = defaultConfig;
716
- const [envList, setEnvList] = React2.useState(() => {
926
+ const [envList, setEnvList] = React3.useState(() => {
717
927
  if (environmentsProp) return environmentsProp;
718
928
  if (onLoadEnvironments) return [];
719
929
  return defaultEnvironments;
720
930
  });
721
- const [isLoadingEnvironments, setIsLoadingEnvironments] = React2.useState(
931
+ const [isLoadingEnvironments, setIsLoadingEnvironments] = React3.useState(
722
932
  () => !environmentsProp && !!onLoadEnvironments
723
933
  );
724
- const onLoadEnvironmentsRef = React2.useRef(onLoadEnvironments);
934
+ const onLoadEnvironmentsRef = React3.useRef(onLoadEnvironments);
725
935
  onLoadEnvironmentsRef.current = onLoadEnvironments;
726
- React2.useEffect(() => {
936
+ React3.useEffect(() => {
727
937
  let cancelled = false;
728
938
  if (onLoadEnvironmentsRef.current) {
729
939
  setIsLoadingEnvironments(true);
@@ -749,10 +959,10 @@ function ProvisioningWizard({
749
959
  }, [environmentsProp]);
750
960
  const environments = envList;
751
961
  const effectiveDefault = dc?.environment ?? defaultEnvironment;
752
- const [selectedEnv, setSelectedEnv] = React2.useState(
962
+ const [selectedEnv, setSelectedEnv] = React3.useState(
753
963
  effectiveDefault ?? environments[0]?.id ?? ""
754
964
  );
755
- React2.useEffect(() => {
965
+ React3.useEffect(() => {
756
966
  if (envList.length === 0) return;
757
967
  if (effectiveDefault && envList.some((e) => e.id === effectiveDefault)) {
758
968
  setSelectedEnv(effectiveDefault);
@@ -763,38 +973,38 @@ function ProvisioningWizard({
763
973
  return envList[0]?.id ?? "";
764
974
  });
765
975
  }, [envList, effectiveDefault]);
766
- const [cpuCores, setCpuCores] = React2.useState(
976
+ const [cpuCores, setCpuCores] = React3.useState(
767
977
  snapSliderValue(dc?.cpuCores ?? 4, CPU_MIN, cpuMax, cpuStep)
768
978
  );
769
- const [ramGB, setRamGB] = React2.useState(
979
+ const [ramGB, setRamGB] = React3.useState(
770
980
  snapSliderValue(dc?.ramGB ?? 16, RAM_MIN, ramMax, ramStep)
771
981
  );
772
- const [storageGB, setStorageGB] = React2.useState(
982
+ const [storageGB, setStorageGB] = React3.useState(
773
983
  snapSliderValue(dc?.storageGB ?? 128, STORAGE_MIN, storageMax, storageStep)
774
984
  );
775
- React2.useEffect(() => {
985
+ React3.useEffect(() => {
776
986
  setCpuCores((prev) => snapSliderValue(prev, CPU_MIN, cpuMax, cpuStep));
777
987
  setRamGB((prev) => snapSliderValue(prev, RAM_MIN, ramMax, ramStep));
778
988
  setStorageGB(
779
989
  (prev) => snapSliderValue(prev, STORAGE_MIN, storageMax, storageStep)
780
990
  );
781
991
  }, [cpuMax, ramMax, storageMax, cpuStep, ramStep, storageStep]);
782
- const [name, setName] = React2.useState(dc?.name ?? "");
783
- const [gitUrl, setGitUrl] = React2.useState(dc?.gitUrl ?? "");
784
- const [envVars, setEnvVars] = React2.useState(dc?.envVars ?? [{ key: "", value: "" }]);
785
- const [driver, setDriver] = React2.useState(dc?.driver ?? "docker");
786
- const [bare, setBare] = React2.useState(dc?.bare ?? false);
787
- const [startupScriptIds, setStartupScriptIds] = React2.useState(
992
+ const [name, setName] = React3.useState(dc?.name ?? "");
993
+ const [gitUrl, setGitUrl] = React3.useState(dc?.gitUrl ?? "");
994
+ const [envVars, setEnvVars] = React3.useState(dc?.envVars ?? [{ key: "", value: "" }]);
995
+ const [driver, setDriver] = React3.useState(dc?.driver ?? "docker");
996
+ const [bare, setBare] = React3.useState(dc?.bare ?? false);
997
+ const [startupScriptIds, setStartupScriptIds] = React3.useState(
788
998
  dc?.startupScriptIds ?? []
789
999
  );
790
- const [availableScripts, setAvailableScripts] = React2.useState([]);
791
- const [activePreset, setActivePreset] = React2.useState(null);
792
- const [pricingView, setPricingView] = React2.useState("hourly");
793
- const [showAdvanced, setShowAdvanced] = React2.useState(false);
794
- const [loadError, setLoadError] = React2.useState(null);
795
- const onLoadStartupScriptsRef = React2.useRef(onLoadStartupScripts);
1000
+ const [availableScripts, setAvailableScripts] = React3.useState([]);
1001
+ const [activePreset, setActivePreset] = React3.useState(null);
1002
+ const [pricingView, setPricingView] = React3.useState("hourly");
1003
+ const [showAdvanced, setShowAdvanced] = React3.useState(false);
1004
+ const [loadError, setLoadError] = React3.useState(null);
1005
+ const onLoadStartupScriptsRef = React3.useRef(onLoadStartupScripts);
796
1006
  onLoadStartupScriptsRef.current = onLoadStartupScripts;
797
- React2.useEffect(() => {
1007
+ React3.useEffect(() => {
798
1008
  let cancelled = false;
799
1009
  if (onLoadStartupScriptsRef.current) {
800
1010
  onLoadStartupScriptsRef.current().then((scripts) => {
@@ -810,14 +1020,8 @@ function ProvisioningWizard({
810
1020
  cancelled = true;
811
1021
  };
812
1022
  }, []);
813
- const isMultistep = variant === "multistep";
814
- const stepLabels = sshAccess ? ["Environment", "Resources", "Access"] : ["Environment", "Resources"];
815
- const finalStep = stepLabels.length;
816
- const [currentStep, setCurrentStep] = React2.useState(
817
- skipToReview && dc && isMultistep ? finalStep : 1
818
- );
819
- const [isDeploying, setIsDeploying] = React2.useState(false);
820
- const [deployError, setDeployError] = React2.useState(null);
1023
+ const [isDeploying, setIsDeploying] = React3.useState(false);
1024
+ const [deployError, setDeployError] = React3.useState(null);
821
1025
  const handleDeploy = async () => {
822
1026
  if (!onSubmit) return;
823
1027
  setIsDeploying(true);
@@ -868,9 +1072,9 @@ function ProvisioningWizard({
868
1072
  unlockLabel: unlockLabel ?? "Pro"
869
1073
  };
870
1074
  });
871
- const didInitPresetFromDcRef = React2.useRef(false);
872
- const lastLimitsRef = React2.useRef(null);
873
- React2.useEffect(() => {
1075
+ const didInitPresetFromDcRef = React3.useRef(false);
1076
+ const lastLimitsRef = React3.useRef(null);
1077
+ React3.useEffect(() => {
874
1078
  const limitsUnchanged = lastLimitsRef.current !== null && lastLimitsRef.current.cpu === cpuMax && lastLimitsRef.current.ram === ramMax && lastLimitsRef.current.storage === storageMax;
875
1079
  if (limitsUnchanged) return;
876
1080
  lastLimitsRef.current = { cpu: cpuMax, ram: ramMax, storage: storageMax };
@@ -908,9 +1112,9 @@ function ProvisioningWizard({
908
1112
  const pricingSuffix = pricingView === "hourly" ? "/ hour" : "/ sec";
909
1113
  const rateSuffix = pricingView === "hourly" ? "/h" : "/s";
910
1114
  const fmtRate = (v) => pricingView === "hourly" ? v.toFixed(2) : formatPerSecondValue(v);
911
- return /* @__PURE__ */ jsxs3("div", { className: cn("max-w-6xl mx-auto flex flex-col", className), children: [
912
- /* @__PURE__ */ jsxs3("div", { className: "mb-4 flex items-center gap-3 shrink-0", children: [
913
- onBack && /* @__PURE__ */ jsx3(
1115
+ return /* @__PURE__ */ jsxs4("div", { className: cn("max-w-6xl mx-auto flex flex-col", className), children: [
1116
+ /* @__PURE__ */ jsxs4("div", { className: "mb-4 flex items-center gap-3 shrink-0", children: [
1117
+ onBack && /* @__PURE__ */ jsx4(
914
1118
  Button,
915
1119
  {
916
1120
  type: "button",
@@ -918,109 +1122,43 @@ function ProvisioningWizard({
918
1122
  size: "icon",
919
1123
  onClick: onBack,
920
1124
  className: "h-9 w-9 shrink-0",
921
- children: /* @__PURE__ */ jsx3(ArrowLeft, { className: "h-4 w-4" })
1125
+ children: /* @__PURE__ */ jsx4(ArrowLeft, { className: "h-4 w-4" })
922
1126
  }
923
1127
  ),
924
- /* @__PURE__ */ jsxs3("div", { children: [
925
- /* @__PURE__ */ jsx3("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: "Sandbox Provisioning" }),
926
- /* @__PURE__ */ jsx3("p", { className: "text-muted-foreground text-sm", children: "Select your stack, allocate resources, and deploy." })
1128
+ /* @__PURE__ */ jsxs4("div", { children: [
1129
+ /* @__PURE__ */ jsx4("h1", { className: "text-2xl font-semibold tracking-tight text-foreground", children: "Sandbox Provisioning" }),
1130
+ /* @__PURE__ */ jsx4("p", { className: "text-muted-foreground text-sm", children: "Select your stack, allocate resources, and deploy." })
927
1131
  ] })
928
1132
  ] }),
929
- /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-12 gap-5 flex-1 min-h-0", children: [
930
- /* @__PURE__ */ jsxs3("div", { className: "col-span-12 xl:col-span-8 flex flex-col min-h-0", children: [
931
- isMultistep && /* @__PURE__ */ jsx3("div", { className: "flex items-center gap-2 mb-4 rounded-lg border border-border bg-card px-4 py-2 shadow-sm mx-auto max-w-2xl justify-between shrink-0", children: stepLabels.map((label, index) => {
932
- const s = index + 1;
933
- return /* @__PURE__ */ jsxs3("div", { className: "flex items-center", children: [
934
- /* @__PURE__ */ jsx3(
935
- "div",
936
- {
937
- className: cn(
938
- "h-6 w-6 rounded-full flex items-center justify-center font-semibold text-xs shrink-0 transition-colors duration-200",
939
- currentStep >= s ? "bg-primary text-primary-foreground" : "bg-muted border border-border text-muted-foreground"
940
- ),
941
- children: currentStep > s ? /* @__PURE__ */ jsx3(Check, { className: "h-3 w-3" }) : s
942
- }
943
- ),
944
- /* @__PURE__ */ jsx3(
945
- "span",
946
- {
947
- className: cn(
948
- "ml-2 font-medium text-sm hidden sm:inline transition-colors duration-200",
949
- currentStep === s ? "text-foreground" : currentStep > s ? "text-primary" : "text-muted-foreground"
950
- ),
951
- children: label
952
- }
953
- ),
954
- s < finalStep && /* @__PURE__ */ jsx3(
955
- "div",
956
- {
957
- className: cn(
958
- "w-4 sm:w-8 h-px mx-2 sm:mx-3 transition-colors duration-300",
959
- currentStep > s ? "bg-primary" : "bg-border"
960
- )
961
- }
962
- )
963
- ] }, s);
964
- }) }),
965
- dc && isMultistep && /* @__PURE__ */ jsxs3("div", { className: "flex items-center justify-between rounded-lg border border-border bg-card px-4 py-2.5 shadow-sm shrink-0 mb-4", children: [
966
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 text-sm", children: [
967
- /* @__PURE__ */ jsx3(Info, { className: "h-4 w-4 text-primary shrink-0" }),
968
- /* @__PURE__ */ jsx3("span", { className: "text-muted-foreground", children: "Pre-configured from template." })
969
- ] }),
970
- /* @__PURE__ */ jsx3(
971
- Button,
972
- {
973
- type: "button",
974
- variant: "link",
975
- onClick: () => {
976
- setCurrentStep(1);
977
- setSelectedEnv(environments[0]?.id ?? "");
978
- setCpuCores(snapSliderValue(4, CPU_MIN, cpuMax, cpuStep));
979
- setRamGB(snapSliderValue(16, RAM_MIN, ramMax, ramStep));
980
- setStorageGB(
981
- snapSliderValue(128, STORAGE_MIN, storageMax, storageStep)
982
- );
983
- setName("");
984
- setGitUrl("");
985
- setEnvVars([{ key: "", value: "" }]);
986
- setDriver("docker");
987
- setBare(false);
988
- setStartupScriptIds([]);
989
- setActivePreset(null);
990
- setPricingView("hourly");
991
- },
992
- className: "h-auto p-0 text-xs",
993
- children: "Start from scratch"
994
- }
995
- )
996
- ] }),
997
- loadError && /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-3 flex items-center gap-2 shrink-0 mb-4", children: [
998
- /* @__PURE__ */ jsx3(Info, { className: "h-4 w-4 text-destructive shrink-0" }),
999
- /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium text-destructive", children: loadError })
1133
+ /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-12 gap-5 flex-1 min-h-0", children: [
1134
+ /* @__PURE__ */ jsxs4("div", { className: "col-span-12 xl:col-span-8 flex flex-col min-h-0", children: [
1135
+ loadError && /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-3 flex items-center gap-2 shrink-0 mb-4", children: [
1136
+ /* @__PURE__ */ jsx4(Info, { className: "h-4 w-4 text-destructive shrink-0" }),
1137
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-medium text-destructive", children: loadError })
1000
1138
  ] }),
1001
- /* @__PURE__ */ jsxs3("div", { className: "flex-1 overflow-y-auto min-h-0 space-y-4", children: [
1002
- (!isMultistep || currentStep === 1) && /* @__PURE__ */ jsx3(React2.Fragment, { children: /* @__PURE__ */ jsxs3("section", { className: SECTION_CARD_CLASS, children: [
1003
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 mb-4", children: [
1004
- /* @__PURE__ */ jsx3(Layers, { className: "h-4 w-4 text-primary shrink-0" }),
1005
- /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold uppercase tracking-[0.06em] text-muted-foreground", children: "Environment Selection" })
1139
+ /* @__PURE__ */ jsxs4("div", { className: "flex-1 overflow-y-auto min-h-0 space-y-4", children: [
1140
+ /* @__PURE__ */ jsxs4("section", { className: SECTION_CARD_CLASS, children: [
1141
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 mb-4", children: [
1142
+ /* @__PURE__ */ jsx4(Layers, { className: "h-4 w-4 text-primary shrink-0" }),
1143
+ /* @__PURE__ */ jsx4("h2", { className: "text-sm font-semibold uppercase tracking-[0.06em] text-muted-foreground", children: "Environment Selection" })
1006
1144
  ] }),
1007
- /* @__PURE__ */ jsx3("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-3", children: isLoadingEnvironments && environments.length === 0 ? Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs3(
1145
+ /* @__PURE__ */ jsx4("div", { className: "grid grid-cols-1 md:grid-cols-3 gap-3", children: isLoadingEnvironments && environments.length === 0 ? Array.from({ length: 3 }).map((_, i) => /* @__PURE__ */ jsxs4(
1008
1146
  "div",
1009
1147
  {
1010
1148
  className: "p-3.5 rounded-lg border border-border bg-card/50 animate-pulse",
1011
1149
  "aria-hidden": "true",
1012
1150
  children: [
1013
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-start mb-2.5", children: [
1014
- /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 rounded-full bg-muted/60 border border-border" }),
1015
- /* @__PURE__ */ jsx3("div", { className: "w-4 h-4 rounded-full border-2 border-border" })
1151
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-start mb-2.5", children: [
1152
+ /* @__PURE__ */ jsx4("div", { className: "w-10 h-10 rounded-full bg-muted/60 border border-border" }),
1153
+ /* @__PURE__ */ jsx4("div", { className: "w-4 h-4 rounded-full border-2 border-border" })
1016
1154
  ] }),
1017
- /* @__PURE__ */ jsx3("div", { className: "h-3 w-1/3 rounded bg-muted/60 mb-2" }),
1018
- /* @__PURE__ */ jsx3("div", { className: "h-2.5 w-5/6 rounded bg-muted/50 mb-1.5" }),
1019
- /* @__PURE__ */ jsx3("div", { className: "h-2.5 w-2/3 rounded bg-muted/50" })
1155
+ /* @__PURE__ */ jsx4("div", { className: "h-3 w-1/3 rounded bg-muted/60 mb-2" }),
1156
+ /* @__PURE__ */ jsx4("div", { className: "h-2.5 w-5/6 rounded bg-muted/50 mb-1.5" }),
1157
+ /* @__PURE__ */ jsx4("div", { className: "h-2.5 w-2/3 rounded bg-muted/50" })
1020
1158
  ]
1021
1159
  },
1022
1160
  `env-skeleton-${i}`
1023
- )) : environments.map((env) => /* @__PURE__ */ jsxs3(
1161
+ )) : environments.map((env) => /* @__PURE__ */ jsxs4(
1024
1162
  "button",
1025
1163
  {
1026
1164
  type: "button",
@@ -1030,36 +1168,36 @@ function ProvisioningWizard({
1030
1168
  selectedEnv === env.id ? "bg-primary/5 border-primary ring-1 ring-primary/20" : "bg-card border-border hover:border-primary/30 active:scale-[0.99]"
1031
1169
  ),
1032
1170
  children: [
1033
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-start mb-2.5", children: [
1034
- /* @__PURE__ */ jsx3("div", { className: "w-10 h-10 rounded-full flex items-center justify-center bg-muted/50 border border-border", children: env.icon }),
1035
- /* @__PURE__ */ jsx3(
1171
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-start mb-2.5", children: [
1172
+ /* @__PURE__ */ jsx4("div", { className: "w-10 h-10 rounded-full flex items-center justify-center bg-muted/50 border border-border", children: env.icon }),
1173
+ /* @__PURE__ */ jsx4(
1036
1174
  "div",
1037
1175
  {
1038
1176
  className: cn(
1039
1177
  "w-4 h-4 rounded-full border-2 flex items-center justify-center transition-colors duration-200",
1040
1178
  selectedEnv === env.id ? "border-primary bg-primary" : "border-border group-hover:border-primary/40"
1041
1179
  ),
1042
- children: selectedEnv === env.id && /* @__PURE__ */ jsx3(Check, { className: "h-2.5 w-2.5 text-primary-foreground" })
1180
+ children: selectedEnv === env.id && /* @__PURE__ */ jsx4(Check, { className: "h-2.5 w-2.5 text-primary-foreground" })
1043
1181
  }
1044
1182
  )
1045
1183
  ] }),
1046
- /* @__PURE__ */ jsx3("h3", { className: "font-semibold text-sm mb-0.5 text-foreground", children: env.name }),
1047
- /* @__PURE__ */ jsx3("p", { className: "text-xs text-muted-foreground leading-relaxed", children: env.description })
1184
+ /* @__PURE__ */ jsx4("h3", { className: "font-semibold text-sm mb-0.5 text-foreground", children: env.name }),
1185
+ /* @__PURE__ */ jsx4("p", { className: "text-xs text-muted-foreground leading-relaxed", children: env.description })
1048
1186
  ]
1049
1187
  },
1050
1188
  env.id
1051
1189
  )) })
1052
- ] }) }),
1053
- (!isMultistep || currentStep === 2) && /* @__PURE__ */ jsx3(React2.Fragment, { children: /* @__PURE__ */ jsxs3("section", { className: SECTION_CARD_CLASS, children: [
1054
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 mb-4", children: [
1055
- /* @__PURE__ */ jsx3(Cpu, { className: "h-4 w-4 text-primary shrink-0" }),
1056
- /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold uppercase tracking-[0.06em] text-muted-foreground", children: "Resource Allocation" })
1190
+ ] }),
1191
+ /* @__PURE__ */ jsxs4("section", { className: SECTION_CARD_CLASS, children: [
1192
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 mb-4", children: [
1193
+ /* @__PURE__ */ jsx4(Cpu, { className: "h-4 w-4 text-primary shrink-0" }),
1194
+ /* @__PURE__ */ jsx4("h2", { className: "text-sm font-semibold uppercase tracking-[0.06em] text-muted-foreground", children: "Resource Allocation" })
1057
1195
  ] }),
1058
- /* @__PURE__ */ jsxs3("div", { className: "mb-4", children: [
1059
- /* @__PURE__ */ jsx3("label", { className: cn(FIELD_LABEL_CLASS, "mb-2"), children: "Compute Presets" }),
1060
- /* @__PURE__ */ jsx3("div", { className: "grid grid-cols-3 gap-2", children: presets.map((p) => {
1196
+ /* @__PURE__ */ jsxs4("div", { className: "mb-4", children: [
1197
+ /* @__PURE__ */ jsx4("label", { className: cn(FIELD_LABEL_CLASS, "mb-2"), children: "Compute Presets" }),
1198
+ /* @__PURE__ */ jsx4("div", { className: "grid grid-cols-3 gap-2", children: presets.map((p) => {
1061
1199
  const active = activePreset === p.name && !p.locked;
1062
- return /* @__PURE__ */ jsxs3(
1200
+ return /* @__PURE__ */ jsxs4(
1063
1201
  "button",
1064
1202
  {
1065
1203
  type: "button",
@@ -1070,8 +1208,8 @@ function ProvisioningWizard({
1070
1208
  active ? "bg-primary/5 border-primary ring-1 ring-primary/20" : p.locked ? "bg-muted/30 border-border opacity-60 cursor-not-allowed" : "bg-card border-border hover:border-primary/30 active:scale-[0.99]"
1071
1209
  ),
1072
1210
  children: [
1073
- p.locked && /* @__PURE__ */ jsx3("div", { className: "absolute -top-1.5 -right-1.5 bg-primary text-primary-foreground text-[9px] font-semibold px-1.5 py-0.5 rounded-full uppercase tracking-wider", children: p.unlockLabel }),
1074
- /* @__PURE__ */ jsx3(
1211
+ p.locked && /* @__PURE__ */ jsx4("div", { className: "absolute -top-1.5 -right-1.5 bg-primary text-primary-foreground text-[9px] font-semibold px-1.5 py-0.5 rounded-full uppercase tracking-wider", children: p.unlockLabel }),
1212
+ /* @__PURE__ */ jsx4(
1075
1213
  "div",
1076
1214
  {
1077
1215
  className: cn(
@@ -1081,7 +1219,7 @@ function ProvisioningWizard({
1081
1219
  children: p.name
1082
1220
  }
1083
1221
  ),
1084
- /* @__PURE__ */ jsxs3("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: [
1222
+ /* @__PURE__ */ jsxs4("div", { className: "text-xs text-muted-foreground mt-0.5 font-mono", children: [
1085
1223
  p.cpu,
1086
1224
  " vCPU",
1087
1225
  p.cpu === 1 ? "" : "s",
@@ -1098,7 +1236,7 @@ function ProvisioningWizard({
1098
1236
  );
1099
1237
  }) })
1100
1238
  ] }),
1101
- /* @__PURE__ */ jsx3("div", { className: "space-y-4", children: [
1239
+ /* @__PURE__ */ jsx4("div", { className: "space-y-4", children: [
1102
1240
  {
1103
1241
  label: "Compute Cores (CPU)",
1104
1242
  value: cpuCores,
@@ -1129,12 +1267,12 @@ function ProvisioningWizard({
1129
1267
  ].map(
1130
1268
  ({ label, value, setter, min, max, step: s, unit }) => {
1131
1269
  const displayUnit = unit === "vCPU" ? `${value} vCPU${value === 1 ? "" : "s"}` : `${value}${unit}`;
1132
- return /* @__PURE__ */ jsxs3("div", { children: [
1133
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-end pb-1 mb-1.5", children: [
1134
- /* @__PURE__ */ jsx3("label", { className: FIELD_LABEL_CLASS, children: label }),
1135
- /* @__PURE__ */ jsx3("span", { className: "text-sm font-semibold text-foreground tabular-nums", children: displayUnit })
1270
+ return /* @__PURE__ */ jsxs4("div", { children: [
1271
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-end pb-1 mb-1.5", children: [
1272
+ /* @__PURE__ */ jsx4("label", { className: FIELD_LABEL_CLASS, children: label }),
1273
+ /* @__PURE__ */ jsx4("span", { className: "text-sm font-semibold text-foreground tabular-nums", children: displayUnit })
1136
1274
  ] }),
1137
- /* @__PURE__ */ jsx3(
1275
+ /* @__PURE__ */ jsx4(
1138
1276
  "input",
1139
1277
  {
1140
1278
  type: "range",
@@ -1149,12 +1287,12 @@ function ProvisioningWizard({
1149
1287
  className: "w-full h-1.5 rounded-full appearance-none cursor-pointer accent-primary [&::-webkit-slider-runnable-track]:bg-border [&::-webkit-slider-runnable-track]:rounded-full [&::-webkit-slider-runnable-track]:h-1.5 [&::-moz-range-track]:bg-border [&::-moz-range-track]:rounded-full [&::-moz-range-track]:h-1.5 [&::-webkit-slider-thumb]:bg-primary [&::-webkit-slider-thumb]:rounded-full [&::-webkit-slider-thumb]:h-4 [&::-webkit-slider-thumb]:w-4 [&::-webkit-slider-thumb]:appearance-none [&::-webkit-slider-thumb]:-mt-[5px] [&::-webkit-slider-thumb]:shadow-sm [&::-webkit-slider-thumb]:border-2 [&::-webkit-slider-thumb]:border-primary-foreground"
1150
1288
  }
1151
1289
  ),
1152
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground/60 mt-1", children: [
1153
- /* @__PURE__ */ jsxs3("span", { children: [
1290
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between text-[10px] font-mono text-muted-foreground/60 mt-1", children: [
1291
+ /* @__PURE__ */ jsxs4("span", { children: [
1154
1292
  min,
1155
1293
  unit === "vCPU" ? min === 1 ? " vCPU" : " vCPUs" : unit
1156
1294
  ] }),
1157
- /* @__PURE__ */ jsxs3("span", { children: [
1295
+ /* @__PURE__ */ jsxs4("span", { children: [
1158
1296
  max,
1159
1297
  unit === "vCPU" ? max === 1 ? " vCPU" : " vCPUs" : unit
1160
1298
  ] })
@@ -1162,25 +1300,25 @@ function ProvisioningWizard({
1162
1300
  ] }, label);
1163
1301
  }
1164
1302
  ) })
1165
- ] }) }),
1166
- (!isMultistep || currentStep === 2) && /* @__PURE__ */ jsx3(React2.Fragment, { children: /* @__PURE__ */ jsx3("section", { className: SECTION_CARD_CLASS, children: /* @__PURE__ */ jsxs3("div", { children: [
1167
- /* @__PURE__ */ jsxs3(
1303
+ ] }),
1304
+ /* @__PURE__ */ jsx4("section", { className: SECTION_CARD_CLASS, children: /* @__PURE__ */ jsxs4("div", { children: [
1305
+ /* @__PURE__ */ jsxs4(
1168
1306
  "button",
1169
1307
  {
1170
1308
  type: "button",
1171
1309
  onClick: () => setShowAdvanced(!showAdvanced),
1172
1310
  className: "flex items-center gap-2 text-muted-foreground hover:text-foreground transition-colors text-sm font-medium focus:outline-none",
1173
1311
  children: [
1174
- /* @__PURE__ */ jsx3(Settings, { className: "w-4 h-4" }),
1312
+ /* @__PURE__ */ jsx4(Settings, { className: "w-4 h-4" }),
1175
1313
  showAdvanced ? "Hide Advanced Options" : "Show Advanced Options"
1176
1314
  ]
1177
1315
  }
1178
1316
  ),
1179
- showAdvanced && /* @__PURE__ */ jsxs3("div", { className: "mt-4 space-y-4", children: [
1180
- /* @__PURE__ */ jsxs3("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1181
- /* @__PURE__ */ jsxs3("div", { children: [
1182
- /* @__PURE__ */ jsx3("label", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Workspace Name" }),
1183
- /* @__PURE__ */ jsx3(
1317
+ showAdvanced && /* @__PURE__ */ jsxs4("div", { className: "mt-4 space-y-4", children: [
1318
+ /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
1319
+ /* @__PURE__ */ jsxs4("div", { children: [
1320
+ /* @__PURE__ */ jsx4("label", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Workspace Name" }),
1321
+ /* @__PURE__ */ jsx4(
1184
1322
  Input,
1185
1323
  {
1186
1324
  type: "text",
@@ -1192,9 +1330,9 @@ function ProvisioningWizard({
1192
1330
  }
1193
1331
  )
1194
1332
  ] }),
1195
- /* @__PURE__ */ jsxs3("div", { children: [
1196
- /* @__PURE__ */ jsx3("label", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Virtualization Driver" }),
1197
- /* @__PURE__ */ jsxs3(
1333
+ /* @__PURE__ */ jsxs4("div", { children: [
1334
+ /* @__PURE__ */ jsx4("label", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Virtualization Driver" }),
1335
+ /* @__PURE__ */ jsxs4(
1198
1336
  "select",
1199
1337
  {
1200
1338
  value: driver,
@@ -1206,8 +1344,8 @@ function ProvisioningWizard({
1206
1344
  },
1207
1345
  className: "w-full bg-card border border-border rounded-lg h-9 px-3 text-sm text-foreground focus:outline-none focus:ring-2 focus:ring-ring focus:border-transparent appearance-none",
1208
1346
  children: [
1209
- /* @__PURE__ */ jsx3("option", { value: "docker", className: "bg-gray-900", children: "Docker container (Default)" }),
1210
- /* @__PURE__ */ jsx3(
1347
+ /* @__PURE__ */ jsx4("option", { value: "docker", className: "bg-gray-900", children: "Docker container (Default)" }),
1348
+ /* @__PURE__ */ jsx4(
1211
1349
  "option",
1212
1350
  {
1213
1351
  value: "firecracker",
@@ -1215,15 +1353,15 @@ function ProvisioningWizard({
1215
1353
  children: "Firecracker microVM (Secure)"
1216
1354
  }
1217
1355
  ),
1218
- /* @__PURE__ */ jsx3("option", { value: "tangle", className: "bg-gray-900", children: "Tangle Distributed Node" })
1356
+ /* @__PURE__ */ jsx4("option", { value: "tangle", className: "bg-gray-900", children: "Tangle Distributed Node" })
1219
1357
  ]
1220
1358
  }
1221
1359
  )
1222
1360
  ] })
1223
1361
  ] }),
1224
- /* @__PURE__ */ jsxs3("div", { children: [
1225
- /* @__PURE__ */ jsx3("label", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Git Repository URL" }),
1226
- /* @__PURE__ */ jsx3(
1362
+ /* @__PURE__ */ jsxs4("div", { children: [
1363
+ /* @__PURE__ */ jsx4("label", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Git Repository URL" }),
1364
+ /* @__PURE__ */ jsx4(
1227
1365
  Input,
1228
1366
  {
1229
1367
  type: "text",
@@ -1234,10 +1372,10 @@ function ProvisioningWizard({
1234
1372
  }
1235
1373
  )
1236
1374
  ] }),
1237
- /* @__PURE__ */ jsxs3("div", { children: [
1238
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center mb-1.5", children: [
1239
- /* @__PURE__ */ jsx3("label", { className: FIELD_LABEL_CLASS, children: "Environment Variables" }),
1240
- /* @__PURE__ */ jsxs3(
1375
+ /* @__PURE__ */ jsxs4("div", { children: [
1376
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center mb-1.5", children: [
1377
+ /* @__PURE__ */ jsx4("label", { className: FIELD_LABEL_CLASS, children: "Environment Variables" }),
1378
+ /* @__PURE__ */ jsxs4(
1241
1379
  "button",
1242
1380
  {
1243
1381
  type: "button",
@@ -1247,15 +1385,15 @@ function ProvisioningWizard({
1247
1385
  ]),
1248
1386
  className: "flex items-center gap-1 text-xs text-primary hover:text-primary/70 transition-colors font-medium",
1249
1387
  children: [
1250
- /* @__PURE__ */ jsx3(Plus, { className: "h-3 w-3" }),
1388
+ /* @__PURE__ */ jsx4(Plus, { className: "h-3 w-3" }),
1251
1389
  " Add Var"
1252
1390
  ]
1253
1391
  }
1254
1392
  )
1255
1393
  ] }),
1256
- /* @__PURE__ */ jsxs3("div", { className: "space-y-2", children: [
1257
- envVars.map((env, i) => /* @__PURE__ */ jsxs3("div", { className: "flex gap-2", children: [
1258
- /* @__PURE__ */ jsx3(
1394
+ /* @__PURE__ */ jsxs4("div", { className: "space-y-2", children: [
1395
+ envVars.map((env, i) => /* @__PURE__ */ jsxs4("div", { className: "flex gap-2", children: [
1396
+ /* @__PURE__ */ jsx4(
1259
1397
  Input,
1260
1398
  {
1261
1399
  type: "text",
@@ -1269,7 +1407,7 @@ function ProvisioningWizard({
1269
1407
  placeholder: "API_KEY"
1270
1408
  }
1271
1409
  ),
1272
- /* @__PURE__ */ jsx3(
1410
+ /* @__PURE__ */ jsx4(
1273
1411
  Input,
1274
1412
  {
1275
1413
  type: "password",
@@ -1283,7 +1421,7 @@ function ProvisioningWizard({
1283
1421
  placeholder: "sk-xxxxxxxxxxx"
1284
1422
  }
1285
1423
  ),
1286
- /* @__PURE__ */ jsx3(
1424
+ /* @__PURE__ */ jsx4(
1287
1425
  Button,
1288
1426
  {
1289
1427
  type: "button",
@@ -1293,25 +1431,25 @@ function ProvisioningWizard({
1293
1431
  envVars.filter((_, idx) => idx !== i)
1294
1432
  ),
1295
1433
  className: "h-9 w-9 shrink-0 text-destructive hover:bg-destructive/10 hover:border-destructive/30",
1296
- children: /* @__PURE__ */ jsx3(Trash2, { className: "h-4 w-4" })
1434
+ children: /* @__PURE__ */ jsx4(Trash2, { className: "h-4 w-4" })
1297
1435
  }
1298
1436
  )
1299
1437
  ] }, i)),
1300
- envVars.length === 0 && /* @__PURE__ */ jsx3("div", { className: "text-center p-3 border border-dashed border-border rounded-lg text-muted-foreground/60 text-xs italic", children: "No environment variables set" })
1438
+ envVars.length === 0 && /* @__PURE__ */ jsx4("div", { className: "text-center p-3 border border-dashed border-border rounded-lg text-muted-foreground/60 text-xs italic", children: "No environment variables set" })
1301
1439
  ] })
1302
1440
  ] }),
1303
- availableScripts.length > 0 && /* @__PURE__ */ jsxs3("div", { children: [
1304
- /* @__PURE__ */ jsx3("div", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Startup Scripts" }),
1305
- /* @__PURE__ */ jsx3("div", { className: "space-y-2", children: availableScripts.filter((s) => s.enabled).map((script) => {
1441
+ availableScripts.length > 0 && /* @__PURE__ */ jsxs4("div", { children: [
1442
+ /* @__PURE__ */ jsx4("div", { className: cn(FIELD_LABEL_CLASS, "mb-1.5"), children: "Startup Scripts" }),
1443
+ /* @__PURE__ */ jsx4("div", { className: "space-y-2", children: availableScripts.filter((s) => s.enabled).map((script) => {
1306
1444
  const selected = startupScriptIds.includes(
1307
1445
  script.id
1308
1446
  );
1309
- return /* @__PURE__ */ jsxs3(
1447
+ return /* @__PURE__ */ jsxs4(
1310
1448
  "label",
1311
1449
  {
1312
1450
  className: "flex items-start gap-3 cursor-pointer group rounded-lg border border-border p-3 transition-colors hover:border-primary/30",
1313
1451
  children: [
1314
- /* @__PURE__ */ jsx3(
1452
+ /* @__PURE__ */ jsx4(
1315
1453
  "input",
1316
1454
  {
1317
1455
  type: "checkbox",
@@ -1324,15 +1462,15 @@ function ProvisioningWizard({
1324
1462
  className: "mt-0.5 h-4 w-4 rounded border-border text-primary focus:ring-primary/30"
1325
1463
  }
1326
1464
  ),
1327
- /* @__PURE__ */ jsxs3("div", { className: "flex-1 min-w-0", children: [
1328
- /* @__PURE__ */ jsx3("div", { className: "text-sm font-medium text-foreground group-hover:text-primary transition-colors", children: script.name }),
1329
- script.description && /* @__PURE__ */ jsx3("div", { className: "text-xs text-muted-foreground mt-0.5", children: script.description }),
1330
- script.injectSecrets.length > 0 && /* @__PURE__ */ jsx3("div", { className: "flex flex-wrap gap-1 mt-1.5", children: script.injectSecrets.map((s) => /* @__PURE__ */ jsxs3(
1465
+ /* @__PURE__ */ jsxs4("div", { className: "flex-1 min-w-0", children: [
1466
+ /* @__PURE__ */ jsx4("div", { className: "text-sm font-medium text-foreground group-hover:text-primary transition-colors", children: script.name }),
1467
+ script.description && /* @__PURE__ */ jsx4("div", { className: "text-xs text-muted-foreground mt-0.5", children: script.description }),
1468
+ script.injectSecrets.length > 0 && /* @__PURE__ */ jsx4("div", { className: "flex flex-wrap gap-1 mt-1.5", children: script.injectSecrets.map((s) => /* @__PURE__ */ jsxs4(
1331
1469
  "span",
1332
1470
  {
1333
1471
  className: "inline-flex items-center gap-0.5 rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground",
1334
1472
  children: [
1335
- /* @__PURE__ */ jsxs3(
1473
+ /* @__PURE__ */ jsxs4(
1336
1474
  "svg",
1337
1475
  {
1338
1476
  className: "h-2.5 w-2.5",
@@ -1341,7 +1479,7 @@ function ProvisioningWizard({
1341
1479
  stroke: "currentColor",
1342
1480
  strokeWidth: "2",
1343
1481
  children: [
1344
- /* @__PURE__ */ jsx3(
1482
+ /* @__PURE__ */ jsx4(
1345
1483
  "rect",
1346
1484
  {
1347
1485
  x: "3",
@@ -1352,7 +1490,7 @@ function ProvisioningWizard({
1352
1490
  ry: "2"
1353
1491
  }
1354
1492
  ),
1355
- /* @__PURE__ */ jsx3("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
1493
+ /* @__PURE__ */ jsx4("path", { d: "M7 11V7a5 5 0 0 1 10 0v4" })
1356
1494
  ]
1357
1495
  }
1358
1496
  ),
@@ -1368,9 +1506,9 @@ function ProvisioningWizard({
1368
1506
  );
1369
1507
  }) })
1370
1508
  ] }),
1371
- /* @__PURE__ */ jsxs3("div", { className: "pt-3 border-t border-border flex items-start justify-between gap-3", children: [
1372
- /* @__PURE__ */ jsxs3("div", { children: [
1373
- /* @__PURE__ */ jsx3(
1509
+ /* @__PURE__ */ jsxs4("div", { className: "pt-3 border-t border-border flex items-start justify-between gap-3", children: [
1510
+ /* @__PURE__ */ jsxs4("div", { children: [
1511
+ /* @__PURE__ */ jsx4(
1374
1512
  "label",
1375
1513
  {
1376
1514
  htmlFor: "wizard-bare-mode",
@@ -1378,9 +1516,9 @@ function ProvisioningWizard({
1378
1516
  children: "Bare Mode"
1379
1517
  }
1380
1518
  ),
1381
- /* @__PURE__ */ jsx3("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Start as a raw container without an embedded AI Agent backend." })
1519
+ /* @__PURE__ */ jsx4("p", { className: "text-xs text-muted-foreground mt-0.5", children: "Start as a raw container without an embedded AI Agent backend." })
1382
1520
  ] }),
1383
- /* @__PURE__ */ jsx3(
1521
+ /* @__PURE__ */ jsx4(
1384
1522
  Switch,
1385
1523
  {
1386
1524
  id: "wizard-bare-mode",
@@ -1391,28 +1529,28 @@ function ProvisioningWizard({
1391
1529
  )
1392
1530
  ] })
1393
1531
  ] })
1394
- ] }) }) }),
1395
- sshAccess && (!isMultistep || currentStep === 3) && /* @__PURE__ */ jsx3(React2.Fragment, { children: /* @__PURE__ */ jsxs3("section", { className: SECTION_CARD_CLASS, children: [
1396
- /* @__PURE__ */ jsxs3("div", { className: "flex items-center gap-2 mb-4", children: [
1397
- /* @__PURE__ */ jsx3(Settings, { className: "h-4 w-4 text-primary shrink-0" }),
1398
- /* @__PURE__ */ jsx3("h2", { className: "text-sm font-semibold uppercase tracking-[0.06em] text-muted-foreground", children: "Access Configuration" })
1532
+ ] }) }),
1533
+ sshAccess && /* @__PURE__ */ jsxs4("section", { className: SECTION_CARD_CLASS, children: [
1534
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-center gap-2 mb-4", children: [
1535
+ /* @__PURE__ */ jsx4(Settings, { className: "h-4 w-4 text-primary shrink-0" }),
1536
+ /* @__PURE__ */ jsx4("h2", { className: "text-sm font-semibold uppercase tracking-[0.06em] text-muted-foreground", children: "Access Configuration" })
1399
1537
  ] }),
1400
- /* @__PURE__ */ jsx3(SshAccessStep, { config: sshAccess })
1401
- ] }) })
1538
+ /* @__PURE__ */ jsx4(SshAccessStep, { config: sshAccess })
1539
+ ] })
1402
1540
  ] })
1403
1541
  ] }),
1404
- /* @__PURE__ */ jsxs3("div", { className: "col-span-12 xl:col-span-4 sticky top-4 space-y-4", children: [
1405
- /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-border bg-card p-5 shadow-sm", children: [
1406
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between items-center mb-3", children: [
1407
- /* @__PURE__ */ jsx3("span", { className: FIELD_LABEL_CLASS, children: "Run Cost" }),
1408
- /* @__PURE__ */ jsxs3(
1542
+ /* @__PURE__ */ jsxs4("div", { className: "col-span-12 xl:col-span-4 sticky top-4 space-y-4", children: [
1543
+ /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-border bg-card p-5 shadow-sm", children: [
1544
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between items-center mb-3", children: [
1545
+ /* @__PURE__ */ jsx4("span", { className: FIELD_LABEL_CLASS, children: "Run Cost" }),
1546
+ /* @__PURE__ */ jsxs4(
1409
1547
  "div",
1410
1548
  {
1411
1549
  role: "group",
1412
1550
  "aria-label": "Pricing view",
1413
1551
  className: "inline-flex items-center rounded-md border border-border bg-muted/50 p-0.5",
1414
1552
  children: [
1415
- /* @__PURE__ */ jsx3(
1553
+ /* @__PURE__ */ jsx4(
1416
1554
  "button",
1417
1555
  {
1418
1556
  type: "button",
@@ -1425,7 +1563,7 @@ function ProvisioningWizard({
1425
1563
  children: "Per Hour"
1426
1564
  }
1427
1565
  ),
1428
- /* @__PURE__ */ jsx3(
1566
+ /* @__PURE__ */ jsx4(
1429
1567
  "button",
1430
1568
  {
1431
1569
  type: "button",
@@ -1442,8 +1580,8 @@ function ProvisioningWizard({
1442
1580
  }
1443
1581
  )
1444
1582
  ] }),
1445
- /* @__PURE__ */ jsxs3("div", { className: "flex items-baseline gap-2 mb-4", children: [
1446
- /* @__PURE__ */ jsxs3(
1583
+ /* @__PURE__ */ jsxs4("div", { className: "flex items-baseline gap-2 mb-4", children: [
1584
+ /* @__PURE__ */ jsxs4(
1447
1585
  "span",
1448
1586
  {
1449
1587
  className: cn(
@@ -1457,36 +1595,36 @@ function ProvisioningWizard({
1457
1595
  },
1458
1596
  pricingView
1459
1597
  ),
1460
- /* @__PURE__ */ jsx3("span", { className: "text-muted-foreground text-sm", children: pricingSuffix })
1598
+ /* @__PURE__ */ jsx4("span", { className: "text-muted-foreground text-sm", children: pricingSuffix })
1461
1599
  ] }),
1462
- /* @__PURE__ */ jsxs3("div", { className: "space-y-2 rounded-md border border-border bg-muted/30 p-3", children: [
1463
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between text-xs font-mono tracking-wide text-muted-foreground", children: [
1464
- /* @__PURE__ */ jsx3("span", { children: "COMPUTE" }),
1465
- /* @__PURE__ */ jsxs3("span", { className: "text-foreground", children: [
1600
+ /* @__PURE__ */ jsxs4("div", { className: "space-y-2 rounded-md border border-border bg-muted/30 p-3", children: [
1601
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between text-xs font-mono tracking-wide text-muted-foreground", children: [
1602
+ /* @__PURE__ */ jsx4("span", { children: "COMPUTE" }),
1603
+ /* @__PURE__ */ jsxs4("span", { className: "text-foreground", children: [
1466
1604
  "$",
1467
1605
  fmtRate(hourlyCostBreakdown.compute),
1468
1606
  rateSuffix
1469
1607
  ] })
1470
1608
  ] }),
1471
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between text-xs font-mono tracking-wide text-muted-foreground", children: [
1472
- /* @__PURE__ */ jsx3("span", { children: "MEMORY" }),
1473
- /* @__PURE__ */ jsxs3("span", { className: "text-foreground/80", children: [
1609
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between text-xs font-mono tracking-wide text-muted-foreground", children: [
1610
+ /* @__PURE__ */ jsx4("span", { children: "MEMORY" }),
1611
+ /* @__PURE__ */ jsxs4("span", { className: "text-foreground/80", children: [
1474
1612
  "$",
1475
1613
  fmtRate(hourlyCostBreakdown.memory),
1476
1614
  rateSuffix
1477
1615
  ] })
1478
1616
  ] }),
1479
- /* @__PURE__ */ jsxs3("div", { className: "flex justify-between text-xs font-mono tracking-wide text-muted-foreground", children: [
1480
- /* @__PURE__ */ jsx3("span", { children: "STORAGE" }),
1481
- /* @__PURE__ */ jsxs3("span", { className: "text-foreground/80", children: [
1617
+ /* @__PURE__ */ jsxs4("div", { className: "flex justify-between text-xs font-mono tracking-wide text-muted-foreground", children: [
1618
+ /* @__PURE__ */ jsx4("span", { children: "STORAGE" }),
1619
+ /* @__PURE__ */ jsxs4("span", { className: "text-foreground/80", children: [
1482
1620
  "$",
1483
1621
  fmtRate(hourlyCostBreakdown.storage),
1484
1622
  rateSuffix
1485
1623
  ] })
1486
1624
  ] }),
1487
- hourlyCostBreakdown.floorApplies && /* @__PURE__ */ jsxs3("div", { className: "flex justify-between text-xs font-mono tracking-wide text-primary border-t border-border pt-2", children: [
1488
- /* @__PURE__ */ jsx3("span", { children: "MIN CHARGE" }),
1489
- /* @__PURE__ */ jsxs3("span", { children: [
1625
+ hourlyCostBreakdown.floorApplies && /* @__PURE__ */ jsxs4("div", { className: "flex justify-between text-xs font-mono tracking-wide text-primary border-t border-border pt-2", children: [
1626
+ /* @__PURE__ */ jsx4("span", { children: "MIN CHARGE" }),
1627
+ /* @__PURE__ */ jsxs4("span", { children: [
1490
1628
  "$",
1491
1629
  fmtRate(
1492
1630
  hourlyCostBreakdown.floor - hourlyCostBreakdown.lineSum
@@ -1496,54 +1634,19 @@ function ProvisioningWizard({
1496
1634
  ] })
1497
1635
  ] })
1498
1636
  ] }),
1499
- deployError && /* @__PURE__ */ jsxs3("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-3 flex items-center gap-2", children: [
1500
- /* @__PURE__ */ jsx3(Info, { className: "h-4 w-4 text-destructive shrink-0" }),
1501
- /* @__PURE__ */ jsx3("p", { className: "text-sm font-medium text-destructive", children: deployError })
1637
+ deployError && /* @__PURE__ */ jsxs4("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-3 flex items-center gap-2", children: [
1638
+ /* @__PURE__ */ jsx4(Info, { className: "h-4 w-4 text-destructive shrink-0" }),
1639
+ /* @__PURE__ */ jsx4("p", { className: "text-sm font-medium text-destructive", children: deployError })
1502
1640
  ] }),
1503
- /* @__PURE__ */ jsx3("div", { className: "space-y-2", children: isMultistep ? /* @__PURE__ */ jsxs3(Fragment3, { children: [
1504
- currentStep < finalStep ? /* @__PURE__ */ jsxs3(
1505
- Button,
1506
- {
1507
- type: "button",
1508
- onClick: () => setCurrentStep((s) => s + 1),
1509
- className: "w-full",
1510
- children: [
1511
- "Continue to ",
1512
- stepLabels[currentStep]
1513
- ]
1514
- }
1515
- ) : /* @__PURE__ */ jsx3(
1516
- Button,
1517
- {
1518
- type: "button",
1519
- onClick: handleDeploy,
1520
- disabled: isDeploying || !selectedEnv,
1521
- className: "w-full",
1522
- children: isDeploying ? /* @__PURE__ */ jsxs3("span", { className: "flex items-center justify-center gap-2", children: [
1523
- /* @__PURE__ */ jsx3(Loader2, { className: "h-4 w-4 animate-spin" }),
1524
- "Deploying..."
1525
- ] }) : "Deploy Workspace"
1526
- }
1527
- ),
1528
- currentStep > 1 && /* @__PURE__ */ jsx3(
1529
- Button,
1530
- {
1531
- type: "button",
1532
- variant: "secondary",
1533
- onClick: () => setCurrentStep((s) => s - 1),
1534
- className: "w-full",
1535
- children: "Back"
1536
- }
1537
- )
1538
- ] }) : /* @__PURE__ */ jsx3(
1641
+ /* @__PURE__ */ jsx4("div", { className: "space-y-2", children: /* @__PURE__ */ jsx4(
1539
1642
  Button,
1540
1643
  {
1541
1644
  type: "button",
1542
1645
  onClick: handleDeploy,
1543
1646
  disabled: isDeploying || !selectedEnv,
1544
1647
  className: "w-full",
1545
- children: isDeploying ? /* @__PURE__ */ jsxs3("span", { className: "flex items-center justify-center gap-2", children: [
1546
- /* @__PURE__ */ jsx3(Loader2, { className: "h-4 w-4 animate-spin" }),
1648
+ children: isDeploying ? /* @__PURE__ */ jsxs4("span", { className: "flex items-center justify-center gap-2", children: [
1649
+ /* @__PURE__ */ jsx4(Loader22, { className: "h-4 w-4 animate-spin" }),
1547
1650
  "Spinning up environment..."
1548
1651
  ] }) : "Deploy Workspace"
1549
1652
  }
@@ -1554,10 +1657,10 @@ function ProvisioningWizard({
1554
1657
  }
1555
1658
 
1556
1659
  // src/pages/pricing-page.tsx
1557
- import * as React3 from "react";
1660
+ import * as React4 from "react";
1558
1661
  import { Skeleton as Skeleton2, SkeletonCard as SkeletonCard2 } from "@tangle-network/ui/primitives";
1559
1662
  import { ChevronDown } from "lucide-react";
1560
- import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
1663
+ import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1561
1664
  async function fetchTiersFromApi(apiBasePath) {
1562
1665
  const res = await fetch(`${apiBasePath}/v1/billing/tiers`);
1563
1666
  if (!res.ok) throw new Error("Failed to fetch pricing tiers");
@@ -1589,14 +1692,14 @@ function StandalonePricingPage({
1589
1692
  eyebrow,
1590
1693
  className
1591
1694
  }) {
1592
- const [state, setState] = React3.useState({
1695
+ const [state, setState] = React4.useState({
1593
1696
  tiers: initialTiers || [],
1594
1697
  loading: !initialTiers,
1595
1698
  error: null,
1596
1699
  billingPeriod: "monthly",
1597
1700
  selectingTier: false
1598
1701
  });
1599
- const loadTiers = React3.useCallback(async () => {
1702
+ const loadTiers = React4.useCallback(async () => {
1600
1703
  setState((prev) => ({ ...prev, loading: true, error: null }));
1601
1704
  try {
1602
1705
  const tiers = fetchTiers ? await fetchTiers() : await fetchTiersFromApi(apiBasePath);
@@ -1609,12 +1712,12 @@ function StandalonePricingPage({
1609
1712
  }));
1610
1713
  }
1611
1714
  }, [apiBasePath, fetchTiers]);
1612
- React3.useEffect(() => {
1715
+ React4.useEffect(() => {
1613
1716
  if (!initialTiers) {
1614
1717
  loadTiers();
1615
1718
  }
1616
1719
  }, [initialTiers, loadTiers]);
1617
- const handleSelectTier = React3.useCallback(
1720
+ const handleSelectTier = React4.useCallback(
1618
1721
  async (tierId) => {
1619
1722
  if (onSelectTier) {
1620
1723
  onSelectTier(tierId, state.billingPeriod);
@@ -1641,25 +1744,25 @@ function StandalonePricingPage({
1641
1744
  },
1642
1745
  [apiBasePath, state.billingPeriod, onSelectTier]
1643
1746
  );
1644
- return /* @__PURE__ */ jsxs4("div", { className: cn("mx-auto max-w-6xl px-6 py-16 space-y-16", className), children: [
1645
- /* @__PURE__ */ jsxs4("div", { className: "space-y-4 text-center", children: [
1646
- eyebrow && /* @__PURE__ */ jsx4("span", { className: "text-xs font-bold uppercase tracking-widest text-[var(--brand-emerald,#10B981)]", children: eyebrow }),
1647
- /* @__PURE__ */ jsx4("h1", { className: "text-4xl font-extrabold tracking-tight text-foreground sm:text-5xl font-display", children: title }),
1648
- /* @__PURE__ */ jsx4("p", { className: "mx-auto max-w-2xl text-lg text-muted-foreground", children: subtitle })
1747
+ return /* @__PURE__ */ jsxs5("div", { className: cn("mx-auto max-w-6xl px-6 py-16 space-y-16", className), children: [
1748
+ /* @__PURE__ */ jsxs5("div", { className: "space-y-4 text-center", children: [
1749
+ eyebrow && /* @__PURE__ */ jsx5("span", { className: "text-xs font-bold uppercase tracking-widest text-[var(--brand-emerald,#10B981)]", children: eyebrow }),
1750
+ /* @__PURE__ */ jsx5("h1", { className: "text-4xl font-extrabold tracking-tight text-foreground sm:text-5xl font-display", children: title }),
1751
+ /* @__PURE__ */ jsx5("p", { className: "mx-auto max-w-2xl text-lg text-muted-foreground", children: subtitle })
1649
1752
  ] }),
1650
- state.loading ? /* @__PURE__ */ jsxs4("div", { className: "space-y-8", children: [
1651
- /* @__PURE__ */ jsxs4("div", { className: "flex items-center justify-center gap-4", children: [
1652
- /* @__PURE__ */ jsx4(Skeleton2, { className: "h-10 w-24" }),
1653
- /* @__PURE__ */ jsx4(Skeleton2, { className: "h-10 w-24" })
1753
+ state.loading ? /* @__PURE__ */ jsxs5("div", { className: "space-y-8", children: [
1754
+ /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-center gap-4", children: [
1755
+ /* @__PURE__ */ jsx5(Skeleton2, { className: "h-10 w-24" }),
1756
+ /* @__PURE__ */ jsx5(Skeleton2, { className: "h-10 w-24" })
1654
1757
  ] }),
1655
- /* @__PURE__ */ jsxs4("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-3", children: [
1656
- /* @__PURE__ */ jsx4(SkeletonCard2, { className: "h-[500px]" }),
1657
- /* @__PURE__ */ jsx4(SkeletonCard2, { className: "h-[500px]" }),
1658
- /* @__PURE__ */ jsx4(SkeletonCard2, { className: "h-[500px]" })
1758
+ /* @__PURE__ */ jsxs5("div", { className: "grid grid-cols-1 gap-6 lg:grid-cols-3", children: [
1759
+ /* @__PURE__ */ jsx5(SkeletonCard2, { className: "h-[500px]" }),
1760
+ /* @__PURE__ */ jsx5(SkeletonCard2, { className: "h-[500px]" }),
1761
+ /* @__PURE__ */ jsx5(SkeletonCard2, { className: "h-[500px]" })
1659
1762
  ] })
1660
- ] }) : state.error ? /* @__PURE__ */ jsxs4("div", { className: "flex flex-col items-center justify-center space-y-4 rounded-xl border border-destructive/20 bg-destructive/5 p-8 text-center", children: [
1661
- /* @__PURE__ */ jsx4("p", { className: "text-destructive text-sm font-medium", children: state.error }),
1662
- /* @__PURE__ */ jsx4(
1763
+ ] }) : state.error ? /* @__PURE__ */ jsxs5("div", { className: "flex flex-col items-center justify-center space-y-4 rounded-xl border border-destructive/20 bg-destructive/5 p-8 text-center", children: [
1764
+ /* @__PURE__ */ jsx5("p", { className: "text-destructive text-sm font-medium", children: state.error }),
1765
+ /* @__PURE__ */ jsx5(
1663
1766
  "button",
1664
1767
  {
1665
1768
  type: "button",
@@ -1668,7 +1771,7 @@ function StandalonePricingPage({
1668
1771
  children: "Try Again"
1669
1772
  }
1670
1773
  )
1671
- ] }) : /* @__PURE__ */ jsx4(
1774
+ ] }) : /* @__PURE__ */ jsx5(
1672
1775
  PricingPage,
1673
1776
  {
1674
1777
  tiers: state.tiers,
@@ -1679,14 +1782,14 @@ function StandalonePricingPage({
1679
1782
  loading: state.selectingTier
1680
1783
  }
1681
1784
  ),
1682
- /* @__PURE__ */ jsxs4("div", { className: "mx-auto max-w-2xl space-y-4 border-t border-border pt-12", children: [
1683
- /* @__PURE__ */ jsx4("h2", { className: "text-center text-xl font-bold text-foreground mb-6", children: "Frequently Asked Questions" }),
1684
- FAQ.map(({ q, a }) => /* @__PURE__ */ jsxs4("details", { className: "group rounded-xl border border-border bg-card overflow-hidden", children: [
1685
- /* @__PURE__ */ jsxs4("summary", { className: "flex cursor-pointer items-center justify-between px-6 py-4 font-medium text-foreground text-sm", children: [
1785
+ /* @__PURE__ */ jsxs5("div", { className: "mx-auto max-w-2xl space-y-4 border-t border-border pt-12", children: [
1786
+ /* @__PURE__ */ jsx5("h2", { className: "text-center text-xl font-bold text-foreground mb-6", children: "Frequently Asked Questions" }),
1787
+ FAQ.map(({ q, a }) => /* @__PURE__ */ jsxs5("details", { className: "group rounded-xl border border-border bg-card overflow-hidden", children: [
1788
+ /* @__PURE__ */ jsxs5("summary", { className: "flex cursor-pointer items-center justify-between px-6 py-4 font-medium text-foreground text-sm", children: [
1686
1789
  q,
1687
- /* @__PURE__ */ jsx4(ChevronDown, { className: "h-4 w-4 text-muted-foreground transition-transform group-open:rotate-180" })
1790
+ /* @__PURE__ */ jsx5(ChevronDown, { className: "h-4 w-4 text-muted-foreground transition-transform group-open:rotate-180" })
1688
1791
  ] }),
1689
- /* @__PURE__ */ jsx4("div", { className: "px-6 pb-4", children: /* @__PURE__ */ jsx4("p", { className: "text-sm text-muted-foreground leading-relaxed", children: a }) })
1792
+ /* @__PURE__ */ jsx5("div", { className: "px-6 pb-4", children: /* @__PURE__ */ jsx5("p", { className: "text-sm text-muted-foreground leading-relaxed", children: a }) })
1690
1793
  ] }, q))
1691
1794
  ] })
1692
1795
  ] });
@@ -1698,27 +1801,27 @@ import {
1698
1801
  ChevronRight,
1699
1802
  Copy,
1700
1803
  Edit2,
1701
- Loader2 as Loader22,
1804
+ Loader2 as Loader23,
1702
1805
  Plus as Plus2,
1703
1806
  Search,
1704
1807
  Settings2,
1705
1808
  Trash2 as Trash22
1706
1809
  } from "lucide-react";
1707
- import * as React4 from "react";
1810
+ import * as React5 from "react";
1708
1811
  import { Button as Button2 } from "@tangle-network/ui/primitives";
1709
1812
  import { Badge as Badge2 } from "@tangle-network/ui/primitives";
1710
1813
  import { Card } from "@tangle-network/ui/primitives";
1711
1814
  import {
1712
- Dialog,
1713
- DialogContent,
1714
- DialogDescription,
1715
- DialogFooter,
1716
- DialogHeader,
1717
- DialogTitle
1815
+ Dialog as Dialog2,
1816
+ DialogContent as DialogContent2,
1817
+ DialogDescription as DialogDescription2,
1818
+ DialogFooter as DialogFooter2,
1819
+ DialogHeader as DialogHeader2,
1820
+ DialogTitle as DialogTitle2
1718
1821
  } from "@tangle-network/ui/primitives";
1719
1822
  import { EmptyState } from "@tangle-network/ui/primitives";
1720
1823
  import { Input as Input2 } from "@tangle-network/ui/primitives";
1721
- import { jsx as jsx5, jsxs as jsxs5 } from "react/jsx-runtime";
1824
+ import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
1722
1825
  var TIER_LIMITS = {
1723
1826
  free: 3,
1724
1827
  starter: 10,
@@ -1732,24 +1835,24 @@ function ProfilesPage({
1732
1835
  onCompareClick,
1733
1836
  title = "Profiles"
1734
1837
  }) {
1735
- const [builtinProfiles, setBuiltinProfiles] = React4.useState([]);
1736
- const [customProfiles, setCustomProfiles] = React4.useState([]);
1737
- const [loading, setLoading] = React4.useState(true);
1738
- const [error, setError] = React4.useState(null);
1739
- const [searchQuery, setSearchQuery] = React4.useState("");
1740
- const [createDialogOpen, setCreateDialogOpen] = React4.useState(false);
1741
- const [editingProfile, setEditingProfile] = React4.useState(
1838
+ const [builtinProfiles, setBuiltinProfiles] = React5.useState([]);
1839
+ const [customProfiles, setCustomProfiles] = React5.useState([]);
1840
+ const [loading, setLoading] = React5.useState(true);
1841
+ const [error, setError] = React5.useState(null);
1842
+ const [searchQuery, setSearchQuery] = React5.useState("");
1843
+ const [createDialogOpen, setCreateDialogOpen] = React5.useState(false);
1844
+ const [editingProfile, setEditingProfile] = React5.useState(
1742
1845
  null
1743
1846
  );
1744
- const [deletingProfile, setDeletingProfile] = React4.useState(
1847
+ const [deletingProfile, setDeletingProfile] = React5.useState(
1745
1848
  null
1746
1849
  );
1747
- const [detailProfile, setDetailProfile] = React4.useState(
1850
+ const [detailProfile, setDetailProfile] = React5.useState(
1748
1851
  null
1749
1852
  );
1750
1853
  const profileLimit = maxProfiles ?? TIER_LIMITS[tier] ?? 3;
1751
1854
  const canCreateMore = customProfiles.length < profileLimit;
1752
- const loadProfiles = React4.useCallback(async () => {
1855
+ const loadProfiles = React5.useCallback(async () => {
1753
1856
  try {
1754
1857
  setLoading(true);
1755
1858
  setError(null);
@@ -1762,7 +1865,7 @@ function ProfilesPage({
1762
1865
  setLoading(false);
1763
1866
  }
1764
1867
  }, [apiClient]);
1765
- React4.useEffect(() => {
1868
+ React5.useEffect(() => {
1766
1869
  loadProfiles();
1767
1870
  }, [loadProfiles]);
1768
1871
  const filteredBuiltin = builtinProfiles.filter(
@@ -1771,14 +1874,14 @@ function ProfilesPage({
1771
1874
  const filteredCustom = customProfiles.filter(
1772
1875
  (p) => p.name.toLowerCase().includes(searchQuery.toLowerCase()) || p.description?.toLowerCase().includes(searchQuery.toLowerCase())
1773
1876
  );
1774
- return /* @__PURE__ */ jsxs5("div", { className: "space-y-6", children: [
1775
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center justify-between", children: [
1776
- /* @__PURE__ */ jsxs5("div", { children: [
1777
- /* @__PURE__ */ jsx5("h1", { className: "font-semibold text-2xl", children: title }),
1778
- /* @__PURE__ */ jsx5("p", { className: "text-muted-foreground", children: "Customize agent behavior with system prompts, models, and instructions" })
1877
+ return /* @__PURE__ */ jsxs6("div", { className: "space-y-6", children: [
1878
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center justify-between", children: [
1879
+ /* @__PURE__ */ jsxs6("div", { children: [
1880
+ /* @__PURE__ */ jsx6("h1", { className: "font-semibold text-2xl", children: title }),
1881
+ /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground", children: "Customize agent behavior with system prompts, models, and instructions" })
1779
1882
  ] }),
1780
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-3", children: [
1781
- onCompareClick && customProfiles.length >= 2 && /* @__PURE__ */ jsx5(
1883
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3", children: [
1884
+ onCompareClick && customProfiles.length >= 2 && /* @__PURE__ */ jsx6(
1782
1885
  Button2,
1783
1886
  {
1784
1887
  variant: "outline",
@@ -1786,30 +1889,30 @@ function ProfilesPage({
1786
1889
  children: "Compare Profiles"
1787
1890
  }
1788
1891
  ),
1789
- /* @__PURE__ */ jsxs5(
1892
+ /* @__PURE__ */ jsxs6(
1790
1893
  Button2,
1791
1894
  {
1792
1895
  onClick: () => setCreateDialogOpen(true),
1793
1896
  disabled: !canCreateMore,
1794
1897
  children: [
1795
- /* @__PURE__ */ jsx5(Plus2, { className: "mr-2 h-4 w-4" }),
1898
+ /* @__PURE__ */ jsx6(Plus2, { className: "mr-2 h-4 w-4" }),
1796
1899
  "Create Profile"
1797
1900
  ]
1798
1901
  }
1799
1902
  )
1800
1903
  ] })
1801
1904
  ] }),
1802
- !canCreateMore && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] p-3 text-sm text-[var(--surface-warning-text)]", children: [
1803
- /* @__PURE__ */ jsx5(AlertCircle, { className: "h-4 w-4" }),
1804
- /* @__PURE__ */ jsxs5("span", { children: [
1905
+ !canCreateMore && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] p-3 text-sm text-[var(--surface-warning-text)]", children: [
1906
+ /* @__PURE__ */ jsx6(AlertCircle, { className: "h-4 w-4" }),
1907
+ /* @__PURE__ */ jsxs6("span", { children: [
1805
1908
  "You've reached your profile limit (",
1806
1909
  profileLimit,
1807
1910
  " profiles). Upgrade your plan to create more."
1808
1911
  ] })
1809
1912
  ] }),
1810
- /* @__PURE__ */ jsxs5("div", { className: "relative max-w-md", children: [
1811
- /* @__PURE__ */ jsx5(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
1812
- /* @__PURE__ */ jsx5(
1913
+ /* @__PURE__ */ jsxs6("div", { className: "relative max-w-md", children: [
1914
+ /* @__PURE__ */ jsx6(Search, { className: "absolute top-1/2 left-3 h-4 w-4 -translate-y-1/2 text-muted-foreground" }),
1915
+ /* @__PURE__ */ jsx6(
1813
1916
  Input2,
1814
1917
  {
1815
1918
  placeholder: "Search profiles...",
@@ -1819,33 +1922,33 @@ function ProfilesPage({
1819
1922
  }
1820
1923
  )
1821
1924
  ] }),
1822
- error && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] p-3 text-[var(--surface-danger-text)] text-sm", children: [
1823
- /* @__PURE__ */ jsx5(AlertCircle, { className: "h-4 w-4" }),
1824
- /* @__PURE__ */ jsx5("span", { children: error }),
1825
- /* @__PURE__ */ jsx5(Button2, { variant: "ghost", size: "sm", onClick: loadProfiles, children: "Retry" })
1925
+ error && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] p-3 text-[var(--surface-danger-text)] text-sm", children: [
1926
+ /* @__PURE__ */ jsx6(AlertCircle, { className: "h-4 w-4" }),
1927
+ /* @__PURE__ */ jsx6("span", { children: error }),
1928
+ /* @__PURE__ */ jsx6(Button2, { variant: "ghost", size: "sm", onClick: loadProfiles, children: "Retry" })
1826
1929
  ] }),
1827
- loading && /* @__PURE__ */ jsx5("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx5(Loader22, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }),
1828
- !loading && /* @__PURE__ */ jsxs5("div", { className: "space-y-8", children: [
1829
- /* @__PURE__ */ jsxs5("section", { children: [
1830
- /* @__PURE__ */ jsx5("div", { className: "mb-3 flex items-center justify-between", children: /* @__PURE__ */ jsxs5("h2", { className: "font-medium text-lg", children: [
1930
+ loading && /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center py-12", children: /* @__PURE__ */ jsx6(Loader23, { className: "h-8 w-8 animate-spin text-muted-foreground" }) }),
1931
+ !loading && /* @__PURE__ */ jsxs6("div", { className: "space-y-8", children: [
1932
+ /* @__PURE__ */ jsxs6("section", { children: [
1933
+ /* @__PURE__ */ jsx6("div", { className: "mb-3 flex items-center justify-between", children: /* @__PURE__ */ jsxs6("h2", { className: "font-medium text-lg", children: [
1831
1934
  "Your Profiles (",
1832
1935
  customProfiles.length,
1833
1936
  "/",
1834
1937
  profileLimit === Number.POSITIVE_INFINITY ? "inf" : profileLimit,
1835
1938
  ")"
1836
1939
  ] }) }),
1837
- filteredCustom.length === 0 ? /* @__PURE__ */ jsx5(
1940
+ filteredCustom.length === 0 ? /* @__PURE__ */ jsx6(
1838
1941
  EmptyState,
1839
1942
  {
1840
- icon: /* @__PURE__ */ jsx5(Settings2, { className: "h-8 w-8" }),
1943
+ icon: /* @__PURE__ */ jsx6(Settings2, { className: "h-8 w-8" }),
1841
1944
  title: "No custom profiles yet",
1842
1945
  description: "Create a profile to customize agent behavior",
1843
- action: canCreateMore ? /* @__PURE__ */ jsxs5(Button2, { onClick: () => setCreateDialogOpen(true), children: [
1844
- /* @__PURE__ */ jsx5(Plus2, { className: "mr-2 h-4 w-4" }),
1946
+ action: canCreateMore ? /* @__PURE__ */ jsxs6(Button2, { onClick: () => setCreateDialogOpen(true), children: [
1947
+ /* @__PURE__ */ jsx6(Plus2, { className: "mr-2 h-4 w-4" }),
1845
1948
  "Create Profile"
1846
1949
  ] }) : void 0
1847
1950
  }
1848
- ) : /* @__PURE__ */ jsx5("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: filteredCustom.map((profile) => /* @__PURE__ */ jsx5(
1951
+ ) : /* @__PURE__ */ jsx6("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: filteredCustom.map((profile) => /* @__PURE__ */ jsx6(
1849
1952
  ProfileCard,
1850
1953
  {
1851
1954
  profile,
@@ -1856,13 +1959,13 @@ function ProfilesPage({
1856
1959
  profile.id
1857
1960
  )) })
1858
1961
  ] }),
1859
- /* @__PURE__ */ jsxs5("section", { children: [
1860
- /* @__PURE__ */ jsx5("div", { className: "mb-3 flex items-center justify-between", children: /* @__PURE__ */ jsxs5("h2", { className: "font-medium text-lg", children: [
1962
+ /* @__PURE__ */ jsxs6("section", { children: [
1963
+ /* @__PURE__ */ jsx6("div", { className: "mb-3 flex items-center justify-between", children: /* @__PURE__ */ jsxs6("h2", { className: "font-medium text-lg", children: [
1861
1964
  "Built-in Profiles (",
1862
1965
  builtinProfiles.length,
1863
1966
  ")"
1864
1967
  ] }) }),
1865
- filteredBuiltin.length === 0 ? /* @__PURE__ */ jsx5("p", { className: "text-muted-foreground text-sm", children: "No matching built-in profiles" }) : /* @__PURE__ */ jsx5("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: filteredBuiltin.map((profile) => /* @__PURE__ */ jsx5(
1968
+ filteredBuiltin.length === 0 ? /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground text-sm", children: "No matching built-in profiles" }) : /* @__PURE__ */ jsx6("div", { className: "grid gap-4 md:grid-cols-2 lg:grid-cols-3", children: filteredBuiltin.map((profile) => /* @__PURE__ */ jsx6(
1866
1969
  ProfileCard,
1867
1970
  {
1868
1971
  profile,
@@ -1873,7 +1976,7 @@ function ProfilesPage({
1873
1976
  )) })
1874
1977
  ] })
1875
1978
  ] }),
1876
- /* @__PURE__ */ jsx5(
1979
+ /* @__PURE__ */ jsx6(
1877
1980
  ProfileFormDialog,
1878
1981
  {
1879
1982
  open: createDialogOpen || !!editingProfile,
@@ -1891,7 +1994,7 @@ function ProfilesPage({
1891
1994
  }
1892
1995
  }
1893
1996
  ),
1894
- /* @__PURE__ */ jsx5(
1997
+ /* @__PURE__ */ jsx6(
1895
1998
  DeleteProfileDialog,
1896
1999
  {
1897
2000
  profile: deletingProfile,
@@ -1903,7 +2006,7 @@ function ProfilesPage({
1903
2006
  }
1904
2007
  }
1905
2008
  ),
1906
- /* @__PURE__ */ jsx5(
2009
+ /* @__PURE__ */ jsx6(
1907
2010
  ProfileDetailDialog,
1908
2011
  {
1909
2012
  profile: detailProfile,
@@ -1932,61 +2035,61 @@ function ProfileCard({
1932
2035
  onDelete,
1933
2036
  isBuiltin
1934
2037
  }) {
1935
- return /* @__PURE__ */ jsxs5(
2038
+ return /* @__PURE__ */ jsxs6(
1936
2039
  Card,
1937
2040
  {
1938
2041
  className: "cursor-pointer p-4 transition-colors hover:border-border/80",
1939
2042
  onClick: onView,
1940
2043
  children: [
1941
- /* @__PURE__ */ jsxs5("div", { className: "flex items-start justify-between", children: [
1942
- /* @__PURE__ */ jsxs5("div", { className: "flex-1", children: [
1943
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
1944
- /* @__PURE__ */ jsx5("h3", { className: "font-medium", children: profile.name }),
1945
- isBuiltin && /* @__PURE__ */ jsx5(Badge2, { variant: "secondary", className: "border-0 text-xs", children: "Built-in" }),
1946
- profile.is_public && !isBuiltin && /* @__PURE__ */ jsx5(Badge2, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Public" })
2044
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-start justify-between", children: [
2045
+ /* @__PURE__ */ jsxs6("div", { className: "flex-1", children: [
2046
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
2047
+ /* @__PURE__ */ jsx6("h3", { className: "font-medium", children: profile.name }),
2048
+ isBuiltin && /* @__PURE__ */ jsx6(Badge2, { variant: "secondary", className: "border-0 text-xs", children: "Built-in" }),
2049
+ profile.is_public && !isBuiltin && /* @__PURE__ */ jsx6(Badge2, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)] text-xs", children: "Public" })
1947
2050
  ] }),
1948
- profile.description && /* @__PURE__ */ jsx5("p", { className: "mt-1 line-clamp-2 text-muted-foreground text-sm", children: profile.description })
2051
+ profile.description && /* @__PURE__ */ jsx6("p", { className: "mt-1 line-clamp-2 text-muted-foreground text-sm", children: profile.description })
1949
2052
  ] }),
1950
- !isBuiltin && /* @__PURE__ */ jsxs5("div", { className: "flex gap-1", onClick: (e) => e.stopPropagation(), children: [
1951
- onEdit && /* @__PURE__ */ jsx5(
2053
+ !isBuiltin && /* @__PURE__ */ jsxs6("div", { className: "flex gap-1", onClick: (e) => e.stopPropagation(), children: [
2054
+ onEdit && /* @__PURE__ */ jsx6(
1952
2055
  Button2,
1953
2056
  {
1954
2057
  variant: "ghost",
1955
2058
  size: "icon",
1956
2059
  onClick: onEdit,
1957
2060
  "aria-label": "Edit profile",
1958
- children: /* @__PURE__ */ jsx5(Edit2, { className: "h-4 w-4" })
2061
+ children: /* @__PURE__ */ jsx6(Edit2, { className: "h-4 w-4" })
1959
2062
  }
1960
2063
  ),
1961
- onDelete && /* @__PURE__ */ jsx5(
2064
+ onDelete && /* @__PURE__ */ jsx6(
1962
2065
  Button2,
1963
2066
  {
1964
2067
  variant: "ghost",
1965
2068
  size: "icon",
1966
2069
  onClick: onDelete,
1967
2070
  "aria-label": "Delete profile",
1968
- children: /* @__PURE__ */ jsx5(Trash22, { className: "h-4 w-4 text-[var(--surface-danger-text)]" })
2071
+ children: /* @__PURE__ */ jsx6(Trash22, { className: "h-4 w-4 text-[var(--surface-danger-text)]" })
1969
2072
  }
1970
2073
  )
1971
2074
  ] })
1972
2075
  ] }),
1973
- /* @__PURE__ */ jsxs5("div", { className: "mt-3 flex flex-wrap gap-2", children: [
1974
- profile.extends && /* @__PURE__ */ jsxs5(Badge2, { variant: "outline", className: "text-xs", children: [
2076
+ /* @__PURE__ */ jsxs6("div", { className: "mt-3 flex flex-wrap gap-2", children: [
2077
+ profile.extends && /* @__PURE__ */ jsxs6(Badge2, { variant: "outline", className: "text-xs", children: [
1975
2078
  "extends ",
1976
2079
  profile.extends
1977
2080
  ] }),
1978
- profile.model && /* @__PURE__ */ jsx5(Badge2, { variant: "outline", className: "text-xs", children: profile.model.split("/").pop() })
2081
+ profile.model && /* @__PURE__ */ jsx6(Badge2, { variant: "outline", className: "text-xs", children: profile.model.split("/").pop() })
1979
2082
  ] }),
1980
- profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs5("div", { className: "mt-3 flex gap-4 border-border border-t pt-3 text-muted-foreground text-xs", children: [
1981
- /* @__PURE__ */ jsxs5("span", { children: [
2083
+ profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs6("div", { className: "mt-3 flex gap-4 border-border border-t pt-3 text-muted-foreground text-xs", children: [
2084
+ /* @__PURE__ */ jsxs6("span", { children: [
1982
2085
  profile.metrics.total_runs,
1983
2086
  " runs"
1984
2087
  ] }),
1985
- /* @__PURE__ */ jsxs5("span", { children: [
2088
+ /* @__PURE__ */ jsxs6("span", { children: [
1986
2089
  profile.metrics.success_rate.toFixed(0),
1987
2090
  "% success"
1988
2091
  ] }),
1989
- /* @__PURE__ */ jsxs5("span", { children: [
2092
+ /* @__PURE__ */ jsxs6("span", { children: [
1990
2093
  "~",
1991
2094
  (profile.metrics.avg_duration_ms / 1e3).toFixed(1),
1992
2095
  "s avg"
@@ -2005,7 +2108,7 @@ function ProfileFormDialog({
2005
2108
  onSuccess
2006
2109
  }) {
2007
2110
  const isEditing = !!profile?.id;
2008
- const [formData, setFormData] = React4.useState({
2111
+ const [formData, setFormData] = React5.useState({
2009
2112
  name: "",
2010
2113
  description: "",
2011
2114
  extends: "",
@@ -2015,9 +2118,9 @@ function ProfileFormDialog({
2015
2118
  tags: [],
2016
2119
  is_public: false
2017
2120
  });
2018
- const [saving, setSaving] = React4.useState(false);
2019
- const [error, setError] = React4.useState(null);
2020
- React4.useEffect(() => {
2121
+ const [saving, setSaving] = React5.useState(false);
2122
+ const [error, setError] = React5.useState(null);
2123
+ React5.useEffect(() => {
2021
2124
  if (profile) {
2022
2125
  setFormData({
2023
2126
  name: profile.name,
@@ -2073,19 +2176,19 @@ function ProfileFormDialog({
2073
2176
  setSaving(false);
2074
2177
  }
2075
2178
  };
2076
- return /* @__PURE__ */ jsx5(Dialog, { open, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ jsxs5(DialogContent, { className: "max-w-2xl", children: [
2077
- /* @__PURE__ */ jsxs5(DialogHeader, { children: [
2078
- /* @__PURE__ */ jsx5(DialogTitle, { children: isEditing ? "Edit Profile" : "Create Profile" }),
2079
- /* @__PURE__ */ jsx5(DialogDescription, { children: isEditing ? "Update your custom profile configuration" : "Create a new profile to customize agent behavior" })
2179
+ return /* @__PURE__ */ jsx6(Dialog2, { open, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ jsxs6(DialogContent2, { className: "max-w-2xl", children: [
2180
+ /* @__PURE__ */ jsxs6(DialogHeader2, { children: [
2181
+ /* @__PURE__ */ jsx6(DialogTitle2, { children: isEditing ? "Edit Profile" : "Create Profile" }),
2182
+ /* @__PURE__ */ jsx6(DialogDescription2, { children: isEditing ? "Update your custom profile configuration" : "Create a new profile to customize agent behavior" })
2080
2183
  ] }),
2081
- /* @__PURE__ */ jsxs5("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
2082
- error && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] p-3 text-[var(--surface-danger-text)] text-sm", children: [
2083
- /* @__PURE__ */ jsx5(AlertCircle, { className: "h-4 w-4" }),
2084
- /* @__PURE__ */ jsx5("span", { children: error })
2184
+ /* @__PURE__ */ jsxs6("form", { onSubmit: handleSubmit, className: "space-y-4", children: [
2185
+ error && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] p-3 text-[var(--surface-danger-text)] text-sm", children: [
2186
+ /* @__PURE__ */ jsx6(AlertCircle, { className: "h-4 w-4" }),
2187
+ /* @__PURE__ */ jsx6("span", { children: error })
2085
2188
  ] }),
2086
- /* @__PURE__ */ jsxs5("div", { children: [
2087
- /* @__PURE__ */ jsx5("label", { className: "mb-1 block font-medium text-sm", children: "Name *" }),
2088
- /* @__PURE__ */ jsx5(
2189
+ /* @__PURE__ */ jsxs6("div", { children: [
2190
+ /* @__PURE__ */ jsx6("label", { className: "mb-1 block font-medium text-sm", children: "Name *" }),
2191
+ /* @__PURE__ */ jsx6(
2089
2192
  Input2,
2090
2193
  {
2091
2194
  value: formData.name,
@@ -2097,9 +2200,9 @@ function ProfileFormDialog({
2097
2200
  }
2098
2201
  )
2099
2202
  ] }),
2100
- /* @__PURE__ */ jsxs5("div", { children: [
2101
- /* @__PURE__ */ jsx5("label", { className: "mb-1 block font-medium text-sm", children: "Description" }),
2102
- /* @__PURE__ */ jsx5(
2203
+ /* @__PURE__ */ jsxs6("div", { children: [
2204
+ /* @__PURE__ */ jsx6("label", { className: "mb-1 block font-medium text-sm", children: "Description" }),
2205
+ /* @__PURE__ */ jsx6(
2103
2206
  Input2,
2104
2207
  {
2105
2208
  value: formData.description,
@@ -2108,17 +2211,17 @@ function ProfileFormDialog({
2108
2211
  }
2109
2212
  )
2110
2213
  ] }),
2111
- /* @__PURE__ */ jsxs5("div", { children: [
2112
- /* @__PURE__ */ jsx5("label", { className: "mb-1 block font-medium text-sm", children: "Extends (base profile)" }),
2113
- /* @__PURE__ */ jsxs5(
2214
+ /* @__PURE__ */ jsxs6("div", { children: [
2215
+ /* @__PURE__ */ jsx6("label", { className: "mb-1 block font-medium text-sm", children: "Extends (base profile)" }),
2216
+ /* @__PURE__ */ jsxs6(
2114
2217
  "select",
2115
2218
  {
2116
2219
  value: formData.extends,
2117
2220
  onChange: (e) => setFormData((d) => ({ ...d, extends: e.target.value })),
2118
2221
  className: "w-full rounded-md border border-border bg-background px-3 py-2 text-sm",
2119
2222
  children: [
2120
- /* @__PURE__ */ jsx5("option", { value: "", children: "None (start from scratch)" }),
2121
- builtinProfiles.map((p) => /* @__PURE__ */ jsxs5("option", { value: p.name, children: [
2223
+ /* @__PURE__ */ jsx6("option", { value: "", children: "None (start from scratch)" }),
2224
+ builtinProfiles.map((p) => /* @__PURE__ */ jsxs6("option", { value: p.name, children: [
2122
2225
  p.name,
2123
2226
  " - ",
2124
2227
  p.description ?? "Built-in profile"
@@ -2127,9 +2230,9 @@ function ProfileFormDialog({
2127
2230
  }
2128
2231
  )
2129
2232
  ] }),
2130
- /* @__PURE__ */ jsxs5("div", { children: [
2131
- /* @__PURE__ */ jsx5("label", { className: "mb-1 block font-medium text-sm", children: "Model" }),
2132
- /* @__PURE__ */ jsx5(
2233
+ /* @__PURE__ */ jsxs6("div", { children: [
2234
+ /* @__PURE__ */ jsx6("label", { className: "mb-1 block font-medium text-sm", children: "Model" }),
2235
+ /* @__PURE__ */ jsx6(
2133
2236
  Input2,
2134
2237
  {
2135
2238
  value: formData.model,
@@ -2137,11 +2240,11 @@ function ProfileFormDialog({
2137
2240
  placeholder: "anthropic/claude-sonnet-4"
2138
2241
  }
2139
2242
  ),
2140
- /* @__PURE__ */ jsx5("p", { className: "mt-1 text-muted-foreground text-xs", children: "Format: provider/model-id (e.g., anthropic/claude-sonnet-4)" })
2243
+ /* @__PURE__ */ jsx6("p", { className: "mt-1 text-muted-foreground text-xs", children: "Format: provider/model-id (e.g., anthropic/claude-sonnet-4)" })
2141
2244
  ] }),
2142
- /* @__PURE__ */ jsxs5("div", { children: [
2143
- /* @__PURE__ */ jsx5("label", { className: "mb-1 block font-medium text-sm", children: "System Prompt" }),
2144
- /* @__PURE__ */ jsx5(
2245
+ /* @__PURE__ */ jsxs6("div", { children: [
2246
+ /* @__PURE__ */ jsx6("label", { className: "mb-1 block font-medium text-sm", children: "System Prompt" }),
2247
+ /* @__PURE__ */ jsx6(
2145
2248
  "textarea",
2146
2249
  {
2147
2250
  value: formData.system_prompt,
@@ -2152,9 +2255,9 @@ function ProfileFormDialog({
2152
2255
  }
2153
2256
  )
2154
2257
  ] }),
2155
- /* @__PURE__ */ jsxs5("div", { children: [
2156
- /* @__PURE__ */ jsx5("label", { className: "mb-1 block font-medium text-sm", children: "Tags" }),
2157
- /* @__PURE__ */ jsx5(
2258
+ /* @__PURE__ */ jsxs6("div", { children: [
2259
+ /* @__PURE__ */ jsx6("label", { className: "mb-1 block font-medium text-sm", children: "Tags" }),
2260
+ /* @__PURE__ */ jsx6(
2158
2261
  Input2,
2159
2262
  {
2160
2263
  value: formData.tags?.join(", "),
@@ -2165,10 +2268,10 @@ function ProfileFormDialog({
2165
2268
  placeholder: "trading, aggressive, experimental"
2166
2269
  }
2167
2270
  ),
2168
- /* @__PURE__ */ jsx5("p", { className: "mt-1 text-muted-foreground text-xs", children: "Comma-separated tags for organization" })
2271
+ /* @__PURE__ */ jsx6("p", { className: "mt-1 text-muted-foreground text-xs", children: "Comma-separated tags for organization" })
2169
2272
  ] }),
2170
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
2171
- /* @__PURE__ */ jsx5(
2273
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
2274
+ /* @__PURE__ */ jsx6(
2172
2275
  "input",
2173
2276
  {
2174
2277
  type: "checkbox",
@@ -2178,12 +2281,12 @@ function ProfileFormDialog({
2178
2281
  className: "rounded border-border"
2179
2282
  }
2180
2283
  ),
2181
- /* @__PURE__ */ jsx5("label", { htmlFor: "is_public", className: "text-sm", children: "Make this profile public (visible to other users)" })
2284
+ /* @__PURE__ */ jsx6("label", { htmlFor: "is_public", className: "text-sm", children: "Make this profile public (visible to other users)" })
2182
2285
  ] }),
2183
- /* @__PURE__ */ jsxs5(DialogFooter, { children: [
2184
- /* @__PURE__ */ jsx5(Button2, { type: "button", variant: "outline", onClick: onClose, children: "Cancel" }),
2185
- /* @__PURE__ */ jsxs5(Button2, { type: "submit", disabled: saving || !formData.name, children: [
2186
- saving && /* @__PURE__ */ jsx5(Loader22, { className: "mr-2 h-4 w-4 animate-spin" }),
2286
+ /* @__PURE__ */ jsxs6(DialogFooter2, { children: [
2287
+ /* @__PURE__ */ jsx6(Button2, { type: "button", variant: "outline", onClick: onClose, children: "Cancel" }),
2288
+ /* @__PURE__ */ jsxs6(Button2, { type: "submit", disabled: saving || !formData.name, children: [
2289
+ saving && /* @__PURE__ */ jsx6(Loader23, { className: "mr-2 h-4 w-4 animate-spin" }),
2187
2290
  isEditing ? "Save Changes" : "Create Profile"
2188
2291
  ] })
2189
2292
  ] })
@@ -2196,8 +2299,8 @@ function DeleteProfileDialog({
2196
2299
  apiClient,
2197
2300
  onSuccess
2198
2301
  }) {
2199
- const [deleting, setDeleting] = React4.useState(false);
2200
- const [error, setError] = React4.useState(null);
2302
+ const [deleting, setDeleting] = React5.useState(false);
2303
+ const [error, setError] = React5.useState(null);
2201
2304
  const handleDelete = async () => {
2202
2305
  if (!profile) return;
2203
2306
  setError(null);
@@ -2211,34 +2314,34 @@ function DeleteProfileDialog({
2211
2314
  setDeleting(false);
2212
2315
  }
2213
2316
  };
2214
- return /* @__PURE__ */ jsx5(Dialog, { open: !!profile, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ jsxs5(DialogContent, { children: [
2215
- /* @__PURE__ */ jsxs5(DialogHeader, { children: [
2216
- /* @__PURE__ */ jsx5(DialogTitle, { children: "Delete Profile" }),
2217
- /* @__PURE__ */ jsxs5(DialogDescription, { children: [
2317
+ return /* @__PURE__ */ jsx6(Dialog2, { open: !!profile, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ jsxs6(DialogContent2, { children: [
2318
+ /* @__PURE__ */ jsxs6(DialogHeader2, { children: [
2319
+ /* @__PURE__ */ jsx6(DialogTitle2, { children: "Delete Profile" }),
2320
+ /* @__PURE__ */ jsxs6(DialogDescription2, { children: [
2218
2321
  'Are you sure you want to delete "',
2219
2322
  profile?.name,
2220
2323
  '"? This action cannot be undone.'
2221
2324
  ] })
2222
2325
  ] }),
2223
- error && /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] p-3 text-[var(--surface-danger-text)] text-sm", children: [
2224
- /* @__PURE__ */ jsx5(AlertCircle, { className: "h-4 w-4" }),
2225
- /* @__PURE__ */ jsx5("span", { children: error })
2326
+ error && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2 rounded-lg border border-[var(--surface-danger-border)] bg-[var(--surface-danger-bg)] p-3 text-[var(--surface-danger-text)] text-sm", children: [
2327
+ /* @__PURE__ */ jsx6(AlertCircle, { className: "h-4 w-4" }),
2328
+ /* @__PURE__ */ jsx6("span", { children: error })
2226
2329
  ] }),
2227
- profile?.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs5("div", { className: "rounded-lg border border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] p-3 text-sm text-[var(--surface-warning-text)]", children: [
2330
+ profile?.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-[var(--surface-warning-border)] bg-[var(--surface-warning-bg)] p-3 text-sm text-[var(--surface-warning-text)]", children: [
2228
2331
  "This profile has ",
2229
2332
  profile.metrics.total_runs,
2230
2333
  " recorded runs. Deleting it will lose all performance metrics."
2231
2334
  ] }),
2232
- /* @__PURE__ */ jsxs5(DialogFooter, { children: [
2233
- /* @__PURE__ */ jsx5(Button2, { variant: "outline", onClick: onClose, children: "Cancel" }),
2234
- /* @__PURE__ */ jsxs5(
2335
+ /* @__PURE__ */ jsxs6(DialogFooter2, { children: [
2336
+ /* @__PURE__ */ jsx6(Button2, { variant: "outline", onClick: onClose, children: "Cancel" }),
2337
+ /* @__PURE__ */ jsxs6(
2235
2338
  Button2,
2236
2339
  {
2237
2340
  variant: "destructive",
2238
2341
  onClick: handleDelete,
2239
2342
  disabled: deleting,
2240
2343
  children: [
2241
- deleting && /* @__PURE__ */ jsx5(Loader22, { className: "mr-2 h-4 w-4 animate-spin" }),
2344
+ deleting && /* @__PURE__ */ jsx6(Loader23, { className: "mr-2 h-4 w-4 animate-spin" }),
2242
2345
  "Delete Profile"
2243
2346
  ]
2244
2347
  }
@@ -2253,35 +2356,35 @@ function ProfileDetailDialog({
2253
2356
  onDuplicate
2254
2357
  }) {
2255
2358
  if (!profile) return null;
2256
- return /* @__PURE__ */ jsx5(Dialog, { open: !!profile, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ jsxs5(DialogContent, { className: "max-w-2xl", children: [
2257
- /* @__PURE__ */ jsxs5(DialogHeader, { children: [
2258
- /* @__PURE__ */ jsxs5("div", { className: "flex items-center gap-2", children: [
2259
- /* @__PURE__ */ jsx5(DialogTitle, { children: profile.name }),
2260
- profile.is_builtin && /* @__PURE__ */ jsx5(Badge2, { variant: "secondary", className: "border-0", children: "Built-in" }),
2261
- profile.is_public && !profile.is_builtin && /* @__PURE__ */ jsx5(Badge2, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)]", children: "Public" })
2359
+ return /* @__PURE__ */ jsx6(Dialog2, { open: !!profile, onOpenChange: (o) => !o && onClose(), children: /* @__PURE__ */ jsxs6(DialogContent2, { className: "max-w-2xl", children: [
2360
+ /* @__PURE__ */ jsxs6(DialogHeader2, { children: [
2361
+ /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-2", children: [
2362
+ /* @__PURE__ */ jsx6(DialogTitle2, { children: profile.name }),
2363
+ profile.is_builtin && /* @__PURE__ */ jsx6(Badge2, { variant: "secondary", className: "border-0", children: "Built-in" }),
2364
+ profile.is_public && !profile.is_builtin && /* @__PURE__ */ jsx6(Badge2, { className: "border border-[var(--surface-info-border)] bg-[var(--surface-info-bg)] text-[var(--surface-info-text)]", children: "Public" })
2262
2365
  ] }),
2263
- profile.description && /* @__PURE__ */ jsx5(DialogDescription, { children: profile.description })
2366
+ profile.description && /* @__PURE__ */ jsx6(DialogDescription2, { children: profile.description })
2264
2367
  ] }),
2265
- /* @__PURE__ */ jsxs5("div", { className: "space-y-4", children: [
2266
- /* @__PURE__ */ jsxs5("div", { className: "grid gap-4 sm:grid-cols-2", children: [
2267
- profile.extends && /* @__PURE__ */ jsxs5("div", { children: [
2268
- /* @__PURE__ */ jsx5("label", { className: "font-medium text-muted-foreground text-xs", children: "Extends" }),
2269
- /* @__PURE__ */ jsx5("p", { className: "text-sm", children: profile.extends })
2368
+ /* @__PURE__ */ jsxs6("div", { className: "space-y-4", children: [
2369
+ /* @__PURE__ */ jsxs6("div", { className: "grid gap-4 sm:grid-cols-2", children: [
2370
+ profile.extends && /* @__PURE__ */ jsxs6("div", { children: [
2371
+ /* @__PURE__ */ jsx6("label", { className: "font-medium text-muted-foreground text-xs", children: "Extends" }),
2372
+ /* @__PURE__ */ jsx6("p", { className: "text-sm", children: profile.extends })
2270
2373
  ] }),
2271
- profile.model && /* @__PURE__ */ jsxs5("div", { children: [
2272
- /* @__PURE__ */ jsx5("label", { className: "font-medium text-muted-foreground text-xs", children: "Model" }),
2273
- /* @__PURE__ */ jsx5("p", { className: "text-sm", children: profile.model })
2374
+ profile.model && /* @__PURE__ */ jsxs6("div", { children: [
2375
+ /* @__PURE__ */ jsx6("label", { className: "font-medium text-muted-foreground text-xs", children: "Model" }),
2376
+ /* @__PURE__ */ jsx6("p", { className: "text-sm", children: profile.model })
2274
2377
  ] })
2275
2378
  ] }),
2276
- profile.tags && profile.tags.length > 0 && /* @__PURE__ */ jsxs5("div", { children: [
2277
- /* @__PURE__ */ jsx5("label", { className: "font-medium text-muted-foreground text-xs", children: "Tags" }),
2278
- /* @__PURE__ */ jsx5("div", { className: "mt-1 flex flex-wrap gap-1", children: profile.tags.map((tag) => /* @__PURE__ */ jsx5(Badge2, { variant: "outline", className: "text-xs", children: tag }, tag)) })
2379
+ profile.tags && profile.tags.length > 0 && /* @__PURE__ */ jsxs6("div", { children: [
2380
+ /* @__PURE__ */ jsx6("label", { className: "font-medium text-muted-foreground text-xs", children: "Tags" }),
2381
+ /* @__PURE__ */ jsx6("div", { className: "mt-1 flex flex-wrap gap-1", children: profile.tags.map((tag) => /* @__PURE__ */ jsx6(Badge2, { variant: "outline", className: "text-xs", children: tag }, tag)) })
2279
2382
  ] }),
2280
- profile.system_prompt && /* @__PURE__ */ jsxs5("div", { children: [
2281
- /* @__PURE__ */ jsx5("label", { className: "font-medium text-muted-foreground text-xs", children: "System Prompt" }),
2282
- /* @__PURE__ */ jsxs5("div", { className: "relative mt-1", children: [
2283
- /* @__PURE__ */ jsx5("pre", { className: "max-h-48 overflow-auto rounded-lg bg-muted p-3 font-mono text-sm", children: profile.system_prompt }),
2284
- /* @__PURE__ */ jsx5(
2383
+ profile.system_prompt && /* @__PURE__ */ jsxs6("div", { children: [
2384
+ /* @__PURE__ */ jsx6("label", { className: "font-medium text-muted-foreground text-xs", children: "System Prompt" }),
2385
+ /* @__PURE__ */ jsxs6("div", { className: "relative mt-1", children: [
2386
+ /* @__PURE__ */ jsx6("pre", { className: "max-h-48 overflow-auto rounded-lg bg-muted p-3 font-mono text-sm", children: profile.system_prompt }),
2387
+ /* @__PURE__ */ jsx6(
2285
2388
  Button2,
2286
2389
  {
2287
2390
  variant: "ghost",
@@ -2289,54 +2392,54 @@ function ProfileDetailDialog({
2289
2392
  className: "absolute top-2 right-2",
2290
2393
  onClick: () => navigator.clipboard.writeText(profile.system_prompt),
2291
2394
  "aria-label": "Copy system prompt",
2292
- children: /* @__PURE__ */ jsx5(Copy, { className: "h-4 w-4" })
2395
+ children: /* @__PURE__ */ jsx6(Copy, { className: "h-4 w-4" })
2293
2396
  }
2294
2397
  )
2295
2398
  ] })
2296
2399
  ] }),
2297
- profile.instructions && profile.instructions.length > 0 && /* @__PURE__ */ jsxs5("div", { children: [
2298
- /* @__PURE__ */ jsx5("label", { className: "font-medium text-muted-foreground text-xs", children: "Instructions" }),
2299
- /* @__PURE__ */ jsx5("ul", { className: "mt-1 space-y-1", children: profile.instructions.map((inst, i) => /* @__PURE__ */ jsxs5("li", { className: "flex items-start gap-2 text-sm", children: [
2300
- /* @__PURE__ */ jsx5(ChevronRight, { className: "mt-0.5 h-4 w-4 text-muted-foreground" }),
2400
+ profile.instructions && profile.instructions.length > 0 && /* @__PURE__ */ jsxs6("div", { children: [
2401
+ /* @__PURE__ */ jsx6("label", { className: "font-medium text-muted-foreground text-xs", children: "Instructions" }),
2402
+ /* @__PURE__ */ jsx6("ul", { className: "mt-1 space-y-1", children: profile.instructions.map((inst, i) => /* @__PURE__ */ jsxs6("li", { className: "flex items-start gap-2 text-sm", children: [
2403
+ /* @__PURE__ */ jsx6(ChevronRight, { className: "mt-0.5 h-4 w-4 text-muted-foreground" }),
2301
2404
  inst
2302
2405
  ] }, i)) })
2303
2406
  ] }),
2304
- profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs5("div", { className: "rounded-lg border border-border p-4", children: [
2305
- /* @__PURE__ */ jsx5("label", { className: "font-medium text-muted-foreground text-xs", children: "Performance Metrics" }),
2306
- /* @__PURE__ */ jsxs5("div", { className: "mt-2 grid grid-cols-2 gap-4 sm:grid-cols-4", children: [
2307
- /* @__PURE__ */ jsxs5("div", { children: [
2308
- /* @__PURE__ */ jsx5("p", { className: "font-medium text-2xl", children: profile.metrics.total_runs }),
2309
- /* @__PURE__ */ jsx5("p", { className: "text-muted-foreground text-xs", children: "Total Runs" })
2407
+ profile.metrics && profile.metrics.total_runs > 0 && /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border p-4", children: [
2408
+ /* @__PURE__ */ jsx6("label", { className: "font-medium text-muted-foreground text-xs", children: "Performance Metrics" }),
2409
+ /* @__PURE__ */ jsxs6("div", { className: "mt-2 grid grid-cols-2 gap-4 sm:grid-cols-4", children: [
2410
+ /* @__PURE__ */ jsxs6("div", { children: [
2411
+ /* @__PURE__ */ jsx6("p", { className: "font-medium text-2xl", children: profile.metrics.total_runs }),
2412
+ /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground text-xs", children: "Total Runs" })
2310
2413
  ] }),
2311
- /* @__PURE__ */ jsxs5("div", { children: [
2312
- /* @__PURE__ */ jsxs5("p", { className: "font-medium text-2xl", children: [
2414
+ /* @__PURE__ */ jsxs6("div", { children: [
2415
+ /* @__PURE__ */ jsxs6("p", { className: "font-medium text-2xl", children: [
2313
2416
  profile.metrics.success_rate.toFixed(0),
2314
2417
  "%"
2315
2418
  ] }),
2316
- /* @__PURE__ */ jsx5("p", { className: "text-muted-foreground text-xs", children: "Success Rate" })
2419
+ /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground text-xs", children: "Success Rate" })
2317
2420
  ] }),
2318
- /* @__PURE__ */ jsxs5("div", { children: [
2319
- /* @__PURE__ */ jsxs5("p", { className: "font-medium text-2xl", children: [
2421
+ /* @__PURE__ */ jsxs6("div", { children: [
2422
+ /* @__PURE__ */ jsxs6("p", { className: "font-medium text-2xl", children: [
2320
2423
  (profile.metrics.avg_duration_ms / 1e3).toFixed(1),
2321
2424
  "s"
2322
2425
  ] }),
2323
- /* @__PURE__ */ jsx5("p", { className: "text-muted-foreground text-xs", children: "Avg Duration" })
2426
+ /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground text-xs", children: "Avg Duration" })
2324
2427
  ] }),
2325
- profile.metrics.avg_tokens_used && /* @__PURE__ */ jsxs5("div", { children: [
2326
- /* @__PURE__ */ jsx5("p", { className: "font-medium text-2xl", children: profile.metrics.avg_tokens_used.toLocaleString() }),
2327
- /* @__PURE__ */ jsx5("p", { className: "text-muted-foreground text-xs", children: "Avg Tokens" })
2428
+ profile.metrics.avg_tokens_used && /* @__PURE__ */ jsxs6("div", { children: [
2429
+ /* @__PURE__ */ jsx6("p", { className: "font-medium text-2xl", children: profile.metrics.avg_tokens_used.toLocaleString() }),
2430
+ /* @__PURE__ */ jsx6("p", { className: "text-muted-foreground text-xs", children: "Avg Tokens" })
2328
2431
  ] })
2329
2432
  ] })
2330
2433
  ] })
2331
2434
  ] }),
2332
- /* @__PURE__ */ jsxs5(DialogFooter, { children: [
2333
- /* @__PURE__ */ jsx5(Button2, { variant: "outline", onClick: onClose, children: "Close" }),
2334
- onDuplicate && /* @__PURE__ */ jsxs5(Button2, { variant: "outline", onClick: onDuplicate, children: [
2335
- /* @__PURE__ */ jsx5(Copy, { className: "mr-2 h-4 w-4" }),
2435
+ /* @__PURE__ */ jsxs6(DialogFooter2, { children: [
2436
+ /* @__PURE__ */ jsx6(Button2, { variant: "outline", onClick: onClose, children: "Close" }),
2437
+ onDuplicate && /* @__PURE__ */ jsxs6(Button2, { variant: "outline", onClick: onDuplicate, children: [
2438
+ /* @__PURE__ */ jsx6(Copy, { className: "mr-2 h-4 w-4" }),
2336
2439
  "Duplicate"
2337
2440
  ] }),
2338
- onEdit && /* @__PURE__ */ jsxs5(Button2, { onClick: onEdit, children: [
2339
- /* @__PURE__ */ jsx5(Edit2, { className: "mr-2 h-4 w-4" }),
2441
+ onEdit && /* @__PURE__ */ jsxs6(Button2, { onClick: onEdit, children: [
2442
+ /* @__PURE__ */ jsx6(Edit2, { className: "mr-2 h-4 w-4" }),
2340
2443
  "Edit"
2341
2444
  ] })
2342
2445
  ] })
@@ -2344,33 +2447,104 @@ function ProfileDetailDialog({
2344
2447
  }
2345
2448
 
2346
2449
  // src/pages/secrets-page.tsx
2347
- import * as React5 from "react";
2348
- import { Lock, Plus as Plus3, Trash2 as Trash23, Eye, EyeOff, AlertCircle as AlertCircle2, Key, Shield, CheckCircle, Users, ArrowRight } from "lucide-react";
2450
+ import * as React6 from "react";
2451
+ import { Lock, Plus as Plus3, Trash2 as Trash23, Eye, EyeOff, AlertCircle as AlertCircle2, Key, Shield, CheckCircle, Users, ArrowRight, Upload } from "lucide-react";
2349
2452
  import {
2350
- Dialog as Dialog2,
2351
- DialogContent as DialogContent2,
2352
- DialogDescription as DialogDescription2,
2353
- DialogFooter as DialogFooter2,
2354
- DialogHeader as DialogHeader2,
2355
- DialogTitle as DialogTitle2
2453
+ Dialog as Dialog3,
2454
+ DialogContent as DialogContent3,
2455
+ DialogDescription as DialogDescription3,
2456
+ DialogFooter as DialogFooter3,
2457
+ DialogHeader as DialogHeader3,
2458
+ DialogTitle as DialogTitle3
2356
2459
  } from "@tangle-network/ui/primitives";
2357
- import { jsx as jsx6, jsxs as jsxs6 } from "react/jsx-runtime";
2460
+
2461
+ // src/pages/env-importer.ts
2462
+ var NORMALIZE_RE = /[^A-Z0-9_]/g;
2463
+ function normalizeKey(rawKey) {
2464
+ return rawKey.toUpperCase().replace(NORMALIZE_RE, "_");
2465
+ }
2466
+ function stripMatchingQuotes(value) {
2467
+ if (value.length >= 2) {
2468
+ const quote = value[0];
2469
+ if ((quote === '"' || quote === "'") && value[value.length - 1] === quote) {
2470
+ const inner = value.slice(1, -1);
2471
+ if (!inner.includes(quote)) {
2472
+ return inner;
2473
+ }
2474
+ }
2475
+ }
2476
+ return value;
2477
+ }
2478
+ function parseEnvText(text) {
2479
+ const rows = [];
2480
+ const errors = [];
2481
+ const lines = text.split(/\r?\n/);
2482
+ for (let i = 0; i < lines.length; i++) {
2483
+ const lineNumber = i + 1;
2484
+ const rawLine = lines[i];
2485
+ const trimmed = rawLine.trim();
2486
+ if (trimmed === "" || trimmed.startsWith("#")) continue;
2487
+ let rest = trimmed;
2488
+ const exportMatch = /^export\s+/.exec(rest);
2489
+ if (exportMatch) rest = rest.slice(exportMatch[0].length);
2490
+ const eqIdx = rest.indexOf("=");
2491
+ if (eqIdx === -1) {
2492
+ errors.push({ lineNumber, message: "Missing '=' separator", rawLine });
2493
+ continue;
2494
+ }
2495
+ const rawKey = rest.slice(0, eqIdx).trim();
2496
+ const rawValue = rest.slice(eqIdx + 1).trim();
2497
+ if (rawKey === "") {
2498
+ errors.push({ lineNumber, message: "Missing key before '='", rawLine });
2499
+ continue;
2500
+ }
2501
+ const key = normalizeKey(rawKey);
2502
+ if (!/[A-Z0-9]/.test(key)) {
2503
+ errors.push({
2504
+ lineNumber,
2505
+ message: "Key has no valid characters (letters or digits)",
2506
+ rawLine
2507
+ });
2508
+ continue;
2509
+ }
2510
+ rows.push({
2511
+ key,
2512
+ rawKey,
2513
+ value: stripMatchingQuotes(rawValue),
2514
+ lineNumber
2515
+ });
2516
+ }
2517
+ return { rows, errors };
2518
+ }
2519
+
2520
+ // src/pages/secrets-page.tsx
2521
+ import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
2522
+ var MAX_IMPORT_FILE_BYTES = 256 * 1024;
2358
2523
  function SecretsPage({ apiClient, className, teamSecretsHint }) {
2359
- const [secrets, setSecrets] = React5.useState([]);
2360
- const [loading, setLoading] = React5.useState(true);
2361
- const [error, setError] = React5.useState(null);
2362
- const [isCreateOpen, setIsCreateOpen] = React5.useState(false);
2363
- const [newName, setNewName] = React5.useState("");
2364
- const [newValue, setNewValue] = React5.useState("");
2365
- const [showValue, setShowValue] = React5.useState(false);
2366
- const [isCreating, setIsCreating] = React5.useState(false);
2367
- const [createError, setCreateError] = React5.useState(null);
2368
- const [deleteTarget, setDeleteTarget] = React5.useState(null);
2369
- const [isDeleting, setIsDeleting] = React5.useState(false);
2370
- const apiRef = React5.useRef(apiClient);
2524
+ const [secrets, setSecrets] = React6.useState([]);
2525
+ const [loading, setLoading] = React6.useState(true);
2526
+ const [error, setError] = React6.useState(null);
2527
+ const [isCreateOpen, setIsCreateOpen] = React6.useState(false);
2528
+ const [newName, setNewName] = React6.useState("");
2529
+ const [newValue, setNewValue] = React6.useState("");
2530
+ const [showValue, setShowValue] = React6.useState(false);
2531
+ const [isCreating, setIsCreating] = React6.useState(false);
2532
+ const [createError, setCreateError] = React6.useState(null);
2533
+ const [deleteTarget, setDeleteTarget] = React6.useState(null);
2534
+ const [isDeleting, setIsDeleting] = React6.useState(false);
2535
+ const [isImportOpen, setIsImportOpen] = React6.useState(false);
2536
+ const [importText, setImportText] = React6.useState("");
2537
+ const [importResult, setImportResult] = React6.useState(null);
2538
+ const [rowStatus, setRowStatus] = React6.useState([]);
2539
+ const [rowMessages, setRowMessages] = React6.useState([]);
2540
+ const [isImportSaving, setIsImportSaving] = React6.useState(false);
2541
+ const [showImportValues, setShowImportValues] = React6.useState(false);
2542
+ const [importFileError, setImportFileError] = React6.useState(null);
2543
+ const fileInputRef = React6.useRef(null);
2544
+ const apiRef = React6.useRef(apiClient);
2371
2545
  apiRef.current = apiClient;
2372
- const loadGenRef = React5.useRef(0);
2373
- const loadSecrets = React5.useCallback(async (showSpinner = true) => {
2546
+ const loadGenRef = React6.useRef(0);
2547
+ const loadSecrets = React6.useCallback(async (showSpinner = true) => {
2374
2548
  const gen = ++loadGenRef.current;
2375
2549
  try {
2376
2550
  if (showSpinner) setLoading(true);
@@ -2385,7 +2559,7 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2385
2559
  if (gen === loadGenRef.current) setLoading(false);
2386
2560
  }
2387
2561
  }, []);
2388
- React5.useEffect(() => {
2562
+ React6.useEffect(() => {
2389
2563
  loadSecrets();
2390
2564
  }, [loadSecrets]);
2391
2565
  const handleCreate = async () => {
@@ -2417,6 +2591,100 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2417
2591
  setIsDeleting(false);
2418
2592
  }
2419
2593
  };
2594
+ const resetImportState = () => {
2595
+ setImportText("");
2596
+ setImportResult(null);
2597
+ setRowStatus([]);
2598
+ setRowMessages([]);
2599
+ setShowImportValues(false);
2600
+ setImportFileError(null);
2601
+ if (fileInputRef.current) fileInputRef.current.value = "";
2602
+ };
2603
+ const runParse = (text) => {
2604
+ const result = parseEnvText(text);
2605
+ setImportResult(result);
2606
+ setRowStatus(new Array(result.rows.length).fill("idle"));
2607
+ setRowMessages(new Array(result.rows.length).fill(""));
2608
+ };
2609
+ const handleParse = () => {
2610
+ runParse(importText);
2611
+ };
2612
+ const handleImportFile = async (file) => {
2613
+ if (!file) return;
2614
+ setImportFileError(null);
2615
+ if (file.size > MAX_IMPORT_FILE_BYTES) {
2616
+ setImportFileError(`File is too large (${Math.round(file.size / 1024)} KiB). Limit is ${MAX_IMPORT_FILE_BYTES / 1024} KiB.`);
2617
+ if (fileInputRef.current) fileInputRef.current.value = "";
2618
+ return;
2619
+ }
2620
+ const text = await file.text();
2621
+ setImportText(text);
2622
+ runParse(text);
2623
+ };
2624
+ const updateRowKey = (index, next) => {
2625
+ setImportResult((prev) => {
2626
+ if (!prev) return prev;
2627
+ const rows = prev.rows.slice();
2628
+ rows[index] = { ...rows[index], key: next.toUpperCase().replace(/[^A-Z0-9_]/g, "_") };
2629
+ return { ...prev, rows };
2630
+ });
2631
+ };
2632
+ const updateRowValue = (index, next) => {
2633
+ setImportResult((prev) => {
2634
+ if (!prev) return prev;
2635
+ const rows = prev.rows.slice();
2636
+ rows[index] = { ...rows[index], value: next };
2637
+ return { ...prev, rows };
2638
+ });
2639
+ };
2640
+ const removeImportRow = (index) => {
2641
+ setImportResult((prev) => {
2642
+ if (!prev) return prev;
2643
+ const rows = prev.rows.slice();
2644
+ rows.splice(index, 1);
2645
+ return { ...prev, rows };
2646
+ });
2647
+ setRowStatus((prev) => {
2648
+ const next = prev.slice();
2649
+ next.splice(index, 1);
2650
+ return next;
2651
+ });
2652
+ setRowMessages((prev) => {
2653
+ const next = prev.slice();
2654
+ next.splice(index, 1);
2655
+ return next;
2656
+ });
2657
+ };
2658
+ const importRows = importResult?.rows ?? [];
2659
+ const hasImportErrors = !!(importResult && importResult.errors.length > 0);
2660
+ const importSaveDisabled = isImportSaving || importRows.length === 0 || hasImportErrors || importRows.some((r) => !r.key || !/[A-Z0-9]/.test(r.key) || !r.value.trim());
2661
+ const handleImportSave = async () => {
2662
+ if (!importResult || importSaveDisabled) return;
2663
+ const rows = importResult.rows;
2664
+ setIsImportSaving(true);
2665
+ const statuses = new Array(rows.length).fill("idle");
2666
+ const messages = new Array(rows.length).fill("");
2667
+ try {
2668
+ for (let i = 0; i < rows.length; i++) {
2669
+ try {
2670
+ await apiRef.current.createSecret(rows[i].key, rows[i].value);
2671
+ statuses[i] = "success";
2672
+ } catch (err) {
2673
+ statuses[i] = "error";
2674
+ messages[i] = err instanceof Error ? err.message : "Failed to create secret";
2675
+ }
2676
+ }
2677
+ setRowStatus(statuses);
2678
+ setRowMessages(messages);
2679
+ await loadSecrets(false);
2680
+ if (statuses.every((s) => s === "success")) {
2681
+ setIsImportOpen(false);
2682
+ resetImportState();
2683
+ }
2684
+ } finally {
2685
+ setIsImportSaving(false);
2686
+ }
2687
+ };
2420
2688
  const formatDate = (dateStr) => {
2421
2689
  try {
2422
2690
  const ts = /^\d+$/.test(dateStr) ? Number(dateStr) : dateStr;
@@ -2427,36 +2695,50 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2427
2695
  return dateStr;
2428
2696
  }
2429
2697
  };
2430
- return /* @__PURE__ */ jsxs6("div", { className: cn("mx-auto w-full max-w-7xl space-y-8", className), children: [
2431
- /* @__PURE__ */ jsxs6("div", { className: "flex flex-col gap-4 md:flex-row md:items-end md:justify-between", children: [
2432
- /* @__PURE__ */ jsxs6("div", { children: [
2433
- /* @__PURE__ */ jsx6("h1", { className: "font-display text-3xl font-extrabold tracking-tight text-foreground", children: "Environment Secrets" }),
2434
- /* @__PURE__ */ jsx6("p", { className: "mt-1 text-sm text-muted-foreground", children: "Secrets are securely stored and automatically exposed as environment variables across all your sandboxes." })
2698
+ return /* @__PURE__ */ jsxs7("div", { className: cn("mx-auto w-full max-w-7xl space-y-8", className), children: [
2699
+ /* @__PURE__ */ jsxs7("div", { className: "flex flex-col gap-4 md:flex-row md:items-end md:justify-between", children: [
2700
+ /* @__PURE__ */ jsxs7("div", { children: [
2701
+ /* @__PURE__ */ jsx7("h1", { className: "font-display text-3xl font-extrabold tracking-tight text-foreground", children: "Environment Secrets" }),
2702
+ /* @__PURE__ */ jsx7("p", { className: "mt-1 text-sm text-muted-foreground", children: "Secrets are securely stored and automatically exposed as environment variables across all your sandboxes." })
2435
2703
  ] }),
2436
- /* @__PURE__ */ jsxs6(
2437
- "button",
2438
- {
2439
- type: "button",
2440
- onClick: () => setIsCreateOpen(true),
2441
- className: "inline-flex items-center gap-2 rounded-lg bg-[var(--btn-primary-bg)] border border-[var(--border-accent,transparent)] px-5 py-2.5 text-sm font-semibold text-[var(--btn-primary-text)] hover:bg-[var(--btn-primary-hover)] transition-colors active:scale-[0.97]",
2442
- children: [
2443
- /* @__PURE__ */ jsx6(Plus3, { className: "h-4 w-4" }),
2444
- "New Secret"
2445
- ]
2446
- }
2447
- )
2704
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
2705
+ /* @__PURE__ */ jsxs7(
2706
+ "button",
2707
+ {
2708
+ type: "button",
2709
+ onClick: () => setIsImportOpen(true),
2710
+ className: "inline-flex items-center gap-2 rounded-lg border border-border bg-card px-4 py-2.5 text-sm font-semibold text-foreground hover:bg-muted transition-colors active:scale-[0.97]",
2711
+ children: [
2712
+ /* @__PURE__ */ jsx7(Upload, { className: "h-4 w-4" }),
2713
+ "Import .env"
2714
+ ]
2715
+ }
2716
+ ),
2717
+ /* @__PURE__ */ jsxs7(
2718
+ "button",
2719
+ {
2720
+ type: "button",
2721
+ onClick: () => setIsCreateOpen(true),
2722
+ className: "inline-flex items-center gap-2 rounded-lg bg-[var(--btn-primary-bg)] border border-[var(--border-accent,transparent)] px-5 py-2.5 text-sm font-semibold text-[var(--btn-primary-text)] hover:bg-[var(--btn-primary-hover)] transition-colors active:scale-[0.97]",
2723
+ children: [
2724
+ /* @__PURE__ */ jsx7(Plus3, { className: "h-4 w-4" }),
2725
+ "New Secret"
2726
+ ]
2727
+ }
2728
+ )
2729
+ ] })
2448
2730
  ] }),
2449
- teamSecretsHint && /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 rounded-lg border border-border bg-[var(--accent-surface-soft)]/40 px-4 py-3", children: [
2450
- /* @__PURE__ */ jsx6(Users, { className: "h-5 w-5 shrink-0 text-[var(--accent-text)]", "aria-hidden": "true" }),
2451
- /* @__PURE__ */ jsxs6("div", { className: "flex-1 text-sm", children: [
2452
- /* @__PURE__ */ jsx6("p", { className: "font-semibold text-foreground", children: "Setting up secrets for a team?" }),
2453
- /* @__PURE__ */ jsxs6("p", { className: "mt-0.5 text-muted-foreground text-xs", children: [
2731
+ teamSecretsHint && /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3 rounded-lg border border-border bg-[var(--accent-surface-soft)]/40 px-4 py-3", children: [
2732
+ /* @__PURE__ */ jsx7(Users, { className: "h-5 w-5 shrink-0 text-[var(--accent-text)]", "aria-hidden": "true" }),
2733
+ /* @__PURE__ */ jsxs7("div", { className: "flex-1 text-sm", children: [
2734
+ /* @__PURE__ */ jsx7("p", { className: "font-semibold text-foreground", children: "Setting up secrets for a team?" }),
2735
+ /* @__PURE__ */ jsxs7("p", { className: "mt-0.5 text-muted-foreground text-xs", children: [
2454
2736
  "Secrets here are ",
2455
- /* @__PURE__ */ jsx6("strong", { children: "personal" }),
2737
+ /* @__PURE__ */ jsx7("strong", { children: "personal" }),
2456
2738
  " \u2014 only available in sandboxes you create. To share credentials with teammates, configure them on the team page instead."
2457
2739
  ] })
2458
2740
  ] }),
2459
- /* @__PURE__ */ jsxs6(
2741
+ /* @__PURE__ */ jsxs7(
2460
2742
  "button",
2461
2743
  {
2462
2744
  type: "button",
@@ -2464,24 +2746,24 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2464
2746
  className: "inline-flex shrink-0 items-center gap-1 rounded-md border border-border bg-card px-3 py-1.5 text-xs font-semibold text-foreground hover:bg-muted transition-colors",
2465
2747
  children: [
2466
2748
  teamSecretsHint.label ?? "Manage team secrets",
2467
- /* @__PURE__ */ jsx6(ArrowRight, { className: "h-3 w-3", "aria-hidden": "true" })
2749
+ /* @__PURE__ */ jsx7(ArrowRight, { className: "h-3 w-3", "aria-hidden": "true" })
2468
2750
  ]
2469
2751
  }
2470
2752
  )
2471
2753
  ] }),
2472
- /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-4", children: [
2473
- /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
2474
- /* @__PURE__ */ jsx6("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Total Active Secrets" }),
2475
- /* @__PURE__ */ jsx6("div", { className: "mt-2 flex items-baseline gap-2", children: /* @__PURE__ */ jsx6("span", { className: "font-display text-2xl font-extrabold text-foreground", children: secrets.length }) })
2754
+ /* @__PURE__ */ jsxs7("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-4", children: [
2755
+ /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
2756
+ /* @__PURE__ */ jsx7("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Total Active Secrets" }),
2757
+ /* @__PURE__ */ jsx7("div", { className: "mt-2 flex items-baseline gap-2", children: /* @__PURE__ */ jsx7("span", { className: "font-display text-2xl font-extrabold text-foreground", children: secrets.length }) })
2476
2758
  ] }),
2477
- /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
2478
- /* @__PURE__ */ jsx6("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Status" }),
2479
- /* @__PURE__ */ jsxs6("div", { className: "mt-2 flex items-center gap-2", children: [
2480
- /* @__PURE__ */ jsx6(CheckCircle, { className: "h-4 w-4 text-[var(--surface-success-text,#047857)]" }),
2481
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-semibold text-[var(--surface-success-text,#047857)]", children: "Encrypted" })
2759
+ /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
2760
+ /* @__PURE__ */ jsx7("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Status" }),
2761
+ /* @__PURE__ */ jsxs7("div", { className: "mt-2 flex items-center gap-2", children: [
2762
+ /* @__PURE__ */ jsx7(CheckCircle, { className: "h-4 w-4 text-[var(--surface-success-text,#047857)]" }),
2763
+ /* @__PURE__ */ jsx7("span", { className: "text-sm font-semibold text-[var(--surface-success-text,#047857)]", children: "Encrypted" })
2482
2764
  ] })
2483
2765
  ] }),
2484
- /* @__PURE__ */ jsx6(
2766
+ /* @__PURE__ */ jsx7(
2485
2767
  InfoPanel,
2486
2768
  {
2487
2769
  className: "md:col-span-2",
@@ -2491,11 +2773,11 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2491
2773
  }
2492
2774
  )
2493
2775
  ] }),
2494
- error && /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-4 flex items-center gap-3", children: [
2495
- /* @__PURE__ */ jsx6(AlertCircle2, { className: "h-5 w-5 text-destructive shrink-0" }),
2496
- /* @__PURE__ */ jsx6("p", { className: "text-destructive text-sm font-medium", children: error })
2776
+ error && /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-destructive/30 bg-destructive/10 p-4 flex items-center gap-3", children: [
2777
+ /* @__PURE__ */ jsx7(AlertCircle2, { className: "h-5 w-5 text-destructive shrink-0" }),
2778
+ /* @__PURE__ */ jsx7("p", { className: "text-destructive text-sm font-medium", children: error })
2497
2779
  ] }),
2498
- /* @__PURE__ */ jsx6(Dialog2, { open: isCreateOpen, onOpenChange: (open) => {
2780
+ /* @__PURE__ */ jsx7(Dialog3, { open: isCreateOpen, onOpenChange: (open) => {
2499
2781
  if (!open) {
2500
2782
  setIsCreateOpen(false);
2501
2783
  setNewName("");
@@ -2503,12 +2785,12 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2503
2785
  setCreateError(null);
2504
2786
  setShowValue(false);
2505
2787
  }
2506
- }, children: /* @__PURE__ */ jsxs6(DialogContent2, { className: "max-w-md", children: [
2507
- /* @__PURE__ */ jsxs6(DialogHeader2, { children: [
2508
- /* @__PURE__ */ jsx6(DialogTitle2, { children: "Create Secret" }),
2509
- /* @__PURE__ */ jsx6(DialogDescription2, { children: "Secrets are automatically exposed as environment variables across all your new sandboxes." })
2788
+ }, children: /* @__PURE__ */ jsxs7(DialogContent3, { className: "max-w-md", children: [
2789
+ /* @__PURE__ */ jsxs7(DialogHeader3, { children: [
2790
+ /* @__PURE__ */ jsx7(DialogTitle3, { children: "Create Secret" }),
2791
+ /* @__PURE__ */ jsx7(DialogDescription3, { children: "Secrets are automatically exposed as environment variables across all your new sandboxes." })
2510
2792
  ] }),
2511
- /* @__PURE__ */ jsxs6(
2793
+ /* @__PURE__ */ jsxs7(
2512
2794
  "form",
2513
2795
  {
2514
2796
  onSubmit: (e) => {
@@ -2517,9 +2799,9 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2517
2799
  },
2518
2800
  className: "space-y-4",
2519
2801
  children: [
2520
- /* @__PURE__ */ jsxs6("div", { children: [
2521
- /* @__PURE__ */ jsx6("label", { htmlFor: "secret-name", className: "block text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Name" }),
2522
- /* @__PURE__ */ jsx6(
2802
+ /* @__PURE__ */ jsxs7("div", { children: [
2803
+ /* @__PURE__ */ jsx7("label", { htmlFor: "secret-name", className: "block text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Name" }),
2804
+ /* @__PURE__ */ jsx7(
2523
2805
  "input",
2524
2806
  {
2525
2807
  id: "secret-name",
@@ -2533,10 +2815,10 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2533
2815
  }
2534
2816
  )
2535
2817
  ] }),
2536
- /* @__PURE__ */ jsxs6("div", { children: [
2537
- /* @__PURE__ */ jsx6("label", { htmlFor: "secret-value", className: "block text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Value" }),
2538
- /* @__PURE__ */ jsxs6("div", { className: "relative", children: [
2539
- /* @__PURE__ */ jsx6(
2818
+ /* @__PURE__ */ jsxs7("div", { children: [
2819
+ /* @__PURE__ */ jsx7("label", { htmlFor: "secret-value", className: "block text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Value" }),
2820
+ /* @__PURE__ */ jsxs7("div", { className: "relative", children: [
2821
+ /* @__PURE__ */ jsx7(
2540
2822
  "input",
2541
2823
  {
2542
2824
  id: "secret-value",
@@ -2549,26 +2831,26 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2549
2831
  className: "w-full rounded-md border border-border bg-card px-3 py-2.5 pr-10 text-sm font-mono text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2550
2832
  }
2551
2833
  ),
2552
- /* @__PURE__ */ jsx6(
2834
+ /* @__PURE__ */ jsx7(
2553
2835
  "button",
2554
2836
  {
2555
2837
  type: "button",
2556
2838
  onClick: () => setShowValue(!showValue),
2557
2839
  className: "absolute right-2 top-1/2 -translate-y-1/2 p-1 text-muted-foreground hover:text-foreground",
2558
2840
  "aria-label": showValue ? "Hide value" : "Show value",
2559
- children: showValue ? /* @__PURE__ */ jsx6(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx6(Eye, { className: "h-4 w-4" })
2841
+ children: showValue ? /* @__PURE__ */ jsx7(EyeOff, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx7(Eye, { className: "h-4 w-4" })
2560
2842
  }
2561
2843
  )
2562
2844
  ] }),
2563
- /* @__PURE__ */ jsx6("p", { className: "mt-1.5 text-xs text-muted-foreground", children: "This value cannot be retrieved after creation." })
2845
+ /* @__PURE__ */ jsx7("p", { className: "mt-1.5 text-xs text-muted-foreground", children: "This value cannot be retrieved after creation." })
2564
2846
  ] }),
2565
- /* @__PURE__ */ jsx6("button", { type: "submit", className: "hidden", tabIndex: -1, "aria-hidden": "true", children: "Submit" })
2847
+ /* @__PURE__ */ jsx7("button", { type: "submit", className: "hidden", tabIndex: -1, "aria-hidden": "true", children: "Submit" })
2566
2848
  ]
2567
2849
  }
2568
2850
  ),
2569
- createError && /* @__PURE__ */ jsx6("p", { className: "mt-3 text-sm text-destructive", children: createError }),
2570
- /* @__PURE__ */ jsxs6(DialogFooter2, { children: [
2571
- /* @__PURE__ */ jsx6(
2851
+ createError && /* @__PURE__ */ jsx7("p", { className: "mt-3 text-sm text-destructive", children: createError }),
2852
+ /* @__PURE__ */ jsxs7(DialogFooter3, { children: [
2853
+ /* @__PURE__ */ jsx7(
2572
2854
  "button",
2573
2855
  {
2574
2856
  type: "button",
@@ -2582,7 +2864,7 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2582
2864
  children: "Cancel"
2583
2865
  }
2584
2866
  ),
2585
- /* @__PURE__ */ jsx6(
2867
+ /* @__PURE__ */ jsx7(
2586
2868
  "button",
2587
2869
  {
2588
2870
  type: "button",
@@ -2594,19 +2876,204 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2594
2876
  )
2595
2877
  ] })
2596
2878
  ] }) }),
2597
- /* @__PURE__ */ jsx6(Dialog2, { open: !!deleteTarget, onOpenChange: (open) => {
2879
+ /* @__PURE__ */ jsx7(Dialog3, { open: isImportOpen, onOpenChange: (open) => {
2880
+ if (!open && !isImportSaving) {
2881
+ setIsImportOpen(false);
2882
+ resetImportState();
2883
+ }
2884
+ }, children: /* @__PURE__ */ jsxs7(DialogContent3, { className: "max-w-2xl", children: [
2885
+ /* @__PURE__ */ jsxs7(DialogHeader3, { children: [
2886
+ /* @__PURE__ */ jsx7(DialogTitle3, { children: "Import Secrets" }),
2887
+ /* @__PURE__ */ jsxs7(DialogDescription3, { children: [
2888
+ "Upload a ",
2889
+ /* @__PURE__ */ jsx7("span", { className: "font-mono", children: ".env" }),
2890
+ " file or paste key-value pairs. Review and edit each row before saving."
2891
+ ] })
2892
+ ] }),
2893
+ /* @__PURE__ */ jsxs7("div", { className: "space-y-4", children: [
2894
+ /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
2895
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-2", children: [
2896
+ /* @__PURE__ */ jsx7(
2897
+ "input",
2898
+ {
2899
+ ref: fileInputRef,
2900
+ type: "file",
2901
+ accept: ".env,.txt,text/plain",
2902
+ "aria-label": "Upload .env file",
2903
+ className: "hidden",
2904
+ onChange: (e) => handleImportFile(e.target.files?.[0] ?? null)
2905
+ }
2906
+ ),
2907
+ /* @__PURE__ */ jsxs7(
2908
+ "button",
2909
+ {
2910
+ type: "button",
2911
+ onClick: () => fileInputRef.current?.click(),
2912
+ className: "inline-flex items-center gap-2 rounded-md border border-border bg-card px-3 py-2 text-xs font-semibold text-foreground hover:bg-muted transition-colors",
2913
+ children: [
2914
+ /* @__PURE__ */ jsx7(Upload, { className: "h-3.5 w-3.5" }),
2915
+ "Choose .env file"
2916
+ ]
2917
+ }
2918
+ ),
2919
+ /* @__PURE__ */ jsx7(
2920
+ "button",
2921
+ {
2922
+ type: "button",
2923
+ onClick: handleParse,
2924
+ disabled: !importText.trim(),
2925
+ className: "rounded-md bg-[var(--btn-primary-bg)] px-3 py-2 text-xs font-bold text-[var(--btn-primary-text)] hover:bg-[var(--btn-primary-hover)] transition-colors disabled:opacity-50",
2926
+ children: "Parse"
2927
+ }
2928
+ )
2929
+ ] }),
2930
+ /* @__PURE__ */ jsx7(
2931
+ "textarea",
2932
+ {
2933
+ "aria-label": "Paste .env contents",
2934
+ placeholder: "Paste .env contents, e.g.\nAPI_KEY=abc123\n# comment\nexport DB_URL=postgres://localhost",
2935
+ value: importText,
2936
+ onChange: (e) => setImportText(e.target.value),
2937
+ rows: 6,
2938
+ spellCheck: false,
2939
+ className: "w-full rounded-md border border-border bg-card px-3 py-2 font-mono text-xs text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-ring"
2940
+ }
2941
+ ),
2942
+ /* @__PURE__ */ jsxs7("p", { className: "text-[11px] text-muted-foreground", children: [
2943
+ "Lines starting with ",
2944
+ /* @__PURE__ */ jsx7("span", { className: "font-mono", children: "#" }),
2945
+ " are comments. Text after ",
2946
+ /* @__PURE__ */ jsx7("span", { className: "font-mono", children: "#" }),
2947
+ " inside a value is preserved."
2948
+ ] }),
2949
+ importFileError && /* @__PURE__ */ jsx7("p", { className: "text-xs text-destructive", role: "alert", children: importFileError })
2950
+ ] }),
2951
+ importResult && importResult.errors.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "rounded-md border border-destructive/30 bg-destructive/10 p-3", children: [
2952
+ /* @__PURE__ */ jsxs7("p", { className: "mb-1 text-xs font-bold uppercase tracking-widest text-destructive", children: [
2953
+ importResult.errors.length,
2954
+ " line",
2955
+ importResult.errors.length !== 1 ? "s" : "",
2956
+ " could not be parsed"
2957
+ ] }),
2958
+ /* @__PURE__ */ jsx7("ul", { className: "space-y-1", children: importResult.errors.map((err) => /* @__PURE__ */ jsxs7("li", { className: "text-xs text-destructive", role: "alert", children: [
2959
+ "Line ",
2960
+ err.lineNumber,
2961
+ ": ",
2962
+ err.message
2963
+ ] }, err.lineNumber)) })
2964
+ ] }),
2965
+ importResult && importResult.rows.length > 0 && /* @__PURE__ */ jsxs7("div", { className: "space-y-2", children: [
2966
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center justify-between", children: [
2967
+ /* @__PURE__ */ jsxs7("p", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: [
2968
+ importResult.rows.length,
2969
+ " secret",
2970
+ importResult.rows.length !== 1 ? "s" : "",
2971
+ " ready"
2972
+ ] }),
2973
+ /* @__PURE__ */ jsxs7(
2974
+ "button",
2975
+ {
2976
+ type: "button",
2977
+ onClick: () => setShowImportValues((s) => !s),
2978
+ className: "inline-flex items-center gap-1 text-xs font-semibold text-muted-foreground hover:text-foreground",
2979
+ children: [
2980
+ showImportValues ? /* @__PURE__ */ jsx7(EyeOff, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx7(Eye, { className: "h-3.5 w-3.5" }),
2981
+ showImportValues ? "Hide values" : "Show values"
2982
+ ]
2983
+ }
2984
+ )
2985
+ ] }),
2986
+ /* @__PURE__ */ jsx7("div", { className: "max-h-64 space-y-2 overflow-y-auto", children: importResult.rows.map((row, index) => {
2987
+ const status = rowStatus[index];
2988
+ const message = rowMessages[index];
2989
+ return /* @__PURE__ */ jsxs7("div", { className: "flex items-start gap-2 rounded-md border border-border bg-muted/30 p-2", children: [
2990
+ /* @__PURE__ */ jsx7(
2991
+ "input",
2992
+ {
2993
+ type: "text",
2994
+ "aria-label": `Import row ${index + 1} key`,
2995
+ value: row.key,
2996
+ onChange: (e) => updateRowKey(index, e.target.value),
2997
+ disabled: isImportSaving,
2998
+ className: "w-2/5 rounded border border-border bg-card px-2 py-1.5 font-mono text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:opacity-60"
2999
+ }
3000
+ ),
3001
+ /* @__PURE__ */ jsx7(
3002
+ "input",
3003
+ {
3004
+ type: showImportValues ? "text" : "password",
3005
+ "aria-label": `Import row ${index + 1} value`,
3006
+ value: row.value,
3007
+ onChange: (e) => updateRowValue(index, e.target.value),
3008
+ disabled: isImportSaving,
3009
+ className: "w-2/5 rounded border border-border bg-card px-2 py-1.5 font-mono text-xs text-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:opacity-60"
3010
+ }
3011
+ ),
3012
+ /* @__PURE__ */ jsxs7("div", { className: "flex w-1/5 flex-col items-end gap-1", children: [
3013
+ status === "success" && /* @__PURE__ */ jsxs7("span", { className: "inline-flex items-center gap-1 text-xs font-semibold text-[var(--surface-success-text,#047857)]", children: [
3014
+ /* @__PURE__ */ jsx7(CheckCircle, { className: "h-3.5 w-3.5" }),
3015
+ " Saved"
3016
+ ] }),
3017
+ status === "error" && /* @__PURE__ */ jsx7("span", { className: "text-right text-xs font-semibold text-destructive", title: message, children: message || "Failed" }),
3018
+ /* @__PURE__ */ jsxs7(
3019
+ "button",
3020
+ {
3021
+ type: "button",
3022
+ onClick: () => removeImportRow(index),
3023
+ disabled: isImportSaving,
3024
+ "aria-label": `Remove import row ${index + 1}`,
3025
+ className: "inline-flex items-center gap-1 text-xs font-semibold text-muted-foreground hover:text-destructive disabled:opacity-50 disabled:pointer-events-none",
3026
+ children: [
3027
+ /* @__PURE__ */ jsx7(Trash23, { className: "h-3.5 w-3.5" }),
3028
+ " Remove"
3029
+ ]
3030
+ }
3031
+ )
3032
+ ] })
3033
+ ] }, `${row.lineNumber}-${index}`);
3034
+ }) })
3035
+ ] }),
3036
+ importResult && importResult.rows.length === 0 && importResult.errors.length === 0 && /* @__PURE__ */ jsx7("p", { className: "text-xs text-muted-foreground", children: "No secrets found. Add at least one KEY=value line." })
3037
+ ] }),
3038
+ /* @__PURE__ */ jsxs7(DialogFooter3, { children: [
3039
+ /* @__PURE__ */ jsx7(
3040
+ "button",
3041
+ {
3042
+ type: "button",
3043
+ onClick: () => {
3044
+ setIsImportOpen(false);
3045
+ resetImportState();
3046
+ },
3047
+ disabled: isImportSaving,
3048
+ className: "rounded-md border border-border bg-card px-4 py-2 text-sm font-medium text-foreground hover:bg-muted transition-colors disabled:opacity-50 disabled:pointer-events-none",
3049
+ children: "Cancel"
3050
+ }
3051
+ ),
3052
+ /* @__PURE__ */ jsx7(
3053
+ "button",
3054
+ {
3055
+ type: "button",
3056
+ onClick: handleImportSave,
3057
+ disabled: importSaveDisabled,
3058
+ className: "rounded-md bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-bold text-[var(--btn-primary-text)] hover:bg-[var(--btn-primary-hover)] transition-colors disabled:opacity-50 active:scale-[0.97]",
3059
+ children: isImportSaving ? "Importing..." : importRows.length > 0 ? `Import ${importRows.length} secret${importRows.length === 1 ? "" : "s"}` : "Import secrets"
3060
+ }
3061
+ )
3062
+ ] })
3063
+ ] }) }),
3064
+ /* @__PURE__ */ jsx7(Dialog3, { open: !!deleteTarget, onOpenChange: (open) => {
2598
3065
  if (!open) setDeleteTarget(null);
2599
- }, children: /* @__PURE__ */ jsxs6(DialogContent2, { className: "max-w-sm", children: [
2600
- /* @__PURE__ */ jsxs6(DialogHeader2, { children: [
2601
- /* @__PURE__ */ jsx6(DialogTitle2, { children: "Delete Secret?" }),
2602
- /* @__PURE__ */ jsxs6(DialogDescription2, { children: [
3066
+ }, children: /* @__PURE__ */ jsxs7(DialogContent3, { className: "max-w-sm", children: [
3067
+ /* @__PURE__ */ jsxs7(DialogHeader3, { children: [
3068
+ /* @__PURE__ */ jsx7(DialogTitle3, { children: "Delete Secret?" }),
3069
+ /* @__PURE__ */ jsxs7(DialogDescription3, { children: [
2603
3070
  "This will permanently delete ",
2604
- /* @__PURE__ */ jsx6("span", { className: "font-mono font-bold text-foreground", children: deleteTarget }),
3071
+ /* @__PURE__ */ jsx7("span", { className: "font-mono font-bold text-foreground", children: deleteTarget }),
2605
3072
  ". Sandboxes using this secret will lose access to it."
2606
3073
  ] })
2607
3074
  ] }),
2608
- /* @__PURE__ */ jsxs6(DialogFooter2, { children: [
2609
- /* @__PURE__ */ jsx6(
3075
+ /* @__PURE__ */ jsxs7(DialogFooter3, { children: [
3076
+ /* @__PURE__ */ jsx7(
2610
3077
  "button",
2611
3078
  {
2612
3079
  type: "button",
@@ -2615,7 +3082,7 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2615
3082
  children: "Cancel"
2616
3083
  }
2617
3084
  ),
2618
- /* @__PURE__ */ jsx6(
3085
+ /* @__PURE__ */ jsx7(
2619
3086
  "button",
2620
3087
  {
2621
3088
  type: "button",
@@ -2627,20 +3094,20 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2627
3094
  )
2628
3095
  ] })
2629
3096
  ] }) }),
2630
- /* @__PURE__ */ jsxs6("div", { className: "overflow-hidden rounded-lg border border-border bg-card shadow-[var(--shadow-card)]", children: [
2631
- /* @__PURE__ */ jsxs6("div", { className: "border-b border-border px-6 py-4 flex items-center justify-between", children: [
2632
- /* @__PURE__ */ jsx6("div", { className: "flex gap-6", children: /* @__PURE__ */ jsx6("button", { type: "button", className: "text-xs font-bold uppercase tracking-widest text-foreground border-b-2 border-foreground pb-1", children: "All Secrets" }) }),
2633
- /* @__PURE__ */ jsxs6("span", { className: "text-xs text-muted-foreground font-mono", children: [
3097
+ /* @__PURE__ */ jsxs7("div", { className: "overflow-hidden rounded-lg border border-border bg-card shadow-[var(--shadow-card)]", children: [
3098
+ /* @__PURE__ */ jsxs7("div", { className: "border-b border-border px-6 py-4 flex items-center justify-between", children: [
3099
+ /* @__PURE__ */ jsx7("div", { className: "flex gap-6", children: /* @__PURE__ */ jsx7("button", { type: "button", className: "text-xs font-bold uppercase tracking-widest text-foreground border-b-2 border-foreground pb-1", children: "All Secrets" }) }),
3100
+ /* @__PURE__ */ jsxs7("span", { className: "text-xs text-muted-foreground font-mono", children: [
2634
3101
  secrets.length,
2635
3102
  " secret",
2636
3103
  secrets.length !== 1 ? "s" : ""
2637
3104
  ] })
2638
3105
  ] }),
2639
- loading ? /* @__PURE__ */ jsx6("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx6("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent" }) }) : secrets.length === 0 ? /* @__PURE__ */ jsxs6("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
2640
- /* @__PURE__ */ jsx6(Lock, { className: "h-10 w-10 text-muted-foreground mb-4" }),
2641
- /* @__PURE__ */ jsx6("h3", { className: "text-lg font-semibold text-foreground", children: "No secrets yet" }),
2642
- /* @__PURE__ */ jsx6("p", { className: "mt-1 text-sm text-muted-foreground max-w-sm", children: "Create a secret to inject into your sandboxes." }),
2643
- /* @__PURE__ */ jsxs6(
3106
+ loading ? /* @__PURE__ */ jsx7("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx7("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-muted-foreground border-t-transparent" }) }) : secrets.length === 0 ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
3107
+ /* @__PURE__ */ jsx7(Lock, { className: "h-10 w-10 text-muted-foreground mb-4" }),
3108
+ /* @__PURE__ */ jsx7("h3", { className: "text-lg font-semibold text-foreground", children: "No secrets yet" }),
3109
+ /* @__PURE__ */ jsx7("p", { className: "mt-1 text-sm text-muted-foreground max-w-sm", children: "Create a secret to inject into your sandboxes." }),
3110
+ /* @__PURE__ */ jsxs7(
2644
3111
  "button",
2645
3112
  {
2646
3113
  type: "button",
@@ -2648,52 +3115,52 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2648
3115
  "aria-label": "Create your first secret",
2649
3116
  className: "mt-6 inline-flex items-center gap-2 rounded-md bg-[var(--btn-primary-bg)] px-4 py-2 text-sm font-semibold text-[var(--btn-primary-text)] hover:bg-[var(--btn-primary-hover)] transition-colors active:scale-[0.97]",
2650
3117
  children: [
2651
- /* @__PURE__ */ jsx6(Plus3, { className: "h-4 w-4" }),
3118
+ /* @__PURE__ */ jsx7(Plus3, { className: "h-4 w-4" }),
2652
3119
  "New Secret"
2653
3120
  ]
2654
3121
  }
2655
3122
  )
2656
- ] }) : /* @__PURE__ */ jsxs6("table", { className: "w-full text-left border-collapse", children: [
2657
- /* @__PURE__ */ jsx6("thead", { children: /* @__PURE__ */ jsxs6("tr", { className: "bg-muted/30 border-b border-border", children: [
2658
- /* @__PURE__ */ jsx6("th", { className: "px-6 py-4 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Secret Name" }),
2659
- /* @__PURE__ */ jsx6("th", { className: "px-6 py-4 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Encrypted Value" }),
2660
- /* @__PURE__ */ jsx6("th", { className: "px-6 py-4 text-[10px] font-bold uppercase tracking-widest text-muted-foreground text-right", children: "Created" }),
2661
- /* @__PURE__ */ jsx6("th", { className: "px-6 py-4 w-12" })
3123
+ ] }) : /* @__PURE__ */ jsxs7("table", { className: "w-full text-left border-collapse", children: [
3124
+ /* @__PURE__ */ jsx7("thead", { children: /* @__PURE__ */ jsxs7("tr", { className: "bg-muted/30 border-b border-border", children: [
3125
+ /* @__PURE__ */ jsx7("th", { className: "px-6 py-4 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Secret Name" }),
3126
+ /* @__PURE__ */ jsx7("th", { className: "px-6 py-4 text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Encrypted Value" }),
3127
+ /* @__PURE__ */ jsx7("th", { className: "px-6 py-4 text-[10px] font-bold uppercase tracking-widest text-muted-foreground text-right", children: "Created" }),
3128
+ /* @__PURE__ */ jsx7("th", { className: "px-6 py-4 w-12" })
2662
3129
  ] }) }),
2663
- /* @__PURE__ */ jsx6("tbody", { className: "divide-y divide-border", children: secrets.map((secret) => /* @__PURE__ */ jsxs6("tr", { className: "hover:bg-muted/20 transition-colors", children: [
2664
- /* @__PURE__ */ jsx6("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3", children: [
2665
- /* @__PURE__ */ jsx6(Key, { className: "h-4 w-4 text-muted-foreground" }),
2666
- /* @__PURE__ */ jsx6("span", { className: "text-sm font-bold font-mono text-foreground", children: secret.name })
3130
+ /* @__PURE__ */ jsx7("tbody", { className: "divide-y divide-border", children: secrets.map((secret) => /* @__PURE__ */ jsxs7("tr", { className: "hover:bg-muted/20 transition-colors", children: [
3131
+ /* @__PURE__ */ jsx7("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3", children: [
3132
+ /* @__PURE__ */ jsx7(Key, { className: "h-4 w-4 text-muted-foreground" }),
3133
+ /* @__PURE__ */ jsx7("span", { className: "text-sm font-bold font-mono text-foreground", children: secret.name })
2667
3134
  ] }) }),
2668
- /* @__PURE__ */ jsx6("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsx6("code", { className: "text-xs font-mono text-muted-foreground bg-muted px-2 py-1 rounded", children: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }) }),
2669
- /* @__PURE__ */ jsx6("td", { className: "px-6 py-4 text-right", children: /* @__PURE__ */ jsx6("span", { className: "text-xs text-muted-foreground", children: formatDate(secret.createdAt) }) }),
2670
- /* @__PURE__ */ jsx6("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsx6(
3135
+ /* @__PURE__ */ jsx7("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsx7("code", { className: "text-xs font-mono text-muted-foreground bg-muted px-2 py-1 rounded", children: "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" }) }),
3136
+ /* @__PURE__ */ jsx7("td", { className: "px-6 py-4 text-right", children: /* @__PURE__ */ jsx7("span", { className: "text-xs text-muted-foreground", children: formatDate(secret.createdAt) }) }),
3137
+ /* @__PURE__ */ jsx7("td", { className: "px-6 py-4", children: /* @__PURE__ */ jsx7(
2671
3138
  "button",
2672
3139
  {
2673
3140
  type: "button",
2674
3141
  onClick: () => setDeleteTarget(secret.name),
2675
3142
  className: "p-1.5 rounded-md text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors",
2676
3143
  "aria-label": `Delete ${secret.name}`,
2677
- children: /* @__PURE__ */ jsx6(Trash23, { className: "h-4 w-4" })
3144
+ children: /* @__PURE__ */ jsx7(Trash23, { className: "h-4 w-4" })
2678
3145
  }
2679
3146
  ) })
2680
3147
  ] }, secret.name)) })
2681
3148
  ] })
2682
3149
  ] }),
2683
- /* @__PURE__ */ jsxs6("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: [
2684
- /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
2685
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 mb-3", children: [
2686
- /* @__PURE__ */ jsx6("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx6(Shield, { className: "h-5 w-5" }) }),
2687
- /* @__PURE__ */ jsx6("h3", { className: "text-sm font-bold text-foreground", children: "Encryption Standard" })
3150
+ /* @__PURE__ */ jsxs7("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: [
3151
+ /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
3152
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3 mb-3", children: [
3153
+ /* @__PURE__ */ jsx7("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx7(Shield, { className: "h-5 w-5" }) }),
3154
+ /* @__PURE__ */ jsx7("h3", { className: "text-sm font-bold text-foreground", children: "Encryption Standard" })
2688
3155
  ] }),
2689
- /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground leading-relaxed", children: "Your secrets are encrypted using AES-256-GCM at rest and TLS 1.3 in transit. Hardware Security Modules manage all root keys." })
3156
+ /* @__PURE__ */ jsx7("p", { className: "text-sm text-muted-foreground leading-relaxed", children: "Your secrets are encrypted using AES-256-GCM at rest and TLS 1.3 in transit. Hardware Security Modules manage all root keys." })
2690
3157
  ] }),
2691
- /* @__PURE__ */ jsxs6("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
2692
- /* @__PURE__ */ jsxs6("div", { className: "flex items-center gap-3 mb-3", children: [
2693
- /* @__PURE__ */ jsx6("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx6(Lock, { className: "h-5 w-5" }) }),
2694
- /* @__PURE__ */ jsx6("h3", { className: "text-sm font-bold text-foreground", children: "Access Policy" })
3158
+ /* @__PURE__ */ jsxs7("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
3159
+ /* @__PURE__ */ jsxs7("div", { className: "flex items-center gap-3 mb-3", children: [
3160
+ /* @__PURE__ */ jsx7("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx7(Lock, { className: "h-5 w-5" }) }),
3161
+ /* @__PURE__ */ jsx7("h3", { className: "text-sm font-bold text-foreground", children: "Access Policy" })
2695
3162
  ] }),
2696
- /* @__PURE__ */ jsx6("p", { className: "text-sm text-muted-foreground leading-relaxed", children: "Secrets are injected at sandbox creation time and are never exposed in logs, API responses, or container metadata." })
3163
+ /* @__PURE__ */ jsx7("p", { className: "text-sm text-muted-foreground leading-relaxed", children: "Secrets are injected at sandbox creation time and are never exposed in logs, API responses, or container metadata." })
2697
3164
  ] })
2698
3165
  ] })
2699
3166
  ] });
@@ -2702,18 +3169,18 @@ function SecretsPage({ apiClient, className, teamSecretsHint }) {
2702
3169
  // src/pages/templates-page.tsx
2703
3170
  import { Layers as Layers2 } from "lucide-react";
2704
3171
  import { Skeleton as Skeleton3 } from "@tangle-network/ui/primitives";
2705
- import { jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
3172
+ import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
2706
3173
  function TemplatesPage({ templates, loading = false, onUseTemplate, className }) {
2707
- return /* @__PURE__ */ jsxs7("div", { className: cn("space-y-8", className), children: [
2708
- /* @__PURE__ */ jsxs7("div", { children: [
2709
- /* @__PURE__ */ jsx7("h1", { className: "font-bold text-3xl text-foreground", children: "Templates" }),
2710
- /* @__PURE__ */ jsx7("p", { className: "mt-1 text-muted-foreground", children: "Pre-configured environments to get started quickly" })
3174
+ return /* @__PURE__ */ jsxs8("div", { className: cn("space-y-8", className), children: [
3175
+ /* @__PURE__ */ jsxs8("div", { children: [
3176
+ /* @__PURE__ */ jsx8("h1", { className: "font-bold text-3xl text-foreground", children: "Templates" }),
3177
+ /* @__PURE__ */ jsx8("p", { className: "mt-1 text-muted-foreground", children: "Pre-configured environments to get started quickly" })
2711
3178
  ] }),
2712
- loading || !templates ? /* @__PURE__ */ jsx7("div", { className: "grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx7(Skeleton3, { className: "h-56 rounded-2xl" }, i)) }) : templates.length === 0 ? /* @__PURE__ */ jsxs7("div", { className: "rounded-2xl border border-border bg-card p-16 text-center", children: [
2713
- /* @__PURE__ */ jsx7(Layers2, { className: "mx-auto mb-3 h-10 w-10 text-muted-foreground" }),
2714
- /* @__PURE__ */ jsx7("p", { className: "text-sm font-medium text-foreground mb-1", children: "No templates available" }),
2715
- /* @__PURE__ */ jsx7("p", { className: "text-sm text-muted-foreground", children: "Check back later for pre-configured environments." })
2716
- ] }) : /* @__PURE__ */ jsx7("div", { className: "grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3", children: templates.map((template) => /* @__PURE__ */ jsx7(
3179
+ loading || !templates ? /* @__PURE__ */ jsx8("div", { className: "grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3", children: Array.from({ length: 6 }).map((_, i) => /* @__PURE__ */ jsx8(Skeleton3, { className: "h-56 rounded-2xl" }, i)) }) : templates.length === 0 ? /* @__PURE__ */ jsxs8("div", { className: "rounded-2xl border border-border bg-card p-16 text-center", children: [
3180
+ /* @__PURE__ */ jsx8(Layers2, { className: "mx-auto mb-3 h-10 w-10 text-muted-foreground" }),
3181
+ /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium text-foreground mb-1", children: "No templates available" }),
3182
+ /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: "Check back later for pre-configured environments." })
3183
+ ] }) : /* @__PURE__ */ jsx8("div", { className: "grid grid-cols-1 gap-5 sm:grid-cols-2 lg:grid-cols-3", children: templates.map((template) => /* @__PURE__ */ jsx8(
2717
3184
  TemplateCard,
2718
3185
  {
2719
3186
  template,
@@ -2725,7 +3192,7 @@ function TemplatesPage({ templates, loading = false, onUseTemplate, className })
2725
3192
  }
2726
3193
 
2727
3194
  // src/pages/startup-scripts-page.tsx
2728
- import * as React6 from "react";
3195
+ import * as React7 from "react";
2729
3196
  import {
2730
3197
  Play,
2731
3198
  Plus as Plus4,
@@ -2746,14 +3213,14 @@ import {
2746
3213
  Layers as Layers3
2747
3214
  } from "lucide-react";
2748
3215
  import {
2749
- Dialog as Dialog3,
2750
- DialogContent as DialogContent3,
2751
- DialogDescription as DialogDescription3,
2752
- DialogFooter as DialogFooter3,
2753
- DialogHeader as DialogHeader3,
2754
- DialogTitle as DialogTitle3
3216
+ Dialog as Dialog4,
3217
+ DialogContent as DialogContent4,
3218
+ DialogDescription as DialogDescription4,
3219
+ DialogFooter as DialogFooter4,
3220
+ DialogHeader as DialogHeader4,
3221
+ DialogTitle as DialogTitle4
2755
3222
  } from "@tangle-network/ui/primitives";
2756
- import { jsx as jsx8, jsxs as jsxs8 } from "react/jsx-runtime";
3223
+ import { jsx as jsx9, jsxs as jsxs9 } from "react/jsx-runtime";
2757
3224
  var SCRIPT_TYPE_META = {
2758
3225
  bash: {
2759
3226
  label: "Bash",
@@ -2922,26 +3389,26 @@ function makeDefaultFormData(scriptType = "bash") {
2922
3389
  };
2923
3390
  }
2924
3391
  function StartupScriptsPage({ apiClient, className }) {
2925
- const [scripts, setScripts] = React6.useState([]);
2926
- const [secrets, setSecrets] = React6.useState([]);
2927
- const [environments, setEnvironments] = React6.useState([]);
2928
- const [loading, setLoading] = React6.useState(true);
2929
- const [error, setError] = React6.useState(null);
2930
- const [isDialogOpen, setIsDialogOpen] = React6.useState(false);
2931
- const [dialogStep, setDialogStep] = React6.useState("picker");
2932
- const [transitionDir, setTransitionDir] = React6.useState("forward");
2933
- const [stepKey, setStepKey] = React6.useState(0);
2934
- const [editingScript, setEditingScript] = React6.useState(null);
2935
- const [formData, setFormData] = React6.useState(makeDefaultFormData());
2936
- const [isSaving, setIsSaving] = React6.useState(false);
2937
- const [formError, setFormError] = React6.useState(null);
2938
- const [showConditions, setShowConditions] = React6.useState(false);
2939
- const [deleteTarget, setDeleteTarget] = React6.useState(null);
2940
- const [isDeleting, setIsDeleting] = React6.useState(false);
2941
- const apiRef = React6.useRef(apiClient);
3392
+ const [scripts, setScripts] = React7.useState([]);
3393
+ const [secrets, setSecrets] = React7.useState([]);
3394
+ const [environments, setEnvironments] = React7.useState([]);
3395
+ const [loading, setLoading] = React7.useState(true);
3396
+ const [error, setError] = React7.useState(null);
3397
+ const [isDialogOpen, setIsDialogOpen] = React7.useState(false);
3398
+ const [dialogStep, setDialogStep] = React7.useState("picker");
3399
+ const [transitionDir, setTransitionDir] = React7.useState("forward");
3400
+ const [stepKey, setStepKey] = React7.useState(0);
3401
+ const [editingScript, setEditingScript] = React7.useState(null);
3402
+ const [formData, setFormData] = React7.useState(makeDefaultFormData());
3403
+ const [isSaving, setIsSaving] = React7.useState(false);
3404
+ const [formError, setFormError] = React7.useState(null);
3405
+ const [showConditions, setShowConditions] = React7.useState(false);
3406
+ const [deleteTarget, setDeleteTarget] = React7.useState(null);
3407
+ const [isDeleting, setIsDeleting] = React7.useState(false);
3408
+ const apiRef = React7.useRef(apiClient);
2942
3409
  apiRef.current = apiClient;
2943
- const loadGenRef = React6.useRef(0);
2944
- const loadData = React6.useCallback(async (showSpinner = true) => {
3410
+ const loadGenRef = React7.useRef(0);
3411
+ const loadData = React7.useCallback(async (showSpinner = true) => {
2945
3412
  const gen = ++loadGenRef.current;
2946
3413
  try {
2947
3414
  if (showSpinner) setLoading(true);
@@ -2962,7 +3429,7 @@ function StartupScriptsPage({ apiClient, className }) {
2962
3429
  if (gen === loadGenRef.current) setLoading(false);
2963
3430
  }
2964
3431
  }, []);
2965
- React6.useEffect(() => {
3432
+ React7.useEffect(() => {
2966
3433
  loadData();
2967
3434
  }, [loadData]);
2968
3435
  const openCreate = () => {
@@ -3075,41 +3542,41 @@ function StartupScriptsPage({ apiClient, className }) {
3075
3542
  }));
3076
3543
  };
3077
3544
  const activeCount = scripts.filter((s) => s.enabled).length;
3078
- return /* @__PURE__ */ jsxs8("div", { className: cn("mx-auto w-full max-w-7xl space-y-6", className), children: [
3079
- /* @__PURE__ */ jsxs8("div", { className: "flex flex-col gap-4 md:flex-row md:items-end md:justify-between", children: [
3080
- /* @__PURE__ */ jsxs8("div", { children: [
3081
- /* @__PURE__ */ jsx8("h1", { className: "font-display text-3xl font-extrabold tracking-tight text-foreground", children: "Startup Scripts" }),
3082
- /* @__PURE__ */ jsx8("p", { className: "mt-1 text-sm text-muted-foreground", children: "Define scripts that run automatically when your sandboxes start. Scripts can access your encrypted secrets." })
3545
+ return /* @__PURE__ */ jsxs9("div", { className: cn("mx-auto w-full max-w-7xl space-y-6", className), children: [
3546
+ /* @__PURE__ */ jsxs9("div", { className: "flex flex-col gap-4 md:flex-row md:items-end md:justify-between", children: [
3547
+ /* @__PURE__ */ jsxs9("div", { children: [
3548
+ /* @__PURE__ */ jsx9("h1", { className: "font-display text-3xl font-extrabold tracking-tight text-foreground", children: "Startup Scripts" }),
3549
+ /* @__PURE__ */ jsx9("p", { className: "mt-1 text-sm text-muted-foreground", children: "Define scripts that run automatically when your sandboxes start. Scripts can access your encrypted secrets." })
3083
3550
  ] }),
3084
- /* @__PURE__ */ jsxs8(
3551
+ /* @__PURE__ */ jsxs9(
3085
3552
  "button",
3086
3553
  {
3087
3554
  type: "button",
3088
3555
  onClick: openCreate,
3089
3556
  className: "inline-flex items-center gap-2 rounded-lg bg-[var(--btn-primary-bg)] px-4 py-2.5 text-sm font-bold text-[var(--btn-primary-text)] shadow-sm transition-colors hover:bg-[var(--btn-primary-hover)]",
3090
3557
  children: [
3091
- /* @__PURE__ */ jsx8(Plus4, { className: "h-4 w-4" }),
3558
+ /* @__PURE__ */ jsx9(Plus4, { className: "h-4 w-4" }),
3092
3559
  "New Script"
3093
3560
  ]
3094
3561
  }
3095
3562
  )
3096
3563
  ] }),
3097
- /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-4", children: [
3098
- /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
3099
- /* @__PURE__ */ jsx8("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Total Scripts" }),
3100
- /* @__PURE__ */ jsx8("div", { className: "mt-2 flex items-baseline gap-2", children: /* @__PURE__ */ jsx8("span", { className: "font-display text-2xl font-extrabold text-foreground", children: scripts.length }) })
3564
+ /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-4", children: [
3565
+ /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
3566
+ /* @__PURE__ */ jsx9("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Total Scripts" }),
3567
+ /* @__PURE__ */ jsx9("div", { className: "mt-2 flex items-baseline gap-2", children: /* @__PURE__ */ jsx9("span", { className: "font-display text-2xl font-extrabold text-foreground", children: scripts.length }) })
3101
3568
  ] }),
3102
- /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
3103
- /* @__PURE__ */ jsx8("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Active" }),
3104
- /* @__PURE__ */ jsxs8("div", { className: "mt-2 flex items-baseline gap-2", children: [
3105
- /* @__PURE__ */ jsx8("span", { className: "font-display text-2xl font-extrabold text-foreground", children: activeCount }),
3106
- /* @__PURE__ */ jsxs8("span", { className: "text-xs text-muted-foreground", children: [
3569
+ /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-border bg-card p-5 shadow-[var(--shadow-card)]", children: [
3570
+ /* @__PURE__ */ jsx9("p", { className: "text-[10px] font-bold uppercase tracking-widest text-muted-foreground", children: "Active" }),
3571
+ /* @__PURE__ */ jsxs9("div", { className: "mt-2 flex items-baseline gap-2", children: [
3572
+ /* @__PURE__ */ jsx9("span", { className: "font-display text-2xl font-extrabold text-foreground", children: activeCount }),
3573
+ /* @__PURE__ */ jsxs9("span", { className: "text-xs text-muted-foreground", children: [
3107
3574
  "of ",
3108
3575
  scripts.length
3109
3576
  ] })
3110
3577
  ] })
3111
3578
  ] }),
3112
- /* @__PURE__ */ jsx8(
3579
+ /* @__PURE__ */ jsx9(
3113
3580
  InfoPanel,
3114
3581
  {
3115
3582
  className: "md:col-span-2",
@@ -3119,12 +3586,12 @@ function StartupScriptsPage({ apiClient, className }) {
3119
3586
  }
3120
3587
  )
3121
3588
  ] }),
3122
- error && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 rounded-lg border border-destructive/30 bg-destructive/10 p-4", children: [
3123
- /* @__PURE__ */ jsx8(AlertCircle3, { className: "h-5 w-5 shrink-0 text-destructive" }),
3124
- /* @__PURE__ */ jsx8("p", { className: "text-sm font-medium text-destructive", children: error })
3589
+ error && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 rounded-lg border border-destructive/30 bg-destructive/10 p-4", children: [
3590
+ /* @__PURE__ */ jsx9(AlertCircle3, { className: "h-5 w-5 shrink-0 text-destructive" }),
3591
+ /* @__PURE__ */ jsx9("p", { className: "text-sm font-medium text-destructive", children: error })
3125
3592
  ] }),
3126
- /* @__PURE__ */ jsx8(Dialog3, { open: isDialogOpen, onOpenChange: setIsDialogOpen, children: /* @__PURE__ */ jsxs8(DialogContent3, { className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [
3127
- dialogStep === "picker" && /* @__PURE__ */ jsxs8(
3593
+ /* @__PURE__ */ jsx9(Dialog4, { open: isDialogOpen, onOpenChange: setIsDialogOpen, children: /* @__PURE__ */ jsxs9(DialogContent4, { className: "max-w-2xl max-h-[90vh] overflow-y-auto", children: [
3594
+ dialogStep === "picker" && /* @__PURE__ */ jsxs9(
3128
3595
  "div",
3129
3596
  {
3130
3597
  className: cn(
@@ -3132,14 +3599,14 @@ function StartupScriptsPage({ apiClient, className }) {
3132
3599
  transitionDir === "back" ? "slide-in-from-left-4" : "slide-in-from-right-4"
3133
3600
  ),
3134
3601
  children: [
3135
- /* @__PURE__ */ jsxs8(DialogHeader3, { children: [
3136
- /* @__PURE__ */ jsx8(DialogTitle3, { children: "New Startup Script" }),
3137
- /* @__PURE__ */ jsx8(DialogDescription3, { children: "Start from a template or create a blank script." })
3602
+ /* @__PURE__ */ jsxs9(DialogHeader4, { children: [
3603
+ /* @__PURE__ */ jsx9(DialogTitle4, { children: "New Startup Script" }),
3604
+ /* @__PURE__ */ jsx9(DialogDescription4, { children: "Start from a template or create a blank script." })
3138
3605
  ] }),
3139
- /* @__PURE__ */ jsxs8("div", { className: "space-y-4 py-2", children: [
3140
- /* @__PURE__ */ jsxs8("div", { children: [
3141
- /* @__PURE__ */ jsx8("p", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Blank Script" }),
3142
- /* @__PURE__ */ jsx8("div", { className: "flex flex-wrap gap-2", children: Object.entries(SCRIPT_TYPE_META).map(([type, meta]) => /* @__PURE__ */ jsx8(
3606
+ /* @__PURE__ */ jsxs9("div", { className: "space-y-4 py-2", children: [
3607
+ /* @__PURE__ */ jsxs9("div", { children: [
3608
+ /* @__PURE__ */ jsx9("p", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Blank Script" }),
3609
+ /* @__PURE__ */ jsx9("div", { className: "flex flex-wrap gap-2", children: Object.entries(SCRIPT_TYPE_META).map(([type, meta]) => /* @__PURE__ */ jsx9(
3143
3610
  "button",
3144
3611
  {
3145
3612
  type: "button",
@@ -3150,24 +3617,24 @@ function StartupScriptsPage({ apiClient, className }) {
3150
3617
  type
3151
3618
  )) })
3152
3619
  ] }),
3153
- /* @__PURE__ */ jsxs8("div", { children: [
3154
- /* @__PURE__ */ jsx8("p", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Templates" }),
3155
- /* @__PURE__ */ jsx8("div", { className: "space-y-2", children: SCRIPT_TEMPLATES.map((tmpl) => /* @__PURE__ */ jsxs8(
3620
+ /* @__PURE__ */ jsxs9("div", { children: [
3621
+ /* @__PURE__ */ jsx9("p", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground mb-2", children: "Templates" }),
3622
+ /* @__PURE__ */ jsx9("div", { className: "space-y-2", children: SCRIPT_TEMPLATES.map((tmpl) => /* @__PURE__ */ jsxs9(
3156
3623
  "button",
3157
3624
  {
3158
3625
  type: "button",
3159
3626
  onClick: () => openFromTemplate(tmpl),
3160
3627
  className: "w-full text-left rounded-lg border border-border bg-card p-4 hover:border-primary/30 hover:bg-muted/30 transition-colors group",
3161
3628
  children: [
3162
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center justify-between", children: [
3163
- /* @__PURE__ */ jsxs8("div", { children: [
3164
- /* @__PURE__ */ jsx8("h4", { className: "text-sm font-bold text-foreground group-hover:text-primary transition-colors", children: tmpl.name }),
3165
- /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-muted-foreground", children: tmpl.description })
3629
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center justify-between", children: [
3630
+ /* @__PURE__ */ jsxs9("div", { children: [
3631
+ /* @__PURE__ */ jsx9("h4", { className: "text-sm font-bold text-foreground group-hover:text-primary transition-colors", children: tmpl.name }),
3632
+ /* @__PURE__ */ jsx9("p", { className: "mt-0.5 text-xs text-muted-foreground", children: tmpl.description })
3166
3633
  ] }),
3167
- /* @__PURE__ */ jsx8("span", { className: "text-[10px] font-mono text-muted-foreground bg-muted rounded px-1.5 py-0.5", children: SCRIPT_TYPE_META[tmpl.scriptType].label })
3634
+ /* @__PURE__ */ jsx9("span", { className: "text-[10px] font-mono text-muted-foreground bg-muted rounded px-1.5 py-0.5", children: SCRIPT_TYPE_META[tmpl.scriptType].label })
3168
3635
  ] }),
3169
- tmpl.injectSecrets.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-wrap gap-1", children: tmpl.injectSecrets.map((s) => /* @__PURE__ */ jsxs8("span", { className: "inline-flex items-center gap-0.5 rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground", children: [
3170
- /* @__PURE__ */ jsx8(Lock2, { className: "h-2.5 w-2.5" }),
3636
+ tmpl.injectSecrets.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-2 flex flex-wrap gap-1", children: tmpl.injectSecrets.map((s) => /* @__PURE__ */ jsxs9("span", { className: "inline-flex items-center gap-0.5 rounded-full bg-muted px-2 py-0.5 text-[10px] text-muted-foreground", children: [
3637
+ /* @__PURE__ */ jsx9(Lock2, { className: "h-2.5 w-2.5" }),
3171
3638
  s
3172
3639
  ] }, s)) })
3173
3640
  ]
@@ -3180,7 +3647,7 @@ function StartupScriptsPage({ apiClient, className }) {
3180
3647
  },
3181
3648
  `picker-${stepKey}`
3182
3649
  ),
3183
- dialogStep === "form" && /* @__PURE__ */ jsxs8(
3650
+ dialogStep === "form" && /* @__PURE__ */ jsxs9(
3184
3651
  "div",
3185
3652
  {
3186
3653
  className: cn(
@@ -3188,14 +3655,14 @@ function StartupScriptsPage({ apiClient, className }) {
3188
3655
  transitionDir === "forward" ? "slide-in-from-right-4" : "slide-in-from-left-4"
3189
3656
  ),
3190
3657
  children: [
3191
- /* @__PURE__ */ jsxs8(DialogHeader3, { children: [
3192
- /* @__PURE__ */ jsx8(DialogTitle3, { children: editingScript ? "Edit Script" : "Create Startup Script" }),
3193
- /* @__PURE__ */ jsx8(DialogDescription3, { children: editingScript ? "Modify your startup script configuration." : "Define a shell script that runs when sandboxes start. Scripts execute before the AI agent." })
3658
+ /* @__PURE__ */ jsxs9(DialogHeader4, { children: [
3659
+ /* @__PURE__ */ jsx9(DialogTitle4, { children: editingScript ? "Edit Script" : "Create Startup Script" }),
3660
+ /* @__PURE__ */ jsx9(DialogDescription4, { children: editingScript ? "Modify your startup script configuration." : "Define a shell script that runs when sandboxes start. Scripts execute before the AI agent." })
3194
3661
  ] }),
3195
- /* @__PURE__ */ jsxs8("div", { className: "space-y-5 py-2", children: [
3196
- /* @__PURE__ */ jsxs8("div", { children: [
3197
- /* @__PURE__ */ jsx8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Name" }),
3198
- /* @__PURE__ */ jsx8(
3662
+ /* @__PURE__ */ jsxs9("div", { className: "space-y-5 py-2", children: [
3663
+ /* @__PURE__ */ jsxs9("div", { children: [
3664
+ /* @__PURE__ */ jsx9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Name" }),
3665
+ /* @__PURE__ */ jsx9(
3199
3666
  "input",
3200
3667
  {
3201
3668
  type: "text",
@@ -3207,9 +3674,9 @@ function StartupScriptsPage({ apiClient, className }) {
3207
3674
  }
3208
3675
  )
3209
3676
  ] }),
3210
- /* @__PURE__ */ jsxs8("div", { children: [
3211
- /* @__PURE__ */ jsx8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Description" }),
3212
- /* @__PURE__ */ jsx8(
3677
+ /* @__PURE__ */ jsxs9("div", { children: [
3678
+ /* @__PURE__ */ jsx9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Description" }),
3679
+ /* @__PURE__ */ jsx9(
3213
3680
  "input",
3214
3681
  {
3215
3682
  type: "text",
@@ -3221,9 +3688,9 @@ function StartupScriptsPage({ apiClient, className }) {
3221
3688
  }
3222
3689
  )
3223
3690
  ] }),
3224
- /* @__PURE__ */ jsxs8("div", { children: [
3225
- /* @__PURE__ */ jsx8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Language" }),
3226
- /* @__PURE__ */ jsx8("div", { className: "mt-1.5 flex flex-wrap gap-2", children: Object.entries(SCRIPT_TYPE_META).map(([type, meta]) => /* @__PURE__ */ jsx8(
3691
+ /* @__PURE__ */ jsxs9("div", { children: [
3692
+ /* @__PURE__ */ jsx9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Language" }),
3693
+ /* @__PURE__ */ jsx9("div", { className: "mt-1.5 flex flex-wrap gap-2", children: Object.entries(SCRIPT_TYPE_META).map(([type, meta]) => /* @__PURE__ */ jsx9(
3227
3694
  "button",
3228
3695
  {
3229
3696
  type: "button",
@@ -3245,9 +3712,9 @@ function StartupScriptsPage({ apiClient, className }) {
3245
3712
  type
3246
3713
  )) })
3247
3714
  ] }),
3248
- /* @__PURE__ */ jsxs8("div", { children: [
3249
- /* @__PURE__ */ jsx8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Script" }),
3250
- /* @__PURE__ */ jsx8(
3715
+ /* @__PURE__ */ jsxs9("div", { children: [
3716
+ /* @__PURE__ */ jsx9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Script" }),
3717
+ /* @__PURE__ */ jsx9(
3251
3718
  "textarea",
3252
3719
  {
3253
3720
  value: formData.content,
@@ -3257,19 +3724,19 @@ function StartupScriptsPage({ apiClient, className }) {
3257
3724
  className: "mt-1.5 w-full rounded-lg border border-border bg-[var(--depth-1,hsl(var(--muted)))] px-4 py-3 font-mono text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30 resize-y"
3258
3725
  }
3259
3726
  ),
3260
- /* @__PURE__ */ jsxs8("p", { className: "mt-1 text-xs text-muted-foreground", children: [
3727
+ /* @__PURE__ */ jsxs9("p", { className: "mt-1 text-xs text-muted-foreground", children: [
3261
3728
  SCRIPT_TYPE_META[formData.scriptType].label,
3262
3729
  " script. Injected secrets are available as environment variables (e.g. ",
3263
- /* @__PURE__ */ jsx8("code", { className: "text-primary", children: "$GITHUB_TOKEN" }),
3730
+ /* @__PURE__ */ jsx9("code", { className: "text-primary", children: "$GITHUB_TOKEN" }),
3264
3731
  ")."
3265
3732
  ] })
3266
3733
  ] }),
3267
- secrets.length > 0 && /* @__PURE__ */ jsxs8("div", { children: [
3268
- /* @__PURE__ */ jsx8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Inject Secrets" }),
3269
- /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-muted-foreground", children: "Select secrets to make available as environment variables." }),
3270
- /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-wrap gap-2", children: secrets.map((secret) => {
3734
+ secrets.length > 0 && /* @__PURE__ */ jsxs9("div", { children: [
3735
+ /* @__PURE__ */ jsx9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground", children: "Inject Secrets" }),
3736
+ /* @__PURE__ */ jsx9("p", { className: "mt-0.5 text-xs text-muted-foreground", children: "Select secrets to make available as environment variables." }),
3737
+ /* @__PURE__ */ jsx9("div", { className: "mt-2 flex flex-wrap gap-2", children: secrets.map((secret) => {
3271
3738
  const selected = formData.injectSecrets.includes(secret.name);
3272
- return /* @__PURE__ */ jsxs8(
3739
+ return /* @__PURE__ */ jsxs9(
3273
3740
  "button",
3274
3741
  {
3275
3742
  type: "button",
@@ -3279,7 +3746,7 @@ function StartupScriptsPage({ apiClient, className }) {
3279
3746
  selected ? "bg-primary/10 border-primary/30 text-primary" : "bg-muted border-border text-muted-foreground hover:border-primary/20"
3280
3747
  ),
3281
3748
  children: [
3282
- /* @__PURE__ */ jsx8(Lock2, { className: "h-3 w-3" }),
3749
+ /* @__PURE__ */ jsx9(Lock2, { className: "h-3 w-3" }),
3283
3750
  secret.name
3284
3751
  ]
3285
3752
  },
@@ -3287,29 +3754,29 @@ function StartupScriptsPage({ apiClient, className }) {
3287
3754
  );
3288
3755
  }) })
3289
3756
  ] }),
3290
- /* @__PURE__ */ jsxs8("div", { children: [
3291
- /* @__PURE__ */ jsxs8(
3757
+ /* @__PURE__ */ jsxs9("div", { children: [
3758
+ /* @__PURE__ */ jsxs9(
3292
3759
  "button",
3293
3760
  {
3294
3761
  type: "button",
3295
3762
  onClick: () => setShowConditions(!showConditions),
3296
3763
  className: "flex items-center gap-2 text-xs font-bold uppercase tracking-widest text-muted-foreground hover:text-foreground transition-colors",
3297
3764
  children: [
3298
- showConditions ? /* @__PURE__ */ jsx8(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx8(ChevronDown2, { className: "h-3.5 w-3.5" }),
3765
+ showConditions ? /* @__PURE__ */ jsx9(ChevronUp, { className: "h-3.5 w-3.5" }) : /* @__PURE__ */ jsx9(ChevronDown2, { className: "h-3.5 w-3.5" }),
3299
3766
  "Conditions & Execution"
3300
3767
  ]
3301
3768
  }
3302
3769
  ),
3303
- showConditions && /* @__PURE__ */ jsxs8("div", { className: "mt-3 space-y-4 rounded-lg border border-border bg-muted/30 p-4", children: [
3304
- /* @__PURE__ */ jsxs8("div", { children: [
3305
- /* @__PURE__ */ jsxs8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3306
- /* @__PURE__ */ jsx8(Layers3, { className: "h-3.5 w-3.5" }),
3770
+ showConditions && /* @__PURE__ */ jsxs9("div", { className: "mt-3 space-y-4 rounded-lg border border-border bg-muted/30 p-4", children: [
3771
+ /* @__PURE__ */ jsxs9("div", { children: [
3772
+ /* @__PURE__ */ jsxs9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3773
+ /* @__PURE__ */ jsx9(Layers3, { className: "h-3.5 w-3.5" }),
3307
3774
  "Environments"
3308
3775
  ] }),
3309
- /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-muted-foreground", children: environments.length > 0 ? "Only run for these environments. Leave empty to run for all." : "No templates configured. Script will run for all environments." }),
3310
- environments.length > 0 && /* @__PURE__ */ jsx8("div", { className: "mt-2 flex flex-wrap gap-2", children: environments.map((env) => {
3776
+ /* @__PURE__ */ jsx9("p", { className: "mt-0.5 text-xs text-muted-foreground", children: environments.length > 0 ? "Only run for these environments. Leave empty to run for all." : "No templates configured. Script will run for all environments." }),
3777
+ environments.length > 0 && /* @__PURE__ */ jsx9("div", { className: "mt-2 flex flex-wrap gap-2", children: environments.map((env) => {
3311
3778
  const selected = formData.environments.includes(env.id);
3312
- return /* @__PURE__ */ jsx8(
3779
+ return /* @__PURE__ */ jsx9(
3313
3780
  "button",
3314
3781
  {
3315
3782
  type: "button",
@@ -3324,13 +3791,13 @@ function StartupScriptsPage({ apiClient, className }) {
3324
3791
  );
3325
3792
  }) })
3326
3793
  ] }),
3327
- /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-2 gap-4", children: [
3328
- /* @__PURE__ */ jsxs8("div", { children: [
3329
- /* @__PURE__ */ jsxs8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3330
- /* @__PURE__ */ jsx8(Cpu2, { className: "h-3.5 w-3.5" }),
3794
+ /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-2 gap-4", children: [
3795
+ /* @__PURE__ */ jsxs9("div", { children: [
3796
+ /* @__PURE__ */ jsxs9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3797
+ /* @__PURE__ */ jsx9(Cpu2, { className: "h-3.5 w-3.5" }),
3331
3798
  "Min CPU Cores"
3332
3799
  ] }),
3333
- /* @__PURE__ */ jsx8(
3800
+ /* @__PURE__ */ jsx9(
3334
3801
  "input",
3335
3802
  {
3336
3803
  type: "number",
@@ -3346,12 +3813,12 @@ function StartupScriptsPage({ apiClient, className }) {
3346
3813
  }
3347
3814
  )
3348
3815
  ] }),
3349
- /* @__PURE__ */ jsxs8("div", { children: [
3350
- /* @__PURE__ */ jsxs8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3351
- /* @__PURE__ */ jsx8(MemoryStick, { className: "h-3.5 w-3.5" }),
3816
+ /* @__PURE__ */ jsxs9("div", { children: [
3817
+ /* @__PURE__ */ jsxs9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3818
+ /* @__PURE__ */ jsx9(MemoryStick, { className: "h-3.5 w-3.5" }),
3352
3819
  "Min RAM (GB)"
3353
3820
  ] }),
3354
- /* @__PURE__ */ jsx8(
3821
+ /* @__PURE__ */ jsx9(
3355
3822
  "input",
3356
3823
  {
3357
3824
  type: "number",
@@ -3368,13 +3835,13 @@ function StartupScriptsPage({ apiClient, className }) {
3368
3835
  )
3369
3836
  ] })
3370
3837
  ] }),
3371
- /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-2 gap-4", children: [
3372
- /* @__PURE__ */ jsxs8("div", { children: [
3373
- /* @__PURE__ */ jsxs8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3374
- /* @__PURE__ */ jsx8(GripVertical, { className: "h-3.5 w-3.5" }),
3838
+ /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-2 gap-4", children: [
3839
+ /* @__PURE__ */ jsxs9("div", { children: [
3840
+ /* @__PURE__ */ jsxs9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3841
+ /* @__PURE__ */ jsx9(GripVertical, { className: "h-3.5 w-3.5" }),
3375
3842
  "Run Order"
3376
3843
  ] }),
3377
- /* @__PURE__ */ jsx8(
3844
+ /* @__PURE__ */ jsx9(
3378
3845
  "input",
3379
3846
  {
3380
3847
  type: "number",
@@ -3385,14 +3852,14 @@ function StartupScriptsPage({ apiClient, className }) {
3385
3852
  className: "mt-1.5 w-full rounded-lg border border-border bg-background px-3 py-2 text-sm text-foreground placeholder:text-muted-foreground focus:outline-none focus:ring-2 focus:ring-primary/30"
3386
3853
  }
3387
3854
  ),
3388
- /* @__PURE__ */ jsx8("p", { className: "mt-1 text-xs text-muted-foreground", children: "Lower runs first" })
3855
+ /* @__PURE__ */ jsx9("p", { className: "mt-1 text-xs text-muted-foreground", children: "Lower runs first" })
3389
3856
  ] }),
3390
- /* @__PURE__ */ jsxs8("div", { children: [
3391
- /* @__PURE__ */ jsxs8("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3392
- /* @__PURE__ */ jsx8(Clock, { className: "h-3.5 w-3.5" }),
3857
+ /* @__PURE__ */ jsxs9("div", { children: [
3858
+ /* @__PURE__ */ jsxs9("label", { className: "text-xs font-bold uppercase tracking-widest text-muted-foreground flex items-center gap-1.5", children: [
3859
+ /* @__PURE__ */ jsx9(Clock, { className: "h-3.5 w-3.5" }),
3393
3860
  "Timeout (seconds)"
3394
3861
  ] }),
3395
- /* @__PURE__ */ jsx8(
3862
+ /* @__PURE__ */ jsx9(
3396
3863
  "input",
3397
3864
  {
3398
3865
  type: "number",
@@ -3405,13 +3872,13 @@ function StartupScriptsPage({ apiClient, className }) {
3405
3872
  )
3406
3873
  ] })
3407
3874
  ] }),
3408
- /* @__PURE__ */ jsxs8("div", { className: "space-y-3", children: [
3409
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center justify-between cursor-pointer", children: [
3410
- /* @__PURE__ */ jsxs8("div", { children: [
3411
- /* @__PURE__ */ jsx8("span", { className: "text-sm font-medium text-foreground", children: "Continue on failure" }),
3412
- /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground", children: "If script fails, continue starting the sandbox" })
3875
+ /* @__PURE__ */ jsxs9("div", { className: "space-y-3", children: [
3876
+ /* @__PURE__ */ jsxs9("label", { className: "flex items-center justify-between cursor-pointer", children: [
3877
+ /* @__PURE__ */ jsxs9("div", { children: [
3878
+ /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-foreground", children: "Continue on failure" }),
3879
+ /* @__PURE__ */ jsx9("p", { className: "text-xs text-muted-foreground", children: "If script fails, continue starting the sandbox" })
3413
3880
  ] }),
3414
- /* @__PURE__ */ jsx8(
3881
+ /* @__PURE__ */ jsx9(
3415
3882
  "button",
3416
3883
  {
3417
3884
  type: "button",
@@ -3420,7 +3887,7 @@ function StartupScriptsPage({ apiClient, className }) {
3420
3887
  "relative h-6 w-11 rounded-full transition-colors",
3421
3888
  formData.continueOnFailure ? "bg-primary" : "bg-border"
3422
3889
  ),
3423
- children: /* @__PURE__ */ jsx8(
3890
+ children: /* @__PURE__ */ jsx9(
3424
3891
  "span",
3425
3892
  {
3426
3893
  className: cn(
@@ -3432,12 +3899,12 @@ function StartupScriptsPage({ apiClient, className }) {
3432
3899
  }
3433
3900
  )
3434
3901
  ] }),
3435
- /* @__PURE__ */ jsxs8("label", { className: "flex items-center justify-between cursor-pointer", children: [
3436
- /* @__PURE__ */ jsxs8("div", { children: [
3437
- /* @__PURE__ */ jsx8("span", { className: "text-sm font-medium text-foreground", children: "Run as root" }),
3438
- /* @__PURE__ */ jsx8("p", { className: "text-xs text-muted-foreground", children: "Execute with root privileges instead of the agent user" })
3902
+ /* @__PURE__ */ jsxs9("label", { className: "flex items-center justify-between cursor-pointer", children: [
3903
+ /* @__PURE__ */ jsxs9("div", { children: [
3904
+ /* @__PURE__ */ jsx9("span", { className: "text-sm font-medium text-foreground", children: "Run as root" }),
3905
+ /* @__PURE__ */ jsx9("p", { className: "text-xs text-muted-foreground", children: "Execute with root privileges instead of the agent user" })
3439
3906
  ] }),
3440
- /* @__PURE__ */ jsx8(
3907
+ /* @__PURE__ */ jsx9(
3441
3908
  "button",
3442
3909
  {
3443
3910
  type: "button",
@@ -3446,7 +3913,7 @@ function StartupScriptsPage({ apiClient, className }) {
3446
3913
  "relative h-6 w-11 rounded-full transition-colors",
3447
3914
  formData.runAsRoot ? "bg-primary" : "bg-border"
3448
3915
  ),
3449
- children: /* @__PURE__ */ jsx8(
3916
+ children: /* @__PURE__ */ jsx9(
3450
3917
  "span",
3451
3918
  {
3452
3919
  className: cn(
@@ -3461,26 +3928,26 @@ function StartupScriptsPage({ apiClient, className }) {
3461
3928
  ] })
3462
3929
  ] })
3463
3930
  ] }),
3464
- formError && /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive/10 p-3", children: [
3465
- /* @__PURE__ */ jsx8(AlertCircle3, { className: "h-4 w-4 text-destructive" }),
3466
- /* @__PURE__ */ jsx8("p", { className: "text-sm text-destructive", children: formError })
3931
+ formError && /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2 rounded-lg border border-destructive/30 bg-destructive/10 p-3", children: [
3932
+ /* @__PURE__ */ jsx9(AlertCircle3, { className: "h-4 w-4 text-destructive" }),
3933
+ /* @__PURE__ */ jsx9("p", { className: "text-sm text-destructive", children: formError })
3467
3934
  ] })
3468
3935
  ] }),
3469
- /* @__PURE__ */ jsxs8(DialogFooter3, { className: "flex items-center justify-between sm:justify-between", children: [
3470
- /* @__PURE__ */ jsx8("div", { children: !editingScript && /* @__PURE__ */ jsxs8(
3936
+ /* @__PURE__ */ jsxs9(DialogFooter4, { className: "flex items-center justify-between sm:justify-between", children: [
3937
+ /* @__PURE__ */ jsx9("div", { children: !editingScript && /* @__PURE__ */ jsxs9(
3471
3938
  "button",
3472
3939
  {
3473
3940
  type: "button",
3474
3941
  onClick: () => goToStep("picker"),
3475
3942
  className: "inline-flex items-center gap-1.5 rounded-lg border border-border px-4 py-2 text-sm font-medium text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
3476
3943
  children: [
3477
- /* @__PURE__ */ jsx8("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx8("path", { d: "m15 18-6-6 6-6" }) }),
3944
+ /* @__PURE__ */ jsx9("svg", { className: "h-4 w-4", viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round", children: /* @__PURE__ */ jsx9("path", { d: "m15 18-6-6 6-6" }) }),
3478
3945
  "Back"
3479
3946
  ]
3480
3947
  }
3481
3948
  ) }),
3482
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
3483
- /* @__PURE__ */ jsx8(
3949
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
3950
+ /* @__PURE__ */ jsx9(
3484
3951
  "button",
3485
3952
  {
3486
3953
  type: "button",
@@ -3489,7 +3956,7 @@ function StartupScriptsPage({ apiClient, className }) {
3489
3956
  children: "Cancel"
3490
3957
  }
3491
3958
  ),
3492
- /* @__PURE__ */ jsx8(
3959
+ /* @__PURE__ */ jsx9(
3493
3960
  "button",
3494
3961
  {
3495
3962
  type: "button",
@@ -3506,17 +3973,17 @@ function StartupScriptsPage({ apiClient, className }) {
3506
3973
  `form-${stepKey}`
3507
3974
  )
3508
3975
  ] }) }),
3509
- /* @__PURE__ */ jsx8(Dialog3, { open: !!deleteTarget, onOpenChange: () => setDeleteTarget(null), children: /* @__PURE__ */ jsxs8(DialogContent3, { className: "max-w-md", children: [
3510
- /* @__PURE__ */ jsxs8(DialogHeader3, { children: [
3511
- /* @__PURE__ */ jsx8(DialogTitle3, { children: "Delete Startup Script" }),
3512
- /* @__PURE__ */ jsxs8(DialogDescription3, { children: [
3976
+ /* @__PURE__ */ jsx9(Dialog4, { open: !!deleteTarget, onOpenChange: () => setDeleteTarget(null), children: /* @__PURE__ */ jsxs9(DialogContent4, { className: "max-w-md", children: [
3977
+ /* @__PURE__ */ jsxs9(DialogHeader4, { children: [
3978
+ /* @__PURE__ */ jsx9(DialogTitle4, { children: "Delete Startup Script" }),
3979
+ /* @__PURE__ */ jsxs9(DialogDescription4, { children: [
3513
3980
  "Are you sure you want to delete \u201C",
3514
3981
  deleteTarget?.name,
3515
3982
  "\u201D? This action cannot be undone."
3516
3983
  ] })
3517
3984
  ] }),
3518
- /* @__PURE__ */ jsxs8(DialogFooter3, { children: [
3519
- /* @__PURE__ */ jsx8(
3985
+ /* @__PURE__ */ jsxs9(DialogFooter4, { children: [
3986
+ /* @__PURE__ */ jsx9(
3520
3987
  "button",
3521
3988
  {
3522
3989
  type: "button",
@@ -3525,7 +3992,7 @@ function StartupScriptsPage({ apiClient, className }) {
3525
3992
  children: "Cancel"
3526
3993
  }
3527
3994
  ),
3528
- /* @__PURE__ */ jsx8(
3995
+ /* @__PURE__ */ jsx9(
3529
3996
  "button",
3530
3997
  {
3531
3998
  type: "button",
@@ -3537,20 +4004,20 @@ function StartupScriptsPage({ apiClient, className }) {
3537
4004
  )
3538
4005
  ] })
3539
4006
  ] }) }),
3540
- /* @__PURE__ */ jsxs8("div", { className: "overflow-hidden rounded-lg border border-border bg-card shadow-[var(--shadow-card)]", children: [
3541
- /* @__PURE__ */ jsxs8("div", { className: "border-b border-border px-6 py-4 flex items-center justify-between", children: [
3542
- /* @__PURE__ */ jsx8("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx8("button", { className: "text-xs font-bold uppercase tracking-widest text-foreground", children: "All Scripts" }) }),
3543
- /* @__PURE__ */ jsxs8("span", { className: "text-xs text-muted-foreground font-mono", children: [
4007
+ /* @__PURE__ */ jsxs9("div", { className: "overflow-hidden rounded-lg border border-border bg-card shadow-[var(--shadow-card)]", children: [
4008
+ /* @__PURE__ */ jsxs9("div", { className: "border-b border-border px-6 py-4 flex items-center justify-between", children: [
4009
+ /* @__PURE__ */ jsx9("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsx9("button", { className: "text-xs font-bold uppercase tracking-widest text-foreground", children: "All Scripts" }) }),
4010
+ /* @__PURE__ */ jsxs9("span", { className: "text-xs text-muted-foreground font-mono", children: [
3544
4011
  scripts.length,
3545
4012
  " script",
3546
4013
  scripts.length !== 1 ? "s" : ""
3547
4014
  ] })
3548
4015
  ] }),
3549
- loading ? /* @__PURE__ */ jsx8("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx8("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent" }) }) : scripts.length === 0 ? /* @__PURE__ */ jsxs8("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
3550
- /* @__PURE__ */ jsx8(Terminal, { className: "h-10 w-10 text-muted-foreground mb-4" }),
3551
- /* @__PURE__ */ jsx8("h3", { className: "text-lg font-semibold text-foreground", children: "No startup scripts yet" }),
3552
- /* @__PURE__ */ jsx8("p", { className: "mt-1 text-sm text-muted-foreground max-w-sm", children: "Create a script to run automatically when your sandboxes start." }),
3553
- /* @__PURE__ */ jsxs8(
4016
+ loading ? /* @__PURE__ */ jsx9("div", { className: "flex items-center justify-center py-16", children: /* @__PURE__ */ jsx9("div", { className: "h-6 w-6 animate-spin rounded-full border-2 border-primary border-t-transparent" }) }) : scripts.length === 0 ? /* @__PURE__ */ jsxs9("div", { className: "flex flex-col items-center justify-center py-16 text-center", children: [
4017
+ /* @__PURE__ */ jsx9(Terminal, { className: "h-10 w-10 text-muted-foreground mb-4" }),
4018
+ /* @__PURE__ */ jsx9("h3", { className: "text-lg font-semibold text-foreground", children: "No startup scripts yet" }),
4019
+ /* @__PURE__ */ jsx9("p", { className: "mt-1 text-sm text-muted-foreground max-w-sm", children: "Create a script to run automatically when your sandboxes start." }),
4020
+ /* @__PURE__ */ jsxs9(
3554
4021
  "button",
3555
4022
  {
3556
4023
  type: "button",
@@ -3558,12 +4025,12 @@ function StartupScriptsPage({ apiClient, className }) {
3558
4025
  "aria-label": "Create your first startup script",
3559
4026
  className: "mt-4 inline-flex items-center gap-2 rounded-lg bg-[var(--btn-primary-bg)] px-4 py-2.5 text-sm font-bold text-[var(--btn-primary-text)] shadow-sm transition-colors hover:bg-[var(--btn-primary-hover)]",
3560
4027
  children: [
3561
- /* @__PURE__ */ jsx8(Plus4, { className: "h-4 w-4" }),
4028
+ /* @__PURE__ */ jsx9(Plus4, { className: "h-4 w-4" }),
3562
4029
  "New Script"
3563
4030
  ]
3564
4031
  }
3565
4032
  )
3566
- ] }) : /* @__PURE__ */ jsx8("div", { className: "divide-y divide-border", children: scripts.map((script) => /* @__PURE__ */ jsxs8(
4033
+ ] }) : /* @__PURE__ */ jsx9("div", { className: "divide-y divide-border", children: scripts.map((script) => /* @__PURE__ */ jsxs9(
3567
4034
  "div",
3568
4035
  {
3569
4036
  className: cn(
@@ -3571,7 +4038,7 @@ function StartupScriptsPage({ apiClient, className }) {
3571
4038
  !script.enabled && "opacity-60"
3572
4039
  ),
3573
4040
  children: [
3574
- /* @__PURE__ */ jsx8(
4041
+ /* @__PURE__ */ jsx9(
3575
4042
  "button",
3576
4043
  {
3577
4044
  type: "button",
@@ -3581,53 +4048,53 @@ function StartupScriptsPage({ apiClient, className }) {
3581
4048
  "flex h-8 w-8 shrink-0 items-center justify-center rounded-full transition-colors",
3582
4049
  script.enabled ? "bg-[var(--surface-success-bg,hsl(142 76% 90%))] text-[var(--surface-success-text,hsl(142 76% 36%))]" : "bg-muted text-muted-foreground"
3583
4050
  ),
3584
- children: script.enabled ? /* @__PURE__ */ jsx8(Power, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx8(PowerOff, { className: "h-4 w-4" })
4051
+ children: script.enabled ? /* @__PURE__ */ jsx9(Power, { className: "h-4 w-4" }) : /* @__PURE__ */ jsx9(PowerOff, { className: "h-4 w-4" })
3585
4052
  }
3586
4053
  ),
3587
- /* @__PURE__ */ jsxs8("div", { className: "flex-1 min-w-0", children: [
3588
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-2", children: [
3589
- /* @__PURE__ */ jsx8("h4", { className: "text-sm font-bold text-foreground truncate", children: script.name }),
3590
- /* @__PURE__ */ jsx8("span", { className: "text-[10px] font-mono text-muted-foreground bg-muted rounded px-1.5 py-0.5", children: SCRIPT_TYPE_META[script.scriptType ?? "bash"].label }),
3591
- script.runOrder !== 100 && /* @__PURE__ */ jsxs8("span", { className: "text-[10px] font-mono text-muted-foreground bg-muted rounded px-1.5 py-0.5", children: [
4054
+ /* @__PURE__ */ jsxs9("div", { className: "flex-1 min-w-0", children: [
4055
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-2", children: [
4056
+ /* @__PURE__ */ jsx9("h4", { className: "text-sm font-bold text-foreground truncate", children: script.name }),
4057
+ /* @__PURE__ */ jsx9("span", { className: "text-[10px] font-mono text-muted-foreground bg-muted rounded px-1.5 py-0.5", children: SCRIPT_TYPE_META[script.scriptType ?? "bash"].label }),
4058
+ script.runOrder !== 100 && /* @__PURE__ */ jsxs9("span", { className: "text-[10px] font-mono text-muted-foreground bg-muted rounded px-1.5 py-0.5", children: [
3592
4059
  "#",
3593
4060
  script.runOrder
3594
4061
  ] })
3595
4062
  ] }),
3596
- script.description && /* @__PURE__ */ jsx8("p", { className: "mt-0.5 text-xs text-muted-foreground truncate", children: script.description }),
3597
- /* @__PURE__ */ jsxs8("div", { className: "mt-1.5 flex flex-wrap gap-1.5", children: [
3598
- script.environments.map((env) => /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary", children: env }, env)),
3599
- script.injectSecrets.map((s) => /* @__PURE__ */ jsxs8("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground flex items-center gap-0.5", children: [
3600
- /* @__PURE__ */ jsx8(Lock2, { className: "h-2.5 w-2.5" }),
4063
+ script.description && /* @__PURE__ */ jsx9("p", { className: "mt-0.5 text-xs text-muted-foreground truncate", children: script.description }),
4064
+ /* @__PURE__ */ jsxs9("div", { className: "mt-1.5 flex flex-wrap gap-1.5", children: [
4065
+ script.environments.map((env) => /* @__PURE__ */ jsx9("span", { className: "rounded-full bg-primary/10 px-2 py-0.5 text-[10px] font-medium text-primary", children: env }, env)),
4066
+ script.injectSecrets.map((s) => /* @__PURE__ */ jsxs9("span", { className: "rounded-full bg-muted px-2 py-0.5 text-[10px] font-medium text-muted-foreground flex items-center gap-0.5", children: [
4067
+ /* @__PURE__ */ jsx9(Lock2, { className: "h-2.5 w-2.5" }),
3601
4068
  s
3602
4069
  ] }, s)),
3603
- script.continueOnFailure && /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-amber-500/10 px-2 py-0.5 text-[10px] font-medium text-amber-600", children: "soft fail" }),
3604
- script.runAsRoot && /* @__PURE__ */ jsx8("span", { className: "rounded-full bg-destructive/10 px-2 py-0.5 text-[10px] font-medium text-destructive", children: "root" })
4070
+ script.continueOnFailure && /* @__PURE__ */ jsx9("span", { className: "rounded-full bg-amber-500/10 px-2 py-0.5 text-[10px] font-medium text-amber-600", children: "soft fail" }),
4071
+ script.runAsRoot && /* @__PURE__ */ jsx9("span", { className: "rounded-full bg-destructive/10 px-2 py-0.5 text-[10px] font-medium text-destructive", children: "root" })
3605
4072
  ] })
3606
4073
  ] }),
3607
- /* @__PURE__ */ jsxs8("div", { className: "hidden md:flex items-center gap-1 text-xs text-muted-foreground", children: [
3608
- /* @__PURE__ */ jsx8(Clock, { className: "h-3.5 w-3.5" }),
4074
+ /* @__PURE__ */ jsxs9("div", { className: "hidden md:flex items-center gap-1 text-xs text-muted-foreground", children: [
4075
+ /* @__PURE__ */ jsx9(Clock, { className: "h-3.5 w-3.5" }),
3609
4076
  script.timeoutSeconds,
3610
4077
  "s"
3611
4078
  ] }),
3612
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-1 sm:opacity-0 sm:group-hover:opacity-100 sm:focus-within:opacity-100 transition-opacity", children: [
3613
- /* @__PURE__ */ jsx8(
4079
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-1 sm:opacity-0 sm:group-hover:opacity-100 sm:focus-within:opacity-100 transition-opacity", children: [
4080
+ /* @__PURE__ */ jsx9(
3614
4081
  "button",
3615
4082
  {
3616
4083
  type: "button",
3617
4084
  onClick: () => openEdit(script),
3618
4085
  className: "rounded-md p-2 text-muted-foreground hover:text-foreground hover:bg-muted transition-colors",
3619
4086
  "aria-label": `Edit ${script.name}`,
3620
- children: /* @__PURE__ */ jsx8(Pencil, { className: "h-4 w-4" })
4087
+ children: /* @__PURE__ */ jsx9(Pencil, { className: "h-4 w-4" })
3621
4088
  }
3622
4089
  ),
3623
- /* @__PURE__ */ jsx8(
4090
+ /* @__PURE__ */ jsx9(
3624
4091
  "button",
3625
4092
  {
3626
4093
  type: "button",
3627
4094
  onClick: () => setDeleteTarget(script),
3628
4095
  className: "rounded-md p-2 text-muted-foreground hover:text-destructive hover:bg-destructive/10 transition-colors",
3629
4096
  "aria-label": `Delete ${script.name}`,
3630
- children: /* @__PURE__ */ jsx8(Trash24, { className: "h-4 w-4" })
4097
+ children: /* @__PURE__ */ jsx9(Trash24, { className: "h-4 w-4" })
3631
4098
  }
3632
4099
  )
3633
4100
  ] })
@@ -3636,20 +4103,20 @@ function StartupScriptsPage({ apiClient, className }) {
3636
4103
  script.id
3637
4104
  )) })
3638
4105
  ] }),
3639
- /* @__PURE__ */ jsxs8("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: [
3640
- /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
3641
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 mb-3", children: [
3642
- /* @__PURE__ */ jsx8("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx8(Play, { className: "h-5 w-5" }) }),
3643
- /* @__PURE__ */ jsx8("h3", { className: "text-sm font-bold text-foreground", children: "How Scripts Run" })
4106
+ /* @__PURE__ */ jsxs9("div", { className: "grid grid-cols-1 gap-6 md:grid-cols-2", children: [
4107
+ /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
4108
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 mb-3", children: [
4109
+ /* @__PURE__ */ jsx9("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx9(Play, { className: "h-5 w-5" }) }),
4110
+ /* @__PURE__ */ jsx9("h3", { className: "text-sm font-bold text-foreground", children: "How Scripts Run" })
3644
4111
  ] }),
3645
- /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: 'Scripts execute in order after the container starts but before the AI agent. They run as bash scripts with full access to mounted tools (Nix profile) and workspace. Failed scripts abort sandbox creation unless "continue on failure" is enabled.' })
4112
+ /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: 'Scripts execute in order after the container starts but before the AI agent. They run as bash scripts with full access to mounted tools (Nix profile) and workspace. Failed scripts abort sandbox creation unless "continue on failure" is enabled.' })
3646
4113
  ] }),
3647
- /* @__PURE__ */ jsxs8("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
3648
- /* @__PURE__ */ jsxs8("div", { className: "flex items-center gap-3 mb-3", children: [
3649
- /* @__PURE__ */ jsx8("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx8(Shield2, { className: "h-5 w-5" }) }),
3650
- /* @__PURE__ */ jsx8("h3", { className: "text-sm font-bold text-foreground", children: "Security & Secrets" })
4114
+ /* @__PURE__ */ jsxs9("div", { className: "rounded-lg border border-border bg-card p-6 shadow-[var(--shadow-card)]", children: [
4115
+ /* @__PURE__ */ jsxs9("div", { className: "flex items-center gap-3 mb-3", children: [
4116
+ /* @__PURE__ */ jsx9("div", { className: "flex h-9 w-9 items-center justify-center rounded-md bg-[var(--brand-primary,hsl(var(--primary)))] text-[var(--btn-primary-text)]", children: /* @__PURE__ */ jsx9(Shield2, { className: "h-5 w-5" }) }),
4117
+ /* @__PURE__ */ jsx9("h3", { className: "text-sm font-bold text-foreground", children: "Security & Secrets" })
3651
4118
  ] }),
3652
- /* @__PURE__ */ jsx8("p", { className: "text-sm text-muted-foreground", children: "Selected secrets are injected as environment variables at execution time. Secret values are never stored in the script itself \u2014 they are decrypted and injected only when the sandbox starts. Scripts can use conditions to restrict execution to specific environments or resource tiers." })
4119
+ /* @__PURE__ */ jsx9("p", { className: "text-sm text-muted-foreground", children: "Selected secrets are injected as environment variables at execution time. Secret values are never stored in the script itself \u2014 they are decrypted and injected only when the sandbox starts. Scripts can use conditions to restrict execution to specific environments or resource tiers." })
3653
4120
  ] })
3654
4121
  ] })
3655
4122
  ] });