@ai-matrx/vault 0.1.8 → 0.1.10

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/index.js CHANGED
@@ -102,7 +102,7 @@ var init_keepass_xml_worker_client = __esm({
102
102
 
103
103
  // src/VaultApp.tsx
104
104
  import { useCallback as useCallback5, useEffect as useEffect23, useMemo as useMemo6, useRef as useRef19, useState as useState40 } from "react";
105
- import { DropdownMenu as DropdownMenu6, DropdownMenuContent as DropdownMenuContent6, DropdownMenuItem as DropdownMenuItem5, DropdownMenuTrigger as DropdownMenuTrigger6 } from "@ai-matrx/design-system";
105
+ import { DropdownMenu as DropdownMenu6, DropdownMenuContent as DropdownMenuContent6, DropdownMenuItem as DropdownMenuItem5, DropdownMenuTrigger as DropdownMenuTrigger6, LookScope } from "@ai-matrx/design-system";
106
106
  import { Button as Button33, SearchField as SearchField4, Select as Select11 } from "@ai-matrx/design-system/controls";
107
107
  import { confirm as confirm13 } from "@ai-matrx/kit/confirm-opener";
108
108
 
@@ -164,6 +164,7 @@ import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } f
164
164
  import { Button, Field } from "@ai-matrx/design-system/controls";
165
165
 
166
166
  // src/glyphs.tsx
167
+ import { GlobeIcon } from "@ai-matrx/design-system/icons";
167
168
  import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
168
169
  function glyph(paths, air = [1, 1]) {
169
170
  const style = { "--matrx-glyph-air-l": air[0], "--matrx-glyph-air-r": air[1] };
@@ -175,10 +176,6 @@ var KeyGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
175
176
  /* @__PURE__ */ jsx2("circle", { cx: "7.5", cy: "15.5", r: "5.5" }),
176
177
  /* @__PURE__ */ jsx2("path", { d: "m21 2-9.6 9.6M15.5 7.5l3 3" })
177
178
  ] }), [1, 2]);
178
- var GlobeGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
179
- /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "10" }),
180
- /* @__PURE__ */ jsx2("path", { d: "M2 12h20M12 2a15.3 15.3 0 0 1 4 10 15.3 15.3 0 0 1-4 10 15.3 15.3 0 0 1-4-10 15.3 15.3 0 0 1 4-10z" })
181
- ] }), [1, 1]);
182
179
  var NoteGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
183
180
  /* @__PURE__ */ jsx2("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
184
181
  /* @__PURE__ */ jsx2("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M16 13H8M16 17H8" })
@@ -208,10 +205,6 @@ var FileGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
208
205
  var CodeGlyph = glyph(/* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2("path", { d: "m16 18 6-6-6-6M8 6l-6 6 6 6" }) }), [1, 1]);
209
206
  var StarGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M12 2l3.1 6.3 6.9 1-5 4.9 1.2 6.8L12 17.8 5.8 21l1.2-6.8-5-4.9 6.9-1z" }), [1, 1]);
210
207
  var PlusGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M12 5v14M5 12h14" }), [4, 4]);
211
- var CopyGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
212
- /* @__PURE__ */ jsx2("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
213
- /* @__PURE__ */ jsx2("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
214
- ] }), [1, 1]);
215
208
  var EyeGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
216
209
  /* @__PURE__ */ jsx2("path", { d: "M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" }),
217
210
  /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" })
@@ -236,11 +229,6 @@ var BuildingGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
236
229
  /* @__PURE__ */ jsx2("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
237
230
  /* @__PURE__ */ jsx2("path", { d: "M9 22v-4h6v4M8 6h.01M16 6h.01M12 6h.01M12 10h.01M12 14h.01M16 10h.01M16 14h.01M8 10h.01M8 14h.01" })
238
231
  ] }), [3, 3]);
239
- var UsersGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
240
- /* @__PURE__ */ jsx2("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
241
- /* @__PURE__ */ jsx2("circle", { cx: "9", cy: "7", r: "4" }),
242
- /* @__PURE__ */ jsx2("path", { d: "M22 21v-2a4 4 0 0 0-3-3.9M16 3.1a4 4 0 0 1 0 7.8" })
243
- ] }), [1, 1]);
244
232
  var ChevronLeftGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "m15 18-6-6 6-6" }), [8, 8]);
245
233
  var GridGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
246
234
  /* @__PURE__ */ jsx2("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
@@ -259,7 +247,7 @@ var FAMILY_GLYPHS = {
259
247
  cloud_infrastructure: ServerGlyph
260
248
  };
261
249
  function definitionGlyph(key, family) {
262
- if (key === "username_password" || key === "website_login") return GlobeGlyph;
250
+ if (key === "username_password" || key === "website_login") return GlobeIcon;
263
251
  return FAMILY_GLYPHS[family] ?? KeyGlyph;
264
252
  }
265
253
  var XGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M18 6 6 18M6 6l12 12" }), [5, 5]);
@@ -277,15 +265,7 @@ var MoreGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
277
265
  /* @__PURE__ */ jsx2("circle", { cx: "5", cy: "12", r: "1" })
278
266
  ] }), [3, 3]);
279
267
  var ShareGlyph = glyph(/* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2("path", { d: "M4 12v8a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2v-8M16 6l-4-4-4 4M12 2v13" }) }), [3, 3]);
280
- var HistoryGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
281
- /* @__PURE__ */ jsx2("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
282
- /* @__PURE__ */ jsx2("path", { d: "M3 3v5h5M12 7v5l4 2" })
283
- ] }), [2, 2]);
284
268
  var ListGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }), [2, 2]);
285
- var SettingsGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
286
- /* @__PURE__ */ jsx2("path", { d: "M12.22 2h-.44a2 2 0 0 0-2 2v.18a2 2 0 0 1-1 1.73l-.43.25a2 2 0 0 1-2 0l-.15-.08a2 2 0 0 0-2.73.73l-.22.38a2 2 0 0 0 .73 2.73l.15.1a2 2 0 0 1 1 1.72v.51a2 2 0 0 1-1 1.74l-.15.09a2 2 0 0 0-.73 2.73l.22.38a2 2 0 0 0 2.73.73l.15-.08a2 2 0 0 1 2 0l.43.25a2 2 0 0 1 1 1.73V20a2 2 0 0 0 2 2h.44a2 2 0 0 0 2-2v-.18a2 2 0 0 1 1-1.73l.43-.25a2 2 0 0 1 2 0l.15.08a2 2 0 0 0 2.73-.73l.22-.39a2 2 0 0 0-.73-2.73l-.15-.08a2 2 0 0 1-1-1.74v-.5a2 2 0 0 1 1-1.74l.15-.09a2 2 0 0 0 .73-2.73l-.22-.38a2 2 0 0 0-2.73-.73l-.15.08a2 2 0 0 1-2 0l-.43-.25a2 2 0 0 1-1-1.73V4a2 2 0 0 0-2-2z" }),
287
- /* @__PURE__ */ jsx2("circle", { cx: "12", cy: "12", r: "3" })
288
- ] }), [2, 2]);
289
269
  var ImportGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" }), [2, 2]);
290
270
  var ExportGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M17 8l-5-5-5 5M12 3v12" }), [2, 2]);
291
271
  var ChevronDownGlyph = glyph(/* @__PURE__ */ jsx2("path", { d: "m6 9 6 6 6-6" }), [5, 5]);
@@ -326,10 +306,6 @@ var RefreshGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
326
306
  /* @__PURE__ */ jsx2("path", { d: "M21 3v5h-5M3 21v-5h5" })
327
307
  ] }), [2, 2]);
328
308
  var SlidersGlyph = glyph(/* @__PURE__ */ jsx2(Fragment, { children: /* @__PURE__ */ jsx2("path", { d: "M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6" }) }), [0, 0]);
329
- var DownloadGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
330
- /* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
331
- /* @__PURE__ */ jsx2("path", { d: "m7 10 5 5 5-5M12 15V3" })
332
- ] }), [2, 2]);
333
309
  var UploadGlyph = glyph(/* @__PURE__ */ jsxs2(Fragment, { children: [
334
310
  /* @__PURE__ */ jsx2("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
335
311
  /* @__PURE__ */ jsx2("path", { d: "m17 8-5-5-5 5M12 3v12" })
@@ -411,7 +387,7 @@ var Ctx2 = createContext2((run) => run());
411
387
  function useConfirmed() {
412
388
  return useContext2(Ctx2);
413
389
  }
414
- var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack" };
390
+ var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack", browser: "Browser", touch_id: "Touch ID" };
415
391
  var providerLabel = (p) => PROVIDER_LABEL[p] ?? p.charAt(0).toUpperCase() + p.slice(1);
416
392
  function IdentityGate({ identity, children }) {
417
393
  const [asking, setAsking] = useState2(false);
@@ -481,10 +457,21 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
481
457
  ] }),
482
458
  /* @__PURE__ */ jsxs3("div", { className: "flex flex-col gap-3", children: [
483
459
  identity.dev ? /* @__PURE__ */ jsx3(Button, { variant: "primary", disabled: busy, onClick: () => void attempt(() => identity.dev?.() ?? Promise.resolve()), children: "Sign in again (dev)" }) : null,
484
- account10?.providers.map((p) => /* @__PURE__ */ jsxs3(Button, { variant: identity.dev ? "outline" : "primary", disabled: busy, onClick: () => void attempt(() => identity.withProvider(p), false), children: [
485
- "Continue with ",
486
- providerLabel(p)
487
- ] }, p)),
460
+ account10?.providers.map((p) => /* @__PURE__ */ jsxs3(
461
+ Button,
462
+ {
463
+ variant: identity.dev ? "outline" : "primary",
464
+ disabled: busy,
465
+ onClick: () => void attempt(async () => {
466
+ if (await identity.withProvider(p) === "confirmed") onDone();
467
+ }, false),
468
+ children: [
469
+ "Continue with ",
470
+ providerLabel(p)
471
+ ]
472
+ },
473
+ p
474
+ )),
488
475
  account10?.hasPassword ? /* @__PURE__ */ jsxs3("form", { className: "flex gap-2", onSubmit: (e) => {
489
476
  e.preventDefault();
490
477
  if (password) void attempt(() => identity.withPassword(password));
@@ -511,6 +498,7 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
511
498
  import { useEffect as useEffect5, useState as useState5 } from "react";
512
499
  import { Badge, Button as Button2, Field as Field2, Textarea } from "@ai-matrx/design-system/controls";
513
500
  import { cn as cn3 } from "@ai-matrx/design-system";
501
+ import { CopyIcon } from "@ai-matrx/design-system/icons";
514
502
 
515
503
  // src/hooks.ts
516
504
  import { createContext as createContext3, createElement, useCallback as useCallback2, useContext as useContext3, useEffect as useEffect3, useLayoutEffect, useRef as useRef3, useState as useState3 } from "react";
@@ -560,7 +548,7 @@ function useElementWidth(ref) {
560
548
  // src/ui.tsx
561
549
  import { createContext as createContext4, useContext as useContext4, useEffect as useEffect4, useState as useState4 } from "react";
562
550
  import { Dialog as Dialog2, DialogContent as DialogContent2, DialogFooter, DialogHeader as DialogHeader2, DialogTitle as DialogTitle2 } from "@ai-matrx/design-system";
563
- import { cn as cn2 } from "@ai-matrx/design-system";
551
+ import { cn as cn2, useLook } from "@ai-matrx/design-system";
564
552
  import { jsx as jsx4, jsxs as jsxs4 } from "react/jsx-runtime";
565
553
  var InPanel = createContext4(false);
566
554
  var Room = createContext4(null);
@@ -579,14 +567,15 @@ function useRoomOf(ref) {
579
567
  return room;
580
568
  }
581
569
  var RoomProvider = Room.Provider;
582
- function Section({ title, actions, children, className }) {
570
+ function VaultSection({ title, actions, children, className }) {
583
571
  const flat = useContext4(InPanel);
572
+ const desktop = useLook() === "desktop";
584
573
  return /* @__PURE__ */ jsxs4("section", { className: cn2("flex flex-col gap-1.5", className), children: [
585
574
  title || actions ? /* @__PURE__ */ jsxs4("div", { className: "flex min-h-7 items-center justify-between gap-2 px-1", children: [
586
- title ? /* @__PURE__ */ jsx4("h3", { className: "text-xs font-medium text-muted-foreground", children: title }) : /* @__PURE__ */ jsx4("span", {}),
575
+ title ? /* @__PURE__ */ jsx4("h3", { className: desktop ? "text-sm font-semibold text-foreground" : "text-xs font-medium text-muted-foreground", children: title }) : /* @__PURE__ */ jsx4("span", {}),
587
576
  actions ? /* @__PURE__ */ jsx4("div", { className: "flex items-center gap-1", children: actions }) : null
588
577
  ] }) : null,
589
- /* @__PURE__ */ jsx4("div", { className: flat ? "-mx-3 flex flex-col sm:-mx-4" : "flex flex-col rounded-xl border border-border bg-card py-1", children })
578
+ /* @__PURE__ */ jsx4("div", { className: flat ? "-mx-3 flex flex-col sm:-mx-4" : desktop ? "flex flex-col divide-y divide-border rounded-xl bg-card" : "flex flex-col rounded-xl border border-border bg-card py-1", children })
590
579
  ] });
591
580
  }
592
581
  var ROW_GRID = {
@@ -594,7 +583,7 @@ var ROW_GRID = {
594
583
  roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
595
584
  viewport: "grid-cols-[5.75rem_minmax(0,1fr)_auto] gap-x-2 px-3 sm:grid-cols-[9rem_minmax(0,1fr)_auto] sm:gap-x-3 sm:px-4"
596
585
  };
597
- function Row({ label, hint, children, actions, top = false, className }) {
586
+ function VaultRow({ label, hint, children, actions, top = false, className }) {
598
587
  const room = useContext4(Room);
599
588
  return /* @__PURE__ */ jsxs4("div", { className: cn2("grid min-h-11 py-1", ROW_GRID[room ?? "viewport"], top ? "items-start" : "items-center", className), children: [
600
589
  /* @__PURE__ */ jsxs4("div", { className: cn2("flex min-w-0 flex-col text-xs leading-tight text-muted-foreground", top && "pt-2.5"), children: [
@@ -615,11 +604,6 @@ function Panel({ title, open = true, onClose, children, footer, size = "lg" }) {
615
604
  footer ? /* @__PURE__ */ jsx4(DialogFooter, { children: footer }) : null
616
605
  ] }) });
617
606
  }
618
- function formatBytes(n) {
619
- if (n < 1024) return `${n} B`;
620
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
621
- return `${(n / 1024 / 1024).toFixed(1)} MB`;
622
- }
623
607
  var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
624
608
 
625
609
  // src/FieldRows.tsx
@@ -678,14 +662,14 @@ function SecretRow({ port, item, field, extra }) {
678
662
  const multiline = field.kind === "multiline";
679
663
  const shown = visible ? plain : secret.value;
680
664
  return /* @__PURE__ */ jsx5(
681
- Row,
665
+ VaultRow,
682
666
  {
683
667
  label: field.label,
684
668
  top: multiline && shown !== null,
685
669
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
686
670
  extra,
687
671
  canSee && !visible ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ jsx5(EyeOffGlyph, {}) : /* @__PURE__ */ jsx5(EyeGlyph, {}), "aria-label": secret.value !== null ? `Hide ${field.label}` : `Show ${field.label}`, disabled: busy, onClick: () => void toggle2() }) : null,
688
- canSee ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(CopyGlyph, {}), "aria-label": `Copy ${field.label}`, disabled: busy, onClick: () => void copy() }) : null
672
+ canSee ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(CopyIcon, {}), "aria-label": `Copy ${field.label}`, disabled: busy, onClick: () => void copy() }) : null
689
673
  ] }),
690
674
  children: sealed ? /* @__PURE__ */ jsx5(Badge, { icon: /* @__PURE__ */ jsx5(LockGlyph, {}), children: "Sealed" }) : off ? /* @__PURE__ */ jsx5("span", { className: "text-muted-foreground", children: "Turned off" }) : error ? /* @__PURE__ */ jsx5("span", { className: "truncate text-destructive", title: error, children: error }) : shown !== null ? visible ? /* @__PURE__ */ jsx5("span", { className: cn3("block", multiline ? "whitespace-pre-wrap break-words" : "truncate"), children: shown || "\u2014" }) : /* @__PURE__ */ jsx5(SecretText, { value: shown, multiline }) : /* @__PURE__ */ jsx5("span", { className: cn3("block truncate text-muted-foreground", !visible && "tracking-widest"), children: visible ? "\u2026" : MASK })
691
675
  }
@@ -695,7 +679,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
695
679
  const copyValue2 = useCopy();
696
680
  const isUrl = /^https?:\/\//i.test(value);
697
681
  return /* @__PURE__ */ jsx5(
698
- Row,
682
+ VaultRow,
699
683
  {
700
684
  label,
701
685
  hint,
@@ -703,7 +687,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
703
687
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
704
688
  extra,
705
689
  isUrl && openUrl ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(ExternalGlyph, {}), "aria-label": `Open ${value}`, onClick: () => openUrl(value) }) : null,
706
- /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(CopyGlyph, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void copyValue2(value, typeof label === "string" && label ? label : "Value", { secret: false }) })
690
+ /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(CopyIcon, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void copyValue2(value, typeof label === "string" && label ? label : "Value", { secret: false }) })
707
691
  ] }),
708
692
  children: isUrl && openUrl ? (
709
693
  // A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
@@ -726,12 +710,12 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
726
710
  );
727
711
  }
728
712
  function AddRow({ label, onAdd, children = "Add" }) {
729
- return /* @__PURE__ */ jsx5(Row, { label, children: onAdd ? /* @__PURE__ */ jsx5("button", { type: "button", className: "text-sm text-muted-foreground hover:text-primary", onClick: onAdd, children }) : /* @__PURE__ */ jsx5("span", { className: "text-disabled-foreground", children: "\u2014" }) });
713
+ return /* @__PURE__ */ jsx5(VaultRow, { label, children: onAdd ? /* @__PURE__ */ jsx5("button", { type: "button", className: "text-sm text-muted-foreground hover:text-primary", onClick: onAdd, children }) : /* @__PURE__ */ jsx5("span", { className: "text-disabled-foreground", children: "\u2014" }) });
730
714
  }
731
715
  function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
732
716
  const [shown, setShown] = useState5(false);
733
717
  return /* @__PURE__ */ jsx5(
734
- Row,
718
+ VaultRow,
735
719
  {
736
720
  label,
737
721
  hint,
@@ -748,7 +732,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
748
732
  function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
749
733
  const [shown, setShown] = useState5(false);
750
734
  return /* @__PURE__ */ jsx5(
751
- Row,
735
+ VaultRow,
752
736
  {
753
737
  label: /* @__PURE__ */ jsx5(Field2, { className: "w-full", value: label, onChange: (e) => onLabel(e.target.value), placeholder: "Name", "aria-label": "Field name" }),
754
738
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
@@ -761,6 +745,7 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
761
745
  }
762
746
 
763
747
  // src/activity/HistoryPanel.tsx
748
+ import { CopyIcon as CopyIcon2 } from "@ai-matrx/design-system/icons";
764
749
  import { formatAbsoluteDate as formatAbsoluteDate2 } from "@ai-matrx/kit/format";
765
750
 
766
751
  // src/activity/logic.ts
@@ -1253,7 +1238,7 @@ function ActivityPanel({ item, port, onClose }) {
1253
1238
  footer: hasMore ? /* @__PURE__ */ jsx6(Button3, { variant: "outline", disabled: loading, onClick: () => setLimit((n) => Math.min(MAX, n * 2)), children: loading ? "Loading\u2026" : "Show more" }) : void 0,
1254
1239
  children: [
1255
1240
  error ? /* @__PURE__ */ jsx6("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
1256
- entries === null ? loading ? /* @__PURE__ */ jsx6(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ jsx6(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ jsx6(Section, { title: day.label, children: collapseRuns(
1241
+ entries === null ? loading ? /* @__PURE__ */ jsx6(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ jsx6(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ jsx6(VaultSection, { title: day.label, children: collapseRuns(
1257
1242
  day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
1258
1243
  (r) => `${r.s.what}|${r.s.who ?? ""}`
1259
1244
  ).map(({ row: { entry, s }, times }) => {
@@ -1276,7 +1261,7 @@ function ActivityPanel({ item, port, onClose }) {
1276
1261
  import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1277
1262
  var MASK2 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
1278
1263
  var messageOf = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
1279
- function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1264
+ function ItemHistoryPanel({ item, port, arg, onClose, onChanged }) {
1280
1265
  const eligible = historyEligible(item);
1281
1266
  const [page, setPage] = useState7(null);
1282
1267
  const [loading, setLoading] = useState7(eligible);
@@ -1338,7 +1323,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1338
1323
  error ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
1339
1324
  notice ? /* @__PURE__ */ jsx7("p", { role: "status", className: "px-1 text-sm text-success", children: notice }) : null,
1340
1325
  page && groups.length === 0 ? /* @__PURE__ */ jsx7(Empty, { children: "No earlier values yet." }) : null,
1341
- page ? groups.map((g) => /* @__PURE__ */ jsx7(Section, { title: g.label, children: g.entries.map((entry) => /* @__PURE__ */ jsx7(HistoryRow, { item, port, page, entry, label: g.label, onRestored: restored, onConflict: conflicted, onError: setError }, `${item.id}:${entry.fieldId}:${entry.revision}`)) }, g.fieldId)) : null,
1326
+ page ? groups.map((g) => /* @__PURE__ */ jsx7(VaultSection, { title: g.label, children: g.entries.map((entry) => /* @__PURE__ */ jsx7(HistoryRow, { item, port, page, entry, label: g.label, onRestored: restored, onConflict: conflicted, onError: setError }, `${item.id}:${entry.fieldId}:${entry.revision}`)) }, g.fieldId)) : null,
1342
1327
  page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
1343
1328
  page.captureStartedAt ? /* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
1344
1329
  "Kept since ",
@@ -1399,12 +1384,12 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1399
1384
  }
1400
1385
  }
1401
1386
  return /* @__PURE__ */ jsx7(
1402
- Row,
1387
+ VaultRow,
1403
1388
  {
1404
1389
  label: when,
1405
1390
  actions: entry.available ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
1406
1391
  /* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ jsx7(EyeOffGlyph, {}) : /* @__PURE__ */ jsx7(EyeGlyph, {}), "aria-label": secret.value !== null ? "Hide" : "Show", disabled: busy, onClick: () => void toggle2() }),
1407
- /* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(CopyGlyph, {}), "aria-label": "Copy", disabled: busy, onClick: () => void copy() }),
1392
+ /* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(CopyIcon2, {}), "aria-label": "Copy", disabled: busy, onClick: () => void copy() }),
1408
1393
  canRestore(page, entry) ? /* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(RestoreGlyph, {}), "aria-label": "Restore", disabled: busy, onClick: () => void restore() }) : null
1409
1394
  ] }) : null,
1410
1395
  children: !entry.available ? /* @__PURE__ */ jsx7(Badge2, { children: "Not kept" }) : secret.value !== null ? /* @__PURE__ */ jsx7(SecretText, { value: secret.value, multiline: false }) : /* @__PURE__ */ jsx7("span", { className: "block truncate tracking-widest text-muted-foreground", children: MASK2 })
@@ -1416,6 +1401,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1416
1401
  import { useEffect as useEffect11, useState as useState13 } from "react";
1417
1402
  import { Button as Button9 } from "@ai-matrx/design-system/controls";
1418
1403
  import { cn as cn6, DropdownMenu as DropdownMenu2, DropdownMenuContent as DropdownMenuContent2, DropdownMenuItem as DropdownMenuItem2, DropdownMenuSeparator as DropdownMenuSeparator2, DropdownMenuTrigger as DropdownMenuTrigger2, TextInputDialog } from "@ai-matrx/design-system";
1404
+ import { CopyIcon as CopyIcon4 } from "@ai-matrx/design-system/icons";
1419
1405
 
1420
1406
  // src/authenticator/AddOtpPanel.tsx
1421
1407
  import { useState as useState12 } from "react";
@@ -1425,8 +1411,11 @@ import { Button as Button8, Field as Field4, Select as Select2 } from "@ai-matrx
1425
1411
  import { useEffect as useEffect8, useRef as useRef6, useState as useState8 } from "react";
1426
1412
  import { Button as Button5 } from "@ai-matrx/design-system/controls";
1427
1413
  import { cn as cn5 } from "@ai-matrx/design-system";
1414
+ import { CopyIcon as CopyIcon3 } from "@ai-matrx/design-system/icons";
1415
+ import { groupCode as groupCode2 } from "@ai-matrx/kit/format";
1428
1416
 
1429
1417
  // src/authenticator/otpauth.ts
1418
+ import { groupCode } from "@ai-matrx/kit/format";
1430
1419
  var TOTP_DEFAULT_DIGITS = 6;
1431
1420
  var TOTP_DEFAULT_PERIOD = 30;
1432
1421
  var TOTP_DEFAULT_ALGORITHM = "SHA1";
@@ -1494,12 +1483,6 @@ function describeEnrollment(parsed) {
1494
1483
  const parts = [parsed.issuer, parsed.account].filter((p) => Boolean(p));
1495
1484
  return parts.length ? parts.join(" \xB7 ") : "Setup key";
1496
1485
  }
1497
- function groupCode(code) {
1498
- const c = code.replace(/\s/g, "");
1499
- if (c.length < 6) return c;
1500
- const head = Math.ceil(c.length / 2);
1501
- return `${c.slice(0, head)} ${c.slice(head)}`;
1502
- }
1503
1486
  function maskedCode(digits = TOTP_DEFAULT_DIGITS) {
1504
1487
  return groupCode("\u2022".repeat(Math.max(6, digits)));
1505
1488
  }
@@ -1577,7 +1560,7 @@ function useCopied() {
1577
1560
  }
1578
1561
  function CodeButton({ live, digits, size = "md", label }) {
1579
1562
  const { copied, copy } = useCopied();
1580
- const shown = live.code ? groupCode(live.code) : maskedCode(digits);
1563
+ const shown = live.code ? groupCode2(live.code) : maskedCode(digits);
1581
1564
  return /* @__PURE__ */ jsxs8(
1582
1565
  "button",
1583
1566
  {
@@ -1596,7 +1579,7 @@ function CodeButton({ live, digits, size = "md", label }) {
1596
1579
  }
1597
1580
  function CopyCodeButton({ live, label }) {
1598
1581
  const { copied, copy } = useCopied();
1599
- return /* @__PURE__ */ jsx8(Button5, { variant: "quiet", icon: copied ? /* @__PURE__ */ jsx8(CheckGlyph, {}) : /* @__PURE__ */ jsx8(CopyGlyph, {}), ...copied ? { glyphTone: "success" } : {}, "aria-label": `Copy ${label} code`, disabled: !live.code, onClick: () => live.code && void copy(live.code) });
1582
+ return /* @__PURE__ */ jsx8(Button5, { variant: "quiet", icon: copied ? /* @__PURE__ */ jsx8(CheckGlyph, {}) : /* @__PURE__ */ jsx8(CopyIcon3, {}), ...copied ? { glyphTone: "success" } : {}, "aria-label": `Copy ${label} code`, disabled: !live.code, onClick: () => live.code && void copy(live.code) });
1600
1583
  }
1601
1584
 
1602
1585
  // src/authenticator/live-code.ts
@@ -1868,7 +1851,7 @@ function OtpSetupRow({ value, onChange, label = "One-time password", placeholder
1868
1851
  className: dragging ? "rounded-lg bg-accent" : void 0,
1869
1852
  children: [
1870
1853
  /* @__PURE__ */ jsxs9(
1871
- Row,
1854
+ VaultRow,
1872
1855
  {
1873
1856
  label,
1874
1857
  actions: /* @__PURE__ */ jsxs9(Fragment4, { children: [
@@ -2018,7 +2001,7 @@ function TotpRow({ port, item, onChanged }) {
2018
2001
  ] })
2019
2002
  ] }) : null;
2020
2003
  return /* @__PURE__ */ jsx10(
2021
- Row,
2004
+ VaultRow,
2022
2005
  {
2023
2006
  label: "One-time password",
2024
2007
  actions: /* @__PURE__ */ jsxs10(Fragment5, { children: [
@@ -2077,7 +2060,7 @@ function TwoFactorMethodRow({ port, item, onChanged }) {
2077
2060
  const [busy, setBusy] = useState11(false);
2078
2061
  const [error, setError] = useState11(null);
2079
2062
  const canEdit = item.capabilities.canEdit || item.capabilities.canManage;
2080
- return /* @__PURE__ */ jsx10(Row, { label: "Two-factor", hint: error ? /* @__PURE__ */ jsx10("span", { className: "text-destructive", children: error }) : void 0, children: /* @__PURE__ */ jsx10(
2063
+ return /* @__PURE__ */ jsx10(VaultRow, { label: "Two-factor", hint: error ? /* @__PURE__ */ jsx10("span", { className: "text-destructive", children: error }) : void 0, children: /* @__PURE__ */ jsx10(
2081
2064
  Select,
2082
2065
  {
2083
2066
  value: value ?? "none",
@@ -2192,7 +2175,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2192
2175
  /* @__PURE__ */ jsx11(Button8, { variant: "primary", disabled: !ready, onClick: () => void save(), children: busy ? "Adding\u2026" : "Add" })
2193
2176
  ] }),
2194
2177
  children: [
2195
- /* @__PURE__ */ jsxs11(Section, { children: [
2178
+ /* @__PURE__ */ jsxs11(VaultSection, { children: [
2196
2179
  /* @__PURE__ */ jsx11(
2197
2180
  OtpSetupRow,
2198
2181
  {
@@ -2214,7 +2197,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2214
2197
  status: image ? `QR image ready \xB7 ${image.name}` : null
2215
2198
  }
2216
2199
  ),
2217
- /* @__PURE__ */ jsx11(Row, { label: "Add to", children: /* @__PURE__ */ jsx11(
2200
+ /* @__PURE__ */ jsx11(VaultRow, { label: "Add to", children: /* @__PURE__ */ jsx11(
2218
2201
  Select2,
2219
2202
  {
2220
2203
  value: target,
@@ -2228,7 +2211,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2228
2211
  }
2229
2212
  ) }),
2230
2213
  isNew ? /* @__PURE__ */ jsxs11(Fragment6, { children: [
2231
- /* @__PURE__ */ jsx11(Row, { label: "Name", children: /* @__PURE__ */ jsx11(
2214
+ /* @__PURE__ */ jsx11(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx11(
2232
2215
  Field4,
2233
2216
  {
2234
2217
  className: "w-full",
@@ -2242,7 +2225,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2242
2225
  "aria-label": "Name"
2243
2226
  }
2244
2227
  ) }),
2245
- /* @__PURE__ */ jsx11(Row, { label: "Website", hint: websiteBad ? /* @__PURE__ */ jsx11("span", { className: "text-destructive", children: "Not a web address" }) : void 0, children: /* @__PURE__ */ jsx11(Field4, { className: "w-full", type: "url", value: website, disabled: busy || created !== null, onChange: (e) => setWebsite(e.target.value), placeholder: "example.com", "aria-label": "Website", "aria-invalid": websiteBad || void 0 }) })
2228
+ /* @__PURE__ */ jsx11(VaultRow, { label: "Website", hint: websiteBad ? /* @__PURE__ */ jsx11("span", { className: "text-destructive", children: "Not a web address" }) : void 0, children: /* @__PURE__ */ jsx11(Field4, { className: "w-full", type: "url", value: website, disabled: busy || created !== null, onChange: (e) => setWebsite(e.target.value), placeholder: "example.com", "aria-label": "Website", "aria-invalid": websiteBad || void 0 }) })
2246
2229
  ] }) : null
2247
2230
  ] }),
2248
2231
  error ? /* @__PURE__ */ jsx11("p", { className: "px-1 text-sm text-destructive", role: "alert", children: error }) : null
@@ -2310,7 +2293,7 @@ function AuthenticatorView({ port, items, definitions, query, onOpen, onChanged,
2310
2293
  /* @__PURE__ */ jsx12("span", { className: "flex size-12 items-center justify-center rounded-full bg-muted text-muted-foreground", children: /* @__PURE__ */ jsx12(ShieldGlyph, { className: "size-6" }) }),
2311
2294
  /* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-foreground", children: "No one-time passwords yet" }),
2312
2295
  /* @__PURE__ */ jsx12(Button9, { variant: "primary", icon: /* @__PURE__ */ jsx12(PlusGlyph, {}), onClick: () => setAdding(true), children: "Add one-time password" })
2313
- ] }) : groups.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ jsx12("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ jsx12("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ jsx12(Section, { ...groups.length > 1 ? { title: g.label } : {}, className: "[&>div]:px-1", children: g.items.map((item) => /* @__PURE__ */ jsx12(
2296
+ ] }) : groups.length === 0 ? /* @__PURE__ */ jsx12("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ jsx12("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ jsx12("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ jsx12(VaultSection, { ...groups.length > 1 ? { title: g.label } : {}, className: "[&>div]:px-1", children: g.items.map((item) => /* @__PURE__ */ jsx12(
2314
2297
  OtpListRow,
2315
2298
  {
2316
2299
  port,
@@ -2404,7 +2387,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2404
2387
  "Open login"
2405
2388
  ] }),
2406
2389
  live.code ? /* @__PURE__ */ jsxs12(DropdownMenuItem2, { onSelect: () => live.code && void copy(live.code), children: [
2407
- /* @__PURE__ */ jsx12(CopyGlyph, { className: "size-4" }),
2390
+ /* @__PURE__ */ jsx12(CopyIcon4, { className: "size-4" }),
2408
2391
  "Copy code"
2409
2392
  ] }) : null,
2410
2393
  canManage ? /* @__PURE__ */ jsxs12(Fragment7, { children: [
@@ -2431,6 +2414,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2431
2414
  import { useRef as useRef9, useState as useState14 } from "react";
2432
2415
  import { Badge as Badge3, Button as Button10, DisclosureHeader, Field as Field5, SegmentedControl, Select as Select3, Switch } from "@ai-matrx/design-system/controls";
2433
2416
  import { confirm as confirm3 } from "@ai-matrx/kit/confirm-opener";
2417
+ import { GlobeIcon as GlobeIcon2 } from "@ai-matrx/design-system/icons";
2434
2418
 
2435
2419
  // src/fields/rules.ts
2436
2420
  var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -2580,7 +2564,7 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2580
2564
  const locked = !canEdit || busy !== null;
2581
2565
  return /* @__PURE__ */ jsxs13(Panel, { title: `${field.label} settings`, size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
2582
2566
  !canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
2583
- /* @__PURE__ */ jsx13(Section, { title: "Who can see it", children: /* @__PURE__ */ jsx13(Row, { label: "Value", hint: quietHint(handling.hint), children: field.handling === "sealed" ? /* @__PURE__ */ jsx13(Badge3, { icon: /* @__PURE__ */ jsx13(LockGlyph, {}), children: "Sealed for good" }) : /* @__PURE__ */ jsx13(
2567
+ /* @__PURE__ */ jsx13(VaultSection, { title: "Who can see it", children: /* @__PURE__ */ jsx13(VaultRow, { label: "Value", hint: quietHint(handling.hint), children: field.handling === "sealed" ? /* @__PURE__ */ jsx13(Badge3, { icon: /* @__PURE__ */ jsx13(LockGlyph, {}), children: "Sealed for good" }) : /* @__PURE__ */ jsx13(
2584
2568
  SegmentedControl,
2585
2569
  {
2586
2570
  "aria-label": "Who can see it",
@@ -2589,8 +2573,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2589
2573
  data: handlingChoices(field.handling).map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint, disabled: locked }))
2590
2574
  }
2591
2575
  ) }) }),
2592
- /* @__PURE__ */ jsxs13(Section, { title: "Automation", children: [
2593
- /* @__PURE__ */ jsx13(Row, { label: "Env key", hint: envProblem ? quietHint(envProblem, "destructive") : quietHint("The name sandboxes and workflows use"), children: /* @__PURE__ */ jsx13(
2576
+ /* @__PURE__ */ jsxs13(VaultSection, { title: "Automation", children: [
2577
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Env key", hint: envProblem ? quietHint(envProblem, "destructive") : quietHint("The name sandboxes and workflows use"), children: /* @__PURE__ */ jsx13(
2594
2578
  Field5,
2595
2579
  {
2596
2580
  ref: envRef,
@@ -2610,10 +2594,10 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2610
2594
  }
2611
2595
  }
2612
2596
  ) }),
2613
- /* @__PURE__ */ jsx13(Row, { label: "Use in sandbox", hint: blocker && !field.injectIntoSandbox ? quietHint(blocker) : quietHint("Sandboxes get it as an env variable"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Use in sandbox", checked: field.injectIntoSandbox, disabled: locked, onCheckedChange: (v) => void setSandbox(v) }) })
2597
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Use in sandbox", hint: blocker && !field.injectIntoSandbox ? quietHint(blocker) : quietHint("Sandboxes get it as an env variable"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Use in sandbox", checked: field.injectIntoSandbox, disabled: locked, onCheckedChange: (v) => void setSandbox(v) }) })
2614
2598
  ] }),
2615
- /* @__PURE__ */ jsxs13(Section, { title: "Field", children: [
2616
- /* @__PURE__ */ jsx13(Row, { label: "Description", children: /* @__PURE__ */ jsx13(
2599
+ /* @__PURE__ */ jsxs13(VaultSection, { title: "Field", children: [
2600
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Description", children: /* @__PURE__ */ jsx13(
2617
2601
  Field5,
2618
2602
  {
2619
2603
  className: "w-full",
@@ -2629,8 +2613,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2629
2613
  }
2630
2614
  }
2631
2615
  ) }),
2632
- /* @__PURE__ */ jsx13(Row, { label: "Editable", hint: quietHint(field.editable ? "The value can be changed" : "The value is locked"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Editable", checked: field.editable, disabled: locked, onCheckedChange: (v) => void update("editable", { editable: v }) }) }),
2633
- /* @__PURE__ */ jsx13(Row, { label: "Active", hint: quietHint(field.active ? "In use" : "Kept, but nothing uses it"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Active", checked: field.active, disabled: locked, onCheckedChange: (v) => void update("active", { active: v }) }) })
2616
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Editable", hint: quietHint(field.editable ? "The value can be changed" : "The value is locked"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Editable", checked: field.editable, disabled: locked, onCheckedChange: (v) => void update("editable", { editable: v }) }) }),
2617
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Active", hint: quietHint(field.active ? "In use" : "Kept, but nothing uses it"), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Active", checked: field.active, disabled: locked, onCheckedChange: (v) => void update("active", { active: v }) }) })
2634
2618
  ] }),
2635
2619
  error ? /* @__PURE__ */ jsx13(Problem, { children: error }) : null
2636
2620
  ] });
@@ -2661,8 +2645,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2661
2645
  const fillHint = !hasWebsite ? "Add a website first" : item.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically";
2662
2646
  return /* @__PURE__ */ jsxs13(Panel, { title: "Item settings", size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
2663
2647
  !canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
2664
- /* @__PURE__ */ jsxs13(Section, { title: "In the browser", children: [
2665
- /* @__PURE__ */ jsx13(Row, { label: "Website matching", hint: quietHint(MATCH_WORDS[item.uriMatchMode].hint), children: /* @__PURE__ */ jsx13(
2648
+ /* @__PURE__ */ jsxs13(VaultSection, { title: "In the browser", children: [
2649
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Website matching", hint: quietHint(MATCH_WORDS[item.uriMatchMode].hint), children: /* @__PURE__ */ jsx13(
2666
2650
  Select3,
2667
2651
  {
2668
2652
  "aria-label": "Website matching",
@@ -2672,13 +2656,13 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2672
2656
  onValueChange: (m) => void save("match", () => port.fields.updateItem(item, { uriMatchMode: m }))
2673
2657
  }
2674
2658
  ) }),
2675
- /* @__PURE__ */ jsx13(Row, { label: "Fill in browser", hint: quietHint(fillHint), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Fill in browser", checked: hasWebsite && item.browserFillEnabled, disabled: locked || !hasWebsite, onCheckedChange: (v) => void save("fill", () => port.fields.updateItem(item, { browserFillEnabled: v })) }) }),
2659
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Fill in browser", hint: quietHint(fillHint), children: /* @__PURE__ */ jsx13(Switch, { "aria-label": "Fill in browser", checked: hasWebsite && item.browserFillEnabled, disabled: locked || !hasWebsite, onCheckedChange: (v) => void save("fill", () => port.fields.updateItem(item, { browserFillEnabled: v })) }) }),
2676
2660
  promotable.map((f) => /* @__PURE__ */ jsx13(
2677
- Row,
2661
+ VaultRow,
2678
2662
  {
2679
2663
  label: f.label,
2680
2664
  hint: quietHint("Encrypted, so the browser can\u2019t match it"),
2681
- actions: /* @__PURE__ */ jsx13(Button10, { variant: "outline", icon: /* @__PURE__ */ jsx13(GlobeGlyph, {}), disabled: locked, onClick: () => void promote(f), children: "Use as website" }),
2665
+ actions: /* @__PURE__ */ jsx13(Button10, { variant: "outline", icon: /* @__PURE__ */ jsx13(GlobeIcon2, {}), disabled: locked, onClick: () => void promote(f), children: "Use as website" }),
2682
2666
  children: /* @__PURE__ */ jsx13("span", { className: "text-muted-foreground", children: "Not a website yet" })
2683
2667
  },
2684
2668
  f.id
@@ -2686,8 +2670,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2686
2670
  ] }),
2687
2671
  /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1.5", children: [
2688
2672
  /* @__PURE__ */ jsx13(DisclosureHeader, { open: advanced, title: "Advanced", meta: item.fields.length ? `${item.fields.length} fields` : void 0, onClick: () => setAdvanced((a) => !a) }),
2689
- advanced ? /* @__PURE__ */ jsx13(Section, { children: item.fields.length === 0 ? /* @__PURE__ */ jsx13(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ jsx13(
2690
- Row,
2673
+ advanced ? /* @__PURE__ */ jsx13(VaultSection, { children: item.fields.length === 0 ? /* @__PURE__ */ jsx13(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ jsx13(
2674
+ VaultRow,
2691
2675
  {
2692
2676
  label: f.label,
2693
2677
  actions: /* @__PURE__ */ jsx13(Button10, { variant: "quiet", icon: /* @__PURE__ */ jsx13(SlidersGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) }),
@@ -2712,6 +2696,7 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2712
2696
  import { createContext as createContext5, useContext as useContext5, useEffect as useEffect12, useRef as useRef10, useState as useState15 } from "react";
2713
2697
  import { Popover, PopoverContent, PopoverTrigger, cn as cn7 } from "@ai-matrx/design-system";
2714
2698
  import { Button as Button11, NumberStepper, SegmentedControl as SegmentedControl2, Select as Select4, Switch as Switch2 } from "@ai-matrx/design-system/controls";
2699
+ import { CopyIcon as CopyIcon5 } from "@ai-matrx/design-system/icons";
2715
2700
 
2716
2701
  // src/generator/generate.ts
2717
2702
  import {
@@ -2869,7 +2854,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
2869
2854
  /* @__PURE__ */ jsxs14("div", { className: "flex min-h-7 items-start gap-1", children: [
2870
2855
  /* @__PURE__ */ jsx14("code", { className: cn7("min-w-0 flex-1 break-all py-1 font-mono text-sm", candidate ? "text-foreground" : "text-muted-foreground"), "data-testid": "generated-value", children: candidate ? revealed ? candidate.value : MASK3 : "\u2014" }),
2871
2856
  /* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: revealed ? /* @__PURE__ */ jsx14(EyeOffGlyph, {}) : /* @__PURE__ */ jsx14(EyeGlyph, {}), "aria-label": revealed ? "Hide" : "Reveal", disabled: !candidate, onClick: () => setRevealed((r) => !r) }),
2872
- /* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(CopyGlyph, {}), "aria-label": "Copy", disabled: !candidate, onClick: () => void copy() }),
2857
+ /* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(CopyIcon5, {}), "aria-label": "Copy", disabled: !candidate, onClick: () => void copy() }),
2873
2858
  /* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(RefreshGlyph, {}), "aria-label": "Generate another", onClick: () => change(settings) })
2874
2859
  ] }),
2875
2860
  strength && candidate ? /* @__PURE__ */ jsxs14("p", { className: "text-xs", children: [
@@ -2996,6 +2981,7 @@ function useLocked(lock) {
2996
2981
  }
2997
2982
 
2998
2983
  // src/io/BackupPanel.tsx
2984
+ import { formatFileSize } from "@ai-matrx/kit/format";
2999
2985
  import { useEffect as useEffect13, useRef as useRef11, useState as useState17 } from "react";
3000
2986
  import { Button as Button13, Field as Field6, SegmentedControl as SegmentedControl3, Switch as Switch3 } from "@ai-matrx/design-system/controls";
3001
2987
  import { downloadFile } from "@ai-matrx/kit/download";
@@ -3137,17 +3123,17 @@ function omissionText(o) {
3137
3123
  return `${o.count ?? "Some"} ${what}: ${o.reason.replaceAll("_", " ")}`;
3138
3124
  }
3139
3125
  function Summary({ value }) {
3140
- return /* @__PURE__ */ jsxs16(Section, { children: [
3141
- /* @__PURE__ */ jsx16(Row, { label: "Credentials", children: value.record_count }),
3142
- /* @__PURE__ */ jsx16(Row, { label: "Protected fields", children: value.field_count }),
3143
- /* @__PURE__ */ jsx16(Row, { label: "Files", children: value.attachment_count > 0 ? `${value.attachment_count} \xB7 ${formatBytes(value.attachment_bytes)}` : "0" })
3126
+ return /* @__PURE__ */ jsxs16(VaultSection, { children: [
3127
+ /* @__PURE__ */ jsx16(VaultRow, { label: "Credentials", children: value.record_count }),
3128
+ /* @__PURE__ */ jsx16(VaultRow, { label: "Protected fields", children: value.field_count }),
3129
+ /* @__PURE__ */ jsx16(VaultRow, { label: "Files", children: value.attachment_count > 0 ? `${value.attachment_count} \xB7 ${formatFileSize(value.attachment_bytes)}` : "0" })
3144
3130
  ] });
3145
3131
  }
3146
3132
  function Omissions({ omissions, accepted, onAccepted, verb }) {
3147
3133
  if (omissions.length === 0) return null;
3148
- return /* @__PURE__ */ jsxs16(Section, { title: "Left out", children: [
3149
- omissions.map((o, i) => /* @__PURE__ */ jsx16(Row, { label: o.component.replaceAll("_", " "), children: /* @__PURE__ */ jsx16("span", { className: "block truncate text-muted-foreground", title: omissionText(o), children: omissionText(o) }) }, `${o.component}-${o.source_item_id ?? i}`)),
3150
- /* @__PURE__ */ jsx16(Row, { label: "Accept", hint: `${verb} without these`, children: /* @__PURE__ */ jsx16(Switch3, { checked: accepted, onCheckedChange: onAccepted, "aria-label": `${verb} without these` }) })
3134
+ return /* @__PURE__ */ jsxs16(VaultSection, { title: "Left out", children: [
3135
+ omissions.map((o, i) => /* @__PURE__ */ jsx16(VaultRow, { label: o.component.replaceAll("_", " "), children: /* @__PURE__ */ jsx16("span", { className: "block truncate text-muted-foreground", title: omissionText(o), children: omissionText(o) }) }, `${o.component}-${o.source_item_id ?? i}`)),
3136
+ /* @__PURE__ */ jsx16(VaultRow, { label: "Accept", hint: `${verb} without these`, children: /* @__PURE__ */ jsx16(Switch3, { checked: accepted, onCheckedChange: onAccepted, "aria-label": `${verb} without these` }) })
3151
3137
  ] });
3152
3138
  }
3153
3139
  function BackupPanel({ port, items, onClose, onChanged }) {
@@ -3282,7 +3268,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3282
3268
  ),
3283
3269
  mode === "backup" ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
3284
3270
  /* @__PURE__ */ jsx16(
3285
- Section,
3271
+ VaultSection,
3286
3272
  {
3287
3273
  title: `${selected.size} of ${plural(items.length, "credential")}`,
3288
3274
  actions: /* @__PURE__ */ jsxs16(Fragment9, { children: [
@@ -3301,13 +3287,13 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3301
3287
  backup ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
3302
3288
  /* @__PURE__ */ jsx16(Summary, { value: backup }),
3303
3289
  /* @__PURE__ */ jsx16(Omissions, { omissions: backup.omissions, accepted, onAccepted: setAccepted, verb: "Back up" }),
3304
- /* @__PURE__ */ jsxs16(Section, { children: [
3305
- /* @__PURE__ */ jsx16(Row, { label: "Passphrase", hint: "Not saved. It can't be recovered.", children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) }),
3306
- /* @__PURE__ */ jsx16(Row, { label: "Repeat", ...mismatch ? { hint: "Doesn't match" } : {}, children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: repeat, autoComplete: "new-password", "aria-label": "Repeat the passphrase", onChange: (e) => setRepeat(e.target.value) }) })
3290
+ /* @__PURE__ */ jsxs16(VaultSection, { children: [
3291
+ /* @__PURE__ */ jsx16(VaultRow, { label: "Passphrase", hint: "Not saved. It can't be recovered.", children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) }),
3292
+ /* @__PURE__ */ jsx16(VaultRow, { label: "Repeat", ...mismatch ? { hint: "Doesn't match" } : {}, children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: repeat, autoComplete: "new-password", "aria-label": "Repeat the passphrase", onChange: (e) => setRepeat(e.target.value) }) })
3307
3293
  ] })
3308
3294
  ] }) : null
3309
- ] }) : /* @__PURE__ */ jsx16(Fragment9, { children: !restorePreview ? /* @__PURE__ */ jsxs16(Section, { children: [
3310
- /* @__PURE__ */ jsxs16(Row, { label: "File", ...file ? { hint: file.name } : {}, children: [
3295
+ ] }) : /* @__PURE__ */ jsx16(Fragment9, { children: !restorePreview ? /* @__PURE__ */ jsxs16(VaultSection, { children: [
3296
+ /* @__PURE__ */ jsxs16(VaultRow, { label: "File", ...file ? { hint: file.name } : {}, children: [
3311
3297
  /* @__PURE__ */ jsx16(Button13, { variant: "outline", disabled: busy, onClick: () => fileInput.current?.click(), children: "Choose a backup" }),
3312
3298
  /* @__PURE__ */ jsx16(
3313
3299
  "input",
@@ -3323,11 +3309,11 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3323
3309
  }
3324
3310
  )
3325
3311
  ] }),
3326
- /* @__PURE__ */ jsx16(Row, { label: "Passphrase", children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: passphrase, autoComplete: "current-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) })
3312
+ /* @__PURE__ */ jsx16(VaultRow, { label: "Passphrase", children: /* @__PURE__ */ jsx16(Field6, { type: "password", value: passphrase, autoComplete: "current-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) })
3327
3313
  ] }) : /* @__PURE__ */ jsxs16(Fragment9, { children: [
3328
3314
  /* @__PURE__ */ jsx16(Summary, { value: restorePreview }),
3329
3315
  !result ? /* @__PURE__ */ jsx16(Omissions, { omissions: restorePreview.omissions, accepted, onAccepted: setAccepted, verb: "Restore" }) : null,
3330
- !result ? /* @__PURE__ */ jsx16("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ jsx16(Section, { title: `${result.created} restored \xB7 ${result.replayed} already \xB7 ${result.refused} refused \xB7 ${result.retryable_failure} to retry`, children: result.results.map((r) => /* @__PURE__ */ jsx16(Row, { label: names.get(r.source_item_id) ?? "Credential", children: /* @__PURE__ */ jsxs16("span", { className: r.status === "refused" || r.status === "retryable_failure" ? "text-destructive" : "text-foreground", children: [
3316
+ !result ? /* @__PURE__ */ jsx16("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ jsx16(VaultSection, { title: `${result.created} restored \xB7 ${result.replayed} already \xB7 ${result.refused} refused \xB7 ${result.retryable_failure} to retry`, children: result.results.map((r) => /* @__PURE__ */ jsx16(VaultRow, { label: names.get(r.source_item_id) ?? "Credential", children: /* @__PURE__ */ jsxs16("span", { className: r.status === "refused" || r.status === "retryable_failure" ? "text-destructive" : "text-foreground", children: [
3331
3317
  RECORD_STATUS[r.status],
3332
3318
  r.reason === "alias_conflict" ? " \xB7 name in use" : ""
3333
3319
  ] }) }, r.source_item_id)) })
@@ -3432,7 +3418,7 @@ function ExportPanel({ port, items, onClose }) {
3432
3418
  ] })
3433
3419
  ] }),
3434
3420
  children: [
3435
- /* @__PURE__ */ jsx17(Section, { children: /* @__PURE__ */ jsx17(Row, { label: "Format", hint: format?.hint, children: /* @__PURE__ */ jsx17(
3421
+ /* @__PURE__ */ jsx17(VaultSection, { children: /* @__PURE__ */ jsx17(VaultRow, { label: "Format", hint: format?.hint, children: /* @__PURE__ */ jsx17(
3436
3422
  Select5,
3437
3423
  {
3438
3424
  value: profile,
@@ -3445,7 +3431,7 @@ function ExportPanel({ port, items, onClose }) {
3445
3431
  }
3446
3432
  ) }) }),
3447
3433
  /* @__PURE__ */ jsx17(
3448
- Section,
3434
+ VaultSection,
3449
3435
  {
3450
3436
  title: `${selected.size} of ${plural(logins.length, "login")}`,
3451
3437
  actions: /* @__PURE__ */ jsxs17(Fragment10, { children: [
@@ -4516,13 +4502,13 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4516
4502
  /* @__PURE__ */ jsx18(Button15, { variant: "primary", onClick: onClose, children: "Done" })
4517
4503
  ] });
4518
4504
  return /* @__PURE__ */ jsxs18(Panel, { title: "Import", size: "xl", onClose, footer, children: [
4519
- stage === "choose" ? /* @__PURE__ */ jsxs18(Section, { children: [
4520
- /* @__PURE__ */ jsx18(Row, { label: "Source", actions: help && host.openUrl ? /* @__PURE__ */ jsx18(Button15, { variant: "quiet", onClick: () => host.openUrl?.(help), children: "How to export" }) : void 0, children: /* @__PURE__ */ jsx18(Select6, { value: source, options: SOURCE_OPTIONS, "aria-label": "Source", onValueChange: (s) => {
4505
+ stage === "choose" ? /* @__PURE__ */ jsxs18(VaultSection, { children: [
4506
+ /* @__PURE__ */ jsx18(VaultRow, { label: "Source", actions: help && host.openUrl ? /* @__PURE__ */ jsx18(Button15, { variant: "quiet", onClick: () => host.openUrl?.(help), children: "How to export" }) : void 0, children: /* @__PURE__ */ jsx18(Select6, { value: source, options: SOURCE_OPTIONS, "aria-label": "Source", onValueChange: (s) => {
4521
4507
  setSource(s);
4522
4508
  setError(null);
4523
4509
  } }) }),
4524
- source === "env" ? /* @__PURE__ */ jsx18(Row, { label: ".env text", hint: "Same key updates in place", top: true, children: /* @__PURE__ */ jsx18(Textarea2, { mono: true, rows: 7, value: envText, autoComplete: "off", spellCheck: false, "aria-label": ".env text", placeholder: "OPENAI_API_KEY=sk-...\nDATABASE_URL=postgres://...", onChange: (e) => setEnvText(e.target.value) }) }) : null,
4525
- /* @__PURE__ */ jsxs18(Row, { label: "File", hint: fileName ?? void 0, children: [
4510
+ source === "env" ? /* @__PURE__ */ jsx18(VaultRow, { label: ".env text", hint: "Same key updates in place", top: true, children: /* @__PURE__ */ jsx18(Textarea2, { mono: true, rows: 7, value: envText, autoComplete: "off", spellCheck: false, "aria-label": ".env text", placeholder: "OPENAI_API_KEY=sk-...\nDATABASE_URL=postgres://...", onChange: (e) => setEnvText(e.target.value) }) }) : null,
4511
+ /* @__PURE__ */ jsxs18(VaultRow, { label: "File", hint: fileName ?? void 0, children: [
4526
4512
  /* @__PURE__ */ jsx18(Button15, { variant: "outline", disabled: reading, onClick: () => fileInput.current?.click(), children: reading ? "Reading\u2026" : source === "env" ? "Load a file" : "Choose a file" }),
4527
4513
  /* @__PURE__ */ jsx18(
4528
4514
  "input",
@@ -4539,12 +4525,12 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4539
4525
  }
4540
4526
  )
4541
4527
  ] }),
4542
- source === "env" ? /* @__PURE__ */ jsx18(Row, { label: "Sandboxes", hint: "Pass these values to agent sandboxes", children: /* @__PURE__ */ jsx18(Switch4, { checked: injectSandbox, onCheckedChange: setInjectSandbox, "aria-label": "Use in sandboxes" }) }) : null
4528
+ source === "env" ? /* @__PURE__ */ jsx18(VaultRow, { label: "Sandboxes", hint: "Pass these values to agent sandboxes", children: /* @__PURE__ */ jsx18(Switch4, { checked: injectSandbox, onCheckedChange: setInjectSandbox, "aria-label": "Use in sandboxes" }) }) : null
4543
4529
  ] }) : null,
4544
4530
  stage === "review" && draft ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
4545
- organizations.length > 0 ? /* @__PURE__ */ jsx18(Section, { children: /* @__PURE__ */ jsx18(Row, { label: "Save to", children: /* @__PURE__ */ jsx18(Select6, { value: destination, options: destinationOptions, "aria-label": "Save to", onValueChange: (v) => draft.kind === "file" ? restart({ destination: v }) : setDestination(v) }) }) }) : null,
4531
+ organizations.length > 0 ? /* @__PURE__ */ jsx18(VaultSection, { children: /* @__PURE__ */ jsx18(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx18(Select6, { value: destination, options: destinationOptions, "aria-label": "Save to", onValueChange: (v) => draft.kind === "file" ? restart({ destination: v }) : setDestination(v) }) }) }) : null,
4546
4532
  /* @__PURE__ */ jsx18(
4547
- Section,
4533
+ VaultSection,
4548
4534
  {
4549
4535
  title: draft.kind === "env" ? plural(envKeys.length, "value") : summary(counts, lines.length),
4550
4536
  actions: /* @__PURE__ */ jsxs18(Fragment11, { children: [
@@ -4572,11 +4558,11 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4572
4558
  )
4573
4559
  }
4574
4560
  ),
4575
- draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ jsx18(Section, { children: /* @__PURE__ */ jsx18(Row, { label: "Visible details", hint: "Approve saving websites and public keys in the clear", children: /* @__PURE__ */ jsx18(Switch4, { checked: approvedVisible, disabled: busy, onCheckedChange: setApprovedVisible, "aria-label": "Approve visible details" }) }) }) : null,
4561
+ draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ jsx18(VaultSection, { children: /* @__PURE__ */ jsx18(VaultRow, { label: "Visible details", hint: "Approve saving websites and public keys in the clear", children: /* @__PURE__ */ jsx18(Switch4, { checked: approvedVisible, disabled: busy, onCheckedChange: setApprovedVisible, "aria-label": "Approve visible details" }) }) }) : null,
4576
4562
  draft.kind === "file" ? /* @__PURE__ */ jsx18(Notices, { draft }) : null,
4577
- draft.kind === "file" ? /* @__PURE__ */ jsx18(More, { children: /* @__PURE__ */ jsxs18(Section, { children: [
4578
- /* @__PURE__ */ jsx18(Row, { label: "Browser fill", hint: "Needs username, password and an https address", children: /* @__PURE__ */ jsx18(Switch4, { checked: browserFill, disabled: busy, onCheckedChange: (on) => restart({ browserFill: on }), "aria-label": "Browser fill" }) }),
4579
- draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ jsx18(Row, { label: header || `Column ${index + 1}`, children: /* @__PURE__ */ jsx18(
4563
+ draft.kind === "file" ? /* @__PURE__ */ jsx18(More, { children: /* @__PURE__ */ jsxs18(VaultSection, { children: [
4564
+ /* @__PURE__ */ jsx18(VaultRow, { label: "Browser fill", hint: "Needs username, password and an https address", children: /* @__PURE__ */ jsx18(Switch4, { checked: browserFill, disabled: busy, onCheckedChange: (on) => restart({ browserFill: on }), "aria-label": "Browser fill" }) }),
4565
+ draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ jsx18(VaultRow, { label: header || `Column ${index + 1}`, children: /* @__PURE__ */ jsx18(
4580
4566
  Select6,
4581
4567
  {
4582
4568
  value: draft.mapping[index] ?? "keep",
@@ -4588,16 +4574,16 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4588
4574
  ] }) }) : null,
4589
4575
  ambiguous ? /* @__PURE__ */ jsx18(ErrorLine, { message: "Each of name, username, password, notes and one-time password can be used by one column." }) : null
4590
4576
  ] }) : null,
4591
- stage === "done" && done ? /* @__PURE__ */ jsxs18(Section, { title: "Result", children: [
4592
- /* @__PURE__ */ jsx18(Row, { label: "Created", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.created.length }) }),
4593
- /* @__PURE__ */ jsx18(Row, { label: "Skipped", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.skipped }) }),
4594
- /* @__PURE__ */ jsx18(Row, { label: "Failed", children: /* @__PURE__ */ jsx18("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
4595
- done.untried.length > 0 ? /* @__PURE__ */ jsx18(Row, { label: "Not tried", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.untried.length }) }) : null,
4596
- done.withOtp > 0 ? /* @__PURE__ */ jsx18(Row, { label: "Codes", children: /* @__PURE__ */ jsxs18("span", { className: "text-muted-foreground", children: [
4577
+ stage === "done" && done ? /* @__PURE__ */ jsxs18(VaultSection, { title: "Result", children: [
4578
+ /* @__PURE__ */ jsx18(VaultRow, { label: "Created", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.created.length }) }),
4579
+ /* @__PURE__ */ jsx18(VaultRow, { label: "Skipped", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.skipped }) }),
4580
+ /* @__PURE__ */ jsx18(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx18("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
4581
+ done.untried.length > 0 ? /* @__PURE__ */ jsx18(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.untried.length }) }) : null,
4582
+ done.withOtp > 0 ? /* @__PURE__ */ jsx18(VaultRow, { label: "Codes", children: /* @__PURE__ */ jsxs18("span", { className: "text-muted-foreground", children: [
4597
4583
  plural(done.withOtp, "login"),
4598
4584
  " still need the one-time password added."
4599
4585
  ] }) }) : null,
4600
- done.failed.map((f) => /* @__PURE__ */ jsx18(Row, { label: f.title, children: /* @__PURE__ */ jsx18("span", { className: "block truncate text-destructive", title: f.reason, children: f.reason }) }, f.key))
4586
+ done.failed.map((f) => /* @__PURE__ */ jsx18(VaultRow, { label: f.title, children: /* @__PURE__ */ jsx18("span", { className: "block truncate text-destructive", title: f.reason, children: f.reason }) }, f.key))
4601
4587
  ] }) : null,
4602
4588
  /* @__PURE__ */ jsx18(ErrorLine, { message: error })
4603
4589
  ] });
@@ -4657,11 +4643,13 @@ import { Badge as Badge7, Button as Button21, CONTROLS_CONTAINER_CLASS, OptionCo
4657
4643
  import { confirm as confirm9 } from "@ai-matrx/kit/confirm-opener";
4658
4644
 
4659
4645
  // src/activity/FilesSection.tsx
4646
+ import { formatFileSize as formatFileSize2 } from "@ai-matrx/kit/format";
4660
4647
  import { useRef as useRef13, useState as useState20 } from "react";
4661
4648
  import { Badge as Badge5, Button as Button16, Field as Field7, SegmentedControl as SegmentedControl4 } from "@ai-matrx/design-system/controls";
4662
4649
  import { cn as cn9 } from "@ai-matrx/design-system";
4663
4650
  import { confirm as confirm6 } from "@ai-matrx/kit/confirm-opener";
4664
4651
  import { downloadFile as downloadFile3 } from "@ai-matrx/kit/download";
4652
+ import { DownloadIcon } from "@ai-matrx/design-system/icons";
4665
4653
  import { Fragment as Fragment12, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
4666
4654
  var messageOf2 = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
4667
4655
  var TOO_BIG = "Files over 25 MB can't be stored.";
@@ -4720,7 +4708,7 @@ function FilesSection({ item, port, editing, onChanged }) {
4720
4708
  onDragLeave: canEdit ? () => setDragging(false) : void 0,
4721
4709
  onDrop: canEdit ? drop : void 0,
4722
4710
  children: /* @__PURE__ */ jsxs19(
4723
- Section,
4711
+ VaultSection,
4724
4712
  {
4725
4713
  title: "Files",
4726
4714
  actions: canEdit ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
@@ -4731,11 +4719,11 @@ function FilesSection({ item, port, editing, onChanged }) {
4731
4719
  } }) : null,
4732
4720
  item.attachments.map(
4733
4721
  (a) => canEdit ? /* @__PURE__ */ jsx20(EditableFile, { port, item, file: a, busy, run, onDownload: () => void download(a), onTooBig: () => setError(TOO_BIG) }, a.id) : /* @__PURE__ */ jsx20(
4734
- Row,
4722
+ VaultRow,
4735
4723
  {
4736
4724
  label: a.label,
4737
4725
  hint: a.description || void 0,
4738
- actions: a.handling === "sealed" ? /* @__PURE__ */ jsx20(Badge5, { icon: /* @__PURE__ */ jsx20(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(DownloadGlyph, {}), "aria-label": `Download ${a.fileName}`, disabled: busy !== null, onClick: () => void download(a) }) : null,
4726
+ actions: a.handling === "sealed" ? /* @__PURE__ */ jsx20(Badge5, { icon: /* @__PURE__ */ jsx20(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: busy !== null, onClick: () => void download(a) }) : null,
4739
4727
  children: /* @__PURE__ */ jsx20(FileName, { file: a })
4740
4728
  },
4741
4729
  a.id
@@ -4761,12 +4749,12 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4761
4749
  }
4762
4750
  return /* @__PURE__ */ jsxs19(Fragment12, { children: [
4763
4751
  /* @__PURE__ */ jsx20(
4764
- Row,
4752
+ VaultRow,
4765
4753
  {
4766
4754
  label: a.label,
4767
4755
  hint: a.description || void 0,
4768
4756
  actions: /* @__PURE__ */ jsxs19(Fragment12, { children: [
4769
- canDownload(it, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(DownloadGlyph, {}), "aria-label": `Download ${a.fileName}`, disabled: b !== null, onClick: onDownload }) : null,
4757
+ canDownload(it, a) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: b !== null, onClick: onDownload }) : null,
4770
4758
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PencilGlyph, {}), "aria-label": `Edit ${a.label}`, pressed: open, disabled: b !== null, onClick: () => setOpen((o) => !o) }),
4771
4759
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(UploadGlyph, {}), "aria-label": `Replace ${a.fileName}`, disabled: b !== null, onClick: () => replacer.current?.click() }),
4772
4760
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(TrashGlyph, {}), "aria-label": `Delete ${a.label}`, disabled: b !== null, onClick: () => void remove() }),
@@ -4797,7 +4785,7 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4797
4785
  function FileName({ file }) {
4798
4786
  return /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
4799
4787
  /* @__PURE__ */ jsx20("span", { className: "truncate", children: file.fileName }),
4800
- /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatBytes(file.sizeBytes) })
4788
+ /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatFileSize2(file.sizeBytes) })
4801
4789
  ] });
4802
4790
  }
4803
4791
  function Protection({ value, locked, onChange }) {
@@ -4820,13 +4808,13 @@ function NewFile({ file, busy, onAdd, onCancel }) {
4820
4808
  await onAdd({ label: label.trim(), description: description.trim() || null, handling });
4821
4809
  }
4822
4810
  return /* @__PURE__ */ jsxs19(Fragment12, { children: [
4823
- /* @__PURE__ */ jsx20(Row, { label: "New file", children: /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
4811
+ /* @__PURE__ */ jsx20(VaultRow, { label: "New file", children: /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
4824
4812
  /* @__PURE__ */ jsx20("span", { className: "truncate", children: file.name }),
4825
- /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatBytes(file.size) })
4813
+ /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatFileSize2(file.size) })
4826
4814
  ] }) }),
4827
- /* @__PURE__ */ jsx20(Row, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4828
- /* @__PURE__ */ jsx20(Row, { label: "Purpose", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4829
- /* @__PURE__ */ jsx20(Row, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: false, onChange: setHandling }) }),
4815
+ /* @__PURE__ */ jsx20(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4816
+ /* @__PURE__ */ jsx20(VaultRow, { label: "Purpose", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4817
+ /* @__PURE__ */ jsx20(VaultRow, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: false, onChange: setHandling }) }),
4830
4818
  /* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4831
4819
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4832
4820
  /* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !label.trim(), onClick: () => void add(), children: busy ? "Adding\u2026" : "Add file" })
@@ -4844,10 +4832,10 @@ function FileDetailsRows({ file, busy, onSave, onCancel }) {
4844
4832
  await onSave({ label: label.trim(), description: description.trim() || null, fileName: fileName.trim(), handling });
4845
4833
  }
4846
4834
  return /* @__PURE__ */ jsxs19(Fragment12, { children: [
4847
- /* @__PURE__ */ jsx20(Row, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4848
- /* @__PURE__ */ jsx20(Row, { label: "Purpose", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4849
- /* @__PURE__ */ jsx20(Row, { label: "File name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
4850
- /* @__PURE__ */ jsx20(Row, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: file.handling === "sealed", onChange: setHandling }) }),
4835
+ /* @__PURE__ */ jsx20(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4836
+ /* @__PURE__ */ jsx20(VaultRow, { label: "Purpose", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4837
+ /* @__PURE__ */ jsx20(VaultRow, { label: "File name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
4838
+ /* @__PURE__ */ jsx20(VaultRow, { label: "Protection", children: /* @__PURE__ */ jsx20(Protection, { value: handling, locked: file.handling === "sealed", onChange: setHandling }) }),
4851
4839
  /* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4852
4840
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4853
4841
  /* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !changed || !label.trim() || !fileName.trim(), onClick: () => void save(), children: busy ? "Saving\u2026" : "Save" })
@@ -4866,6 +4854,7 @@ function confirmSeal(label) {
4866
4854
  // src/fields/RecoveryCodesRow.tsx
4867
4855
  import { useState as useState21 } from "react";
4868
4856
  import { Badge as Badge6, Button as Button17, Textarea as Textarea3 } from "@ai-matrx/design-system/controls";
4857
+ import { CopyIcon as CopyIcon6 } from "@ai-matrx/design-system/icons";
4869
4858
  import { Fragment as Fragment13, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
4870
4859
  var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
4871
4860
  var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
@@ -4906,7 +4895,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4906
4895
  };
4907
4896
  if (draft !== null) {
4908
4897
  return /* @__PURE__ */ jsxs20(
4909
- Row,
4898
+ VaultRow,
4910
4899
  {
4911
4900
  label: "Recovery codes",
4912
4901
  top: true,
@@ -4926,7 +4915,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4926
4915
  }
4927
4916
  if (!field) {
4928
4917
  if (!canEdit) return null;
4929
- return /* @__PURE__ */ jsx21(Row, { label: "Recovery codes", actions: /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(PlusGlyph, {}), "aria-label": "Add recovery codes", onClick: () => setDraft("") }), children: /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "None" }) });
4918
+ return /* @__PURE__ */ jsx21(VaultRow, { label: "Recovery codes", actions: /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(PlusGlyph, {}), "aria-label": "Add recovery codes", onClick: () => setDraft("") }), children: /* @__PURE__ */ jsx21("span", { className: "text-muted-foreground", children: "None" }) });
4930
4919
  }
4931
4920
  const sealed = field.handling === "sealed";
4932
4921
  const canSee = !sealed && item.capabilities.canReveal;
@@ -4948,7 +4937,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4948
4937
  });
4949
4938
  };
4950
4939
  return /* @__PURE__ */ jsx21(
4951
- Row,
4940
+ VaultRow,
4952
4941
  {
4953
4942
  label: "Recovery codes",
4954
4943
  top: codes !== null,
@@ -4959,7 +4948,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4959
4948
  children: sealed ? /* @__PURE__ */ jsx21(Badge6, { icon: /* @__PURE__ */ jsx21(LockGlyph, {}), children: "Sealed" }) : codes ? /* @__PURE__ */ jsxs20("ul", { className: "flex flex-col gap-0.5", "aria-label": "Recovery codes", children: [
4960
4949
  codes.map((code, i) => /* @__PURE__ */ jsxs20("li", { className: "flex min-h-7 items-center gap-1", children: [
4961
4950
  /* @__PURE__ */ jsx21("code", { className: "min-w-0 flex-1 break-all font-mono text-sm text-foreground", children: code }),
4962
- /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CopyGlyph, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
4951
+ /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CopyIcon6, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
4963
4952
  canEdit ? /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CheckGlyph, {}), disabled: busy, onClick: () => void markUsed(i), children: "Mark used" }) : null
4964
4953
  ] }, `${i}-${code}`)),
4965
4954
  error ? /* @__PURE__ */ jsx21("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
@@ -4968,33 +4957,17 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4968
4957
  );
4969
4958
  }
4970
4959
 
4960
+ // src/ItemPane.tsx
4961
+ import { HistoryIcon, SettingsIcon, UsersIcon as UsersIcon2 } from "@ai-matrx/design-system/icons";
4962
+ import { dropKeptDraft, keepDraft, readKeptDraft } from "@ai-matrx/kit/drafts";
4963
+
4971
4964
  // src/draft-keep.ts
4972
4965
  var PREFIX = "matrx.vault.draft:";
4973
4966
  function draftKey(itemId, definitionKey) {
4974
4967
  return `${PREFIX}${itemId ?? `new:${definitionKey ?? "custom"}`}`;
4975
4968
  }
4976
- function keepDraft(key, basedOn, d) {
4977
- const kept = { basedOn, draft: { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom } };
4978
- try {
4979
- globalThis.sessionStorage?.setItem(key, JSON.stringify(kept));
4980
- } catch {
4981
- }
4982
- }
4983
- function readKeptDraft(key, basedOn) {
4984
- try {
4985
- const raw = globalThis.sessionStorage?.getItem(key);
4986
- if (!raw) return null;
4987
- const kept = JSON.parse(raw);
4988
- return kept.basedOn === basedOn ? kept.draft : null;
4989
- } catch {
4990
- return null;
4991
- }
4992
- }
4993
- function dropKeptDraft(key) {
4994
- try {
4995
- globalThis.sessionStorage?.removeItem(key);
4996
- } catch {
4997
- }
4969
+ function keptFieldsOf(d) {
4970
+ return { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom };
4998
4971
  }
4999
4972
 
5000
4973
  // src/extension/page-logic.ts
@@ -5141,6 +5114,7 @@ import { useEffect as useEffect15, useState as useState25 } from "react";
5141
5114
  import { confirm as confirm8 } from "@ai-matrx/kit/confirm-opener";
5142
5115
  import { Button as Button20, DisclosureHeader as DisclosureHeader3, Field as Field9, RegionSkeleton, Select as Select8 } from "@ai-matrx/design-system/controls";
5143
5116
  import { cn as cn11 } from "@ai-matrx/design-system";
5117
+ import { UsersIcon } from "@ai-matrx/design-system/icons";
5144
5118
 
5145
5119
  // src/sharing/logic.ts
5146
5120
  var LEVEL_OPTIONS = [
@@ -5172,7 +5146,7 @@ function copyRefusal(message2) {
5172
5146
  return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
5173
5147
  }
5174
5148
  var isPasskey = (item) => item.definitionKey === "native_passkey" || item.definitionKey === "passkey_private";
5175
- function moveConsequence(item, to) {
5149
+ function itemMoveConsequence(item, to) {
5176
5150
  if (item.authenticator) return "One-time password stays behind; set it up again";
5177
5151
  return to ? "Its members get access; people you shared with lose it" : "Only you; organization members lose access";
5178
5152
  }
@@ -5262,7 +5236,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5262
5236
  const to = destinationOf(moveChoice.value);
5263
5237
  const ok = await confirm7({
5264
5238
  title: `Move to ${moveChoice.label}?`,
5265
- description: `"${item.name}" stays the same item, so everything using it keeps working. ${moveConsequence(item, to)}.`,
5239
+ description: `"${item.name}" stays the same item, so everything using it keeps working. ${itemMoveConsequence(item, to)}.`,
5266
5240
  confirmLabel: "Move"
5267
5241
  });
5268
5242
  if (!ok) return;
@@ -5298,17 +5272,17 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5298
5272
  /* @__PURE__ */ jsx24(StatusLine, { error, notice }),
5299
5273
  /* @__PURE__ */ jsx24(Button19, { variant: "outline", className: "ml-auto", onClick: onClose, children: "Close" })
5300
5274
  ] }),
5301
- children: nothing ? /* @__PURE__ */ jsx24(Section, { children: /* @__PURE__ */ jsx24(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ jsxs22(Section, { children: [
5275
+ children: nothing ? /* @__PURE__ */ jsx24(VaultSection, { children: /* @__PURE__ */ jsx24(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ jsxs22(VaultSection, { children: [
5302
5276
  canMove && moves.length > 0 ? /* @__PURE__ */ jsx24(
5303
- Row,
5277
+ VaultRow,
5304
5278
  {
5305
5279
  label: "Move to",
5306
- hint: moveChoice ? moveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5280
+ hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5307
5281
  actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
5308
5282
  children: /* @__PURE__ */ jsx24(Select7, { className: "w-full", "aria-label": "Move to", value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
5309
5283
  }
5310
5284
  ) : null,
5311
- canGive ? /* @__PURE__ */ jsx24(Row, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ jsx24(Button19, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ jsx24(
5285
+ canGive ? /* @__PURE__ */ jsx24(VaultRow, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ jsx24(Button19, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ jsx24(
5312
5286
  Field8,
5313
5287
  {
5314
5288
  className: "w-full",
@@ -5322,7 +5296,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5322
5296
  onChange: (e) => setEmail(e.target.value)
5323
5297
  }
5324
5298
  ) }) : null,
5325
- canCopy && copies.length > 0 ? /* @__PURE__ */ jsx24(Row, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ jsx24(Select7, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
5299
+ canCopy && copies.length > 0 ? /* @__PURE__ */ jsx24(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ jsx24(Select7, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
5326
5300
  ] })
5327
5301
  }
5328
5302
  );
@@ -5404,7 +5378,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5404
5378
  }
5405
5379
  };
5406
5380
  if (!item.capabilities.canManage) {
5407
- return /* @__PURE__ */ jsx25(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ jsx25(Section, { children: /* @__PURE__ */ jsx25(Empty, { children: "Only the owner can change who has access." }) }) });
5381
+ return /* @__PURE__ */ jsx25(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ jsx25(VaultSection, { children: /* @__PURE__ */ jsx25(Empty, { children: "Only the owner can change who has access." }) }) });
5408
5382
  }
5409
5383
  return /* @__PURE__ */ jsxs23(
5410
5384
  Panel,
@@ -5417,9 +5391,9 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5417
5391
  /* @__PURE__ */ jsx25(Button20, { variant: "primary", className: "ml-auto", onClick: onClose, children: "Done" })
5418
5392
  ] }),
5419
5393
  children: [
5420
- /* @__PURE__ */ jsxs23(Section, { title: "Who has access", children: [
5394
+ /* @__PURE__ */ jsxs23(VaultSection, { title: "Who has access", children: [
5421
5395
  isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: BuildingGlyph, who: `${orgName} admins`, children: /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }) : /* @__PURE__ */ jsx25(AccessLine, { glyph: PersonGlyph, who: "You", meta: "Owner", children: /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }),
5422
- isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: UsersGlyph, who: `${orgName} members`, children: /* @__PURE__ */ jsx25(
5396
+ isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ jsx25(
5423
5397
  Select8,
5424
5398
  {
5425
5399
  variant: "inline",
@@ -5480,7 +5454,7 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
5480
5454
  const [level, setLevel] = useState25("use");
5481
5455
  const chosen = open.find((o) => o.id === target);
5482
5456
  if (item.owner.kind !== "me") return null;
5483
- return /* @__PURE__ */ jsx25(Section, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ jsxs23(Fragment14, { children: [
5457
+ return /* @__PURE__ */ jsx25(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ jsxs23(Fragment14, { children: [
5484
5458
  /* @__PURE__ */ jsxs23("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5485
5459
  /* @__PURE__ */ jsx25(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5486
5460
  /* @__PURE__ */ jsx25(Select8, { className: "min-w-0 flex-1", "aria-label": "Organization", value: target || "__none__", onValueChange: (v) => setTarget(v === "__none__" ? "" : v), options: [{ value: "__none__", label: "Choose an organization" }, ...open.map((o) => ({ value: o.id, label: o.name }))] }),
@@ -5530,7 +5504,7 @@ function MemberAccess({ port, organizationId, organizationName }) {
5530
5504
  const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
5531
5505
  if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
5532
5506
  };
5533
- return /* @__PURE__ */ jsxs23(Section, { title: `${organizationName} vault access`, children: [
5507
+ return /* @__PURE__ */ jsxs23(VaultSection, { title: `${organizationName} vault access`, children: [
5534
5508
  loadError ? /* @__PURE__ */ jsx25(Empty, { children: loadError }) : list === null ? /* @__PURE__ */ jsx25(RegionSkeleton, { shape: "rows", count: 3, "aria-label": "Loading member access", className: "px-3 sm:px-4" }) : list.members.length === 0 ? /* @__PURE__ */ jsx25(Empty, { children: "No members yet." }) : list.members.map((m) => /* @__PURE__ */ jsx25(AccessLine, { glyph: PersonGlyph, who: m.email || m.userId, meta: m.role, children: m.effective === "admin" ? /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: MEMBER_ACCESS_LABEL.admin }) : /* @__PURE__ */ jsx25(
5535
5509
  Select8,
5536
5510
  {
@@ -5606,7 +5580,7 @@ function ItemPane(props) {
5606
5580
  if (was && was.id === id && was.mode === mode && editing) {
5607
5581
  setDraft((d) => rebaseDraft(was.base, base, d));
5608
5582
  } else {
5609
- const kept = editing ? readKeptDraft(keepKey, item?.updatedAt ?? "new") : null;
5583
+ const kept = editing ? readKeptDraft(keepKey, { basedOn: item?.updatedAt ?? "new" })?.value ?? null : null;
5610
5584
  setDraft(kept ? { ...base, ...kept } : base);
5611
5585
  setTagsText((kept ?? base).tags.join(", "));
5612
5586
  setError(null);
@@ -5621,7 +5595,7 @@ function ItemPane(props) {
5621
5595
  useEffect16(() => onDirty(dirty), [dirty, onDirty]);
5622
5596
  const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
5623
5597
  useEffect16(() => {
5624
- if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new", draft);
5598
+ if (editing && dirty) keepDraft(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
5625
5599
  else if (!editing) dropKeptDraft(keepKey);
5626
5600
  }, [editing, dirty, draft, keepKey, item?.updatedAt]);
5627
5601
  useEffect16(() => {
@@ -5708,7 +5682,7 @@ function ItemPane(props) {
5708
5682
  const viewCustom = (item?.custom ?? []).filter((c) => !declaredKeys.has(c.key) && c.key !== MFA_METHOD_KEY && !isAuthenticatorStorage(c.key));
5709
5683
  const isLogin = (item?.definitionKey ?? definition?.key) === "website_login" || (item?.definitionKey ?? definition?.key) === "username_password";
5710
5684
  const typeLabel = definition?.label ?? item?.definitionLabel ?? "";
5711
- const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ jsx26(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ jsx26(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ jsx26(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ jsx26(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ jsx26(BuildingGlyph, {}) : /* @__PURE__ */ jsx26(UsersGlyph, {}) } : null;
5685
+ const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ jsx26(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ jsx26(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ jsx26(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ jsx26(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ jsx26(BuildingGlyph, {}) : /* @__PURE__ */ jsx26(UsersIcon2, {}) } : null;
5712
5686
  const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
5713
5687
  const descriptionVisible = showDescription || draft.description !== "";
5714
5688
  const header = /* @__PURE__ */ jsxs24("header", { className: "flex min-h-14 items-center gap-2 border-b border-border px-3 py-2 sm:gap-3 sm:px-5", children: [
@@ -5765,7 +5739,7 @@ function ItemPane(props) {
5765
5739
  "Send securely"
5766
5740
  ] }) : null,
5767
5741
  /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("history"), children: [
5768
- /* @__PURE__ */ jsx26(HistoryGlyph, { className: "size-4" }),
5742
+ /* @__PURE__ */ jsx26(HistoryIcon, { className: "size-4" }),
5769
5743
  "Password history"
5770
5744
  ] }),
5771
5745
  /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("activity"), children: [
@@ -5773,7 +5747,7 @@ function ItemPane(props) {
5773
5747
  "Activity"
5774
5748
  ] }),
5775
5749
  canEdit ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("settings"), children: [
5776
- /* @__PURE__ */ jsx26(SettingsGlyph, { className: "size-4" }),
5750
+ /* @__PURE__ */ jsx26(SettingsIcon, { className: "size-4" }),
5777
5751
  "Settings"
5778
5752
  ] }) : null,
5779
5753
  canManage ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
@@ -5793,8 +5767,8 @@ function ItemPane(props) {
5793
5767
  error ? /* @__PURE__ */ jsx26("div", { role: "alert", className: "border-b border-border bg-muted px-5 py-2 text-sm text-destructive", children: error }) : null,
5794
5768
  notice && !editing ? /* @__PURE__ */ jsx26("div", { role: "status", className: "border-b border-border bg-muted px-5 py-2 text-sm text-warning", children: notice }) : null,
5795
5769
  /* @__PURE__ */ jsx26("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx26("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5 px-3 py-4 sm:px-6 sm:py-6", children: editing ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
5796
- /* @__PURE__ */ jsxs24(Section, { children: [
5797
- mode === "new" ? /* @__PURE__ */ jsx26(Row, { label: "Save to", children: /* @__PURE__ */ jsx26(
5770
+ /* @__PURE__ */ jsxs24(VaultSection, { children: [
5771
+ mode === "new" ? /* @__PURE__ */ jsx26(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx26(
5798
5772
  OptionCombobox,
5799
5773
  {
5800
5774
  value: owner,
@@ -5815,7 +5789,7 @@ function ItemPane(props) {
5815
5789
  /* @__PURE__ */ jsx26(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
5816
5790
  mode === "new" && owner === "person" ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
5817
5791
  /* @__PURE__ */ jsx26(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
5818
- declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ jsx26(Row, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ jsx26(Switch5, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
5792
+ declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ jsx26(VaultRow, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ jsx26(Switch5, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
5819
5793
  ] }) : null,
5820
5794
  declared.map((f) => {
5821
5795
  const existing = item?.fields.find((x) => x.key === f.key);
@@ -5835,7 +5809,7 @@ function ItemPane(props) {
5835
5809
  actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
5836
5810
  hidden && existing?.handling === "revealable" && item?.capabilities.canReveal ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
5837
5811
  secretKind ? /* @__PURE__ */ jsx26(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
5838
- existing ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
5812
+ existing ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
5839
5813
  ] })
5840
5814
  },
5841
5815
  f.key
@@ -5853,7 +5827,7 @@ function ItemPane(props) {
5853
5827
  removeLabel: `Delete ${f.label}`,
5854
5828
  actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
5855
5829
  f.handling === "revealable" && !(f.key in loaded) && item?.capabilities.canReveal ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
5856
- /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
5830
+ /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
5857
5831
  ] })
5858
5832
  },
5859
5833
  f.id
@@ -5886,9 +5860,9 @@ function ItemPane(props) {
5886
5860
  /* @__PURE__ */ jsx26(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator), item, port, onEnrolled: onChanged }),
5887
5861
  item && isLogin && !item.authenticator ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
5888
5862
  ] }),
5889
- /* @__PURE__ */ jsx26(Section, { children: /* @__PURE__ */ jsx26(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
5863
+ /* @__PURE__ */ jsx26(VaultSection, { children: /* @__PURE__ */ jsx26(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
5890
5864
  /* @__PURE__ */ jsxs24(
5891
- Section,
5865
+ VaultSection,
5892
5866
  {
5893
5867
  title: "More",
5894
5868
  actions: /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
@@ -5922,7 +5896,7 @@ function ItemPane(props) {
5922
5896
  ),
5923
5897
  filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: true }) : null
5924
5898
  ] }) : item ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
5925
- /* @__PURE__ */ jsxs24(Section, { children: [
5899
+ /* @__PURE__ */ jsxs24(VaultSection, { children: [
5926
5900
  declared.map((f) => {
5927
5901
  if (f.storage === "metadata") {
5928
5902
  const v = metaValue(f.key);
@@ -5937,10 +5911,10 @@ function ItemPane(props) {
5937
5911
  item.authenticator ? /* @__PURE__ */ jsx26(TotpRow, { port, item, onChanged }) : /* @__PURE__ */ jsx26(AddRow, { label: "One-time password", onAdd: canEdit ? () => onMode("edit") : null, children: "Set up" }),
5938
5912
  !item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
5939
5913
  ] }),
5940
- /* @__PURE__ */ jsx26(Section, { children: item.notes ? /* @__PURE__ */ jsx26(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ jsx26(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
5941
- item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs24(Section, { title: "More", children: [
5914
+ /* @__PURE__ */ jsx26(VaultSection, { children: item.notes ? /* @__PURE__ */ jsx26(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ jsx26(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
5915
+ item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs24(VaultSection, { title: "More", children: [
5942
5916
  item.description ? /* @__PURE__ */ jsx26(PlainRow, { label: "Description", value: item.description }) : null,
5943
- item.tags.length > 0 ? /* @__PURE__ */ jsx26(Row, { label: "Tags", children: /* @__PURE__ */ jsx26("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ jsx26("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
5917
+ item.tags.length > 0 ? /* @__PURE__ */ jsx26(VaultRow, { label: "Tags", children: /* @__PURE__ */ jsx26("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ jsx26("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
5944
5918
  viewCustom.map((c) => /* @__PURE__ */ jsx26(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
5945
5919
  ] }) : null,
5946
5920
  filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: false }) : null,
@@ -6188,13 +6162,13 @@ function RestorePanel({ lists, item, restore, onClose }) {
6188
6162
  refused ? null : /* @__PURE__ */ jsx28(Button23, { variant: "primary", icon: /* @__PURE__ */ jsx28(RestoreGlyph, {}), disabled: busy || loading || lists.preview !== void 0 && preview === null, onClick: () => void run(), children: busy ? "Restoring\u2026" : "Restore" })
6189
6163
  ] }),
6190
6164
  children: [
6191
- loading ? /* @__PURE__ */ jsx28(Section, { children: /* @__PURE__ */ jsx28(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ jsxs26(Section, { title: "Comes back", children: [
6192
- /* @__PURE__ */ jsx28(Row, { label: "Fields", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
6193
- /* @__PURE__ */ jsx28(Row, { label: "Files", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
6194
- preview.passkeys === 1 ? /* @__PURE__ */ jsx28(Row, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
6195
- /* @__PURE__ */ jsx28(Row, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
6196
- preview.priorWasDisabled ? /* @__PURE__ */ jsx28(Row, { label: "Before", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
6197
- ] }) : preview ? /* @__PURE__ */ jsx28(Section, { children: /* @__PURE__ */ jsx28(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ jsx28(Section, { children: /* @__PURE__ */ jsx28(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
6165
+ loading ? /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ jsxs26(VaultSection, { title: "Comes back", children: [
6166
+ /* @__PURE__ */ jsx28(VaultRow, { label: "Fields", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
6167
+ /* @__PURE__ */ jsx28(VaultRow, { label: "Files", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
6168
+ preview.passkeys === 1 ? /* @__PURE__ */ jsx28(VaultRow, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
6169
+ /* @__PURE__ */ jsx28(VaultRow, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
6170
+ preview.priorWasDisabled ? /* @__PURE__ */ jsx28(VaultRow, { label: "Before", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
6171
+ ] }) : preview ? /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
6198
6172
  error ? /* @__PURE__ */ jsx28("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
6199
6173
  ]
6200
6174
  }
@@ -6226,7 +6200,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6226
6200
  };
6227
6201
  return /* @__PURE__ */ jsxs27("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
6228
6202
  header,
6229
- /* @__PURE__ */ jsx29(Section, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ jsx29(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
6203
+ /* @__PURE__ */ jsx29(VaultSection, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ jsx29(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
6230
6204
  // A list row, not a field row: the name gets the whole width (on a phone a label column
6231
6205
  // left "Vau…" for every row), the deletion date sits under it.
6232
6206
  /* @__PURE__ */ jsxs27("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
@@ -6246,6 +6220,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6246
6220
  import { useMemo as useMemo4, useState as useState30 } from "react";
6247
6221
  import { cn as cn14 } from "@ai-matrx/design-system";
6248
6222
  import { Button as Button25, Field as Field10, SearchField as SearchField2 } from "@ai-matrx/design-system/controls";
6223
+ import { GlobeIcon as GlobeIcon3 } from "@ai-matrx/design-system/icons";
6249
6224
  import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
6250
6225
  function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6251
6226
  const [search, setSearch] = useState30("");
@@ -6280,7 +6255,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6280
6255
  "aria-label": "Website address",
6281
6256
  inputMode: "url",
6282
6257
  autoFocus: true,
6283
- icon: /* @__PURE__ */ jsx30(GlobeGlyph, {})
6258
+ icon: /* @__PURE__ */ jsx30(GlobeIcon3, {})
6284
6259
  }
6285
6260
  ),
6286
6261
  guess && login ? /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
@@ -6530,9 +6505,9 @@ function SecureLinkPanel({ item, port, onClose }) {
6530
6505
  ] }),
6531
6506
  children: [
6532
6507
  remedy ? /* @__PURE__ */ jsx31("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
6533
- /* @__PURE__ */ jsxs29(Section, { title: "Recipient", children: [
6534
- /* @__PURE__ */ jsx31(Row, { label: "Email", children: /* @__PURE__ */ jsx31(Field11, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
6535
- /* @__PURE__ */ jsx31(Row, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ jsx31(
6508
+ /* @__PURE__ */ jsxs29(VaultSection, { title: "Recipient", children: [
6509
+ /* @__PURE__ */ jsx31(VaultRow, { label: "Email", children: /* @__PURE__ */ jsx31(Field11, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
6510
+ /* @__PURE__ */ jsx31(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ jsx31(
6536
6511
  Field11,
6537
6512
  {
6538
6513
  type: "tel",
@@ -6548,8 +6523,8 @@ function SecureLinkPanel({ item, port, onClose }) {
6548
6523
  className: "w-full"
6549
6524
  }
6550
6525
  ) }),
6551
- /* @__PURE__ */ jsx31(Row, { label: "Name", hint: "Optional", children: /* @__PURE__ */ jsx31(Field11, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
6552
- plan && !plan.same ? /* @__PURE__ */ jsx31(Row, { label: "Link by", children: /* @__PURE__ */ jsx31(
6526
+ /* @__PURE__ */ jsx31(VaultRow, { label: "Name", hint: "Optional", children: /* @__PURE__ */ jsx31(Field11, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
6527
+ plan && !plan.same ? /* @__PURE__ */ jsx31(VaultRow, { label: "Link by", children: /* @__PURE__ */ jsx31(
6553
6528
  SegmentedControl5,
6554
6529
  {
6555
6530
  "aria-label": "Send the link by",
@@ -6561,26 +6536,26 @@ function SecureLinkPanel({ item, port, onClose }) {
6561
6536
  ]
6562
6537
  }
6563
6538
  ) }) : null,
6564
- email.trim() ? /* @__PURE__ */ jsx31(Row, { label: "Delivery", children: /* @__PURE__ */ jsx31("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
6539
+ email.trim() ? /* @__PURE__ */ jsx31(VaultRow, { label: "Delivery", children: /* @__PURE__ */ jsx31("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
6565
6540
  ] }),
6566
- /* @__PURE__ */ jsx31(Section, { title: "Include", children: optionsError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ jsxs29("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
6541
+ /* @__PURE__ */ jsx31(VaultSection, { title: "Include", children: optionsError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ jsxs29("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
6567
6542
  /* @__PURE__ */ jsx31(Checkbox2, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
6568
6543
  /* @__PURE__ */ jsx31("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
6569
6544
  !f.available && f.reason ? /* @__PURE__ */ jsx31("span", { className: "min-w-0 max-w-[55%] truncate text-xs text-muted-foreground", title: f.reason, children: f.reason }) : null
6570
6545
  ] }, f.key)) }),
6571
- /* @__PURE__ */ jsx31(Section, { title: "Message", children: /* @__PURE__ */ jsx31("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ jsx31(Textarea4, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
6572
- options ? /* @__PURE__ */ jsxs29(Section, { title: "Link", children: [
6573
- /* @__PURE__ */ jsx31(Row, { label: "Opens", children: /* @__PURE__ */ jsx31("span", { className: "text-foreground", children: "Once" }) }),
6574
- /* @__PURE__ */ jsx31(Row, { label: "Link expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
6546
+ /* @__PURE__ */ jsx31(VaultSection, { title: "Message", children: /* @__PURE__ */ jsx31("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ jsx31(Textarea4, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
6547
+ options ? /* @__PURE__ */ jsxs29(VaultSection, { title: "Link", children: [
6548
+ /* @__PURE__ */ jsx31(VaultRow, { label: "Opens", children: /* @__PURE__ */ jsx31("span", { className: "text-foreground", children: "Once" }) }),
6549
+ /* @__PURE__ */ jsx31(VaultRow, { label: "Link expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
6575
6550
  "After ",
6576
6551
  lifetimeWords(options.linkMinutes)
6577
6552
  ] }) }),
6578
- /* @__PURE__ */ jsx31(Row, { label: "Code expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
6553
+ /* @__PURE__ */ jsx31(VaultRow, { label: "Code expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
6579
6554
  "After ",
6580
6555
  lifetimeWords(options.codeMinutes)
6581
6556
  ] }) })
6582
6557
  ] }) : null,
6583
- sharing.sentSecureLinks ? /* @__PURE__ */ jsx31(Section, { title: "Sent links", children: sentError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ jsxs29(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
6558
+ sharing.sentSecureLinks ? /* @__PURE__ */ jsx31(VaultSection, { title: "Sent links", children: sentError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ jsxs29(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
6584
6559
  /* @__PURE__ */ jsx31(Badge8, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
6585
6560
  row.status === "pending" ? /* @__PURE__ */ jsx31(Button26, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
6586
6561
  ] }, row.id)) }) : null
@@ -6722,10 +6697,10 @@ function DevicesPanel({ port, onClose }) {
6722
6697
  };
6723
6698
  return /* @__PURE__ */ jsxs30(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
6724
6699
  /* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
6725
- /* @__PURE__ */ jsx32(Section, { children: devices === null ? error ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32(Button27, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx32(RegionSkeleton3, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ jsx32(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
6700
+ /* @__PURE__ */ jsx32(VaultSection, { children: devices === null ? error ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32(Button27, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx32(RegionSkeleton3, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ jsx32(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
6726
6701
  const off = isRevoked(device);
6727
6702
  return /* @__PURE__ */ jsx32(
6728
- Row,
6703
+ VaultRow,
6729
6704
  {
6730
6705
  label: off ? "Turned off" : "Can fill",
6731
6706
  hint: off ? formatAbsoluteDate6(device.revokedAt, DAY_FORMAT, "") : void 0,
@@ -6813,18 +6788,18 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6813
6788
  /* @__PURE__ */ jsx32(Button27, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
6814
6789
  canApprove ? /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void approve(), children: busy === "approve" ? "Approving\u2026" : "Approve with passkey" }) : null
6815
6790
  ] });
6816
- return /* @__PURE__ */ jsx32(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx32(Section, { children: /* @__PURE__ */ jsxs30(Empty, { children: [
6791
+ return /* @__PURE__ */ jsx32(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx32(VaultSection, { children: /* @__PURE__ */ jsxs30(Empty, { children: [
6817
6792
  "This link names no key. Start again from ",
6818
6793
  where,
6819
6794
  "."
6820
6795
  ] }) }) : /* @__PURE__ */ jsxs30(Fragment17, { children: [
6821
- /* @__PURE__ */ jsxs30(Section, { title: "What is asking", children: [
6822
- /* @__PURE__ */ jsx32(Row, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
6823
- name ? /* @__PURE__ */ jsx32(Row, { label: "Name", children: /* @__PURE__ */ jsx32("span", { className: "block truncate", children: name }) }) : null,
6824
- /* @__PURE__ */ jsx32(Row, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ jsx32("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
6796
+ /* @__PURE__ */ jsxs30(VaultSection, { title: "What is asking", children: [
6797
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
6798
+ name ? /* @__PURE__ */ jsx32(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx32("span", { className: "block truncate", children: name }) }) : null,
6799
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ jsx32("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
6825
6800
  ] }),
6826
6801
  /* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
6827
- /* @__PURE__ */ jsx32(Section, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ jsx32(Row, { label: "Approved", actions: /* @__PURE__ */ jsx32(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ jsxs30("span", { className: "text-foreground", children: [
6802
+ /* @__PURE__ */ jsx32(VaultSection, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ jsx32(VaultRow, { label: "Approved", actions: /* @__PURE__ */ jsx32(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ jsxs30("span", { className: "text-foreground", children: [
6828
6803
  "Return to ",
6829
6804
  where,
6830
6805
  " by ",
@@ -6835,7 +6810,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6835
6810
  where,
6836
6811
  "."
6837
6812
  ] }) : !here ? /* @__PURE__ */ jsx32(
6838
- Row,
6813
+ VaultRow,
6839
6814
  {
6840
6815
  label: "Passkey",
6841
6816
  hint: `Passkeys work only on ${passkeys.rpId}`,
@@ -6843,14 +6818,14 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6843
6818
  children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: "Not on this page" })
6844
6819
  }
6845
6820
  ) : methods === null ? error ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32(Button27, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx32(RegionSkeleton3, { shape: "rows", count: 1, "aria-label": "Checking your account", className: "px-3 sm:px-4" }) : !methods.passkey ? /* @__PURE__ */ jsx32(
6846
- Row,
6821
+ VaultRow,
6847
6822
  {
6848
6823
  label: "Passkey",
6849
6824
  hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
6850
6825
  actions: /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
6851
6826
  children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
6852
6827
  }
6853
- ) : /* @__PURE__ */ jsx32(Row, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ jsx32("span", { className: "text-foreground", children: "Ready" }) }) })
6828
+ ) : /* @__PURE__ */ jsx32(VaultRow, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ jsx32("span", { className: "text-foreground", children: "Ready" }) }) })
6854
6829
  ] }) });
6855
6830
  }
6856
6831
 
@@ -7128,7 +7103,7 @@ var TONE = {
7128
7103
  };
7129
7104
  function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
7130
7105
  if (!bridge) {
7131
- return /* @__PURE__ */ jsx33(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ jsx33(Section, { children: /* @__PURE__ */ jsx33(Empty, { children: "Passkey import needs the desktop app." }) }) });
7106
+ return /* @__PURE__ */ jsx33(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ jsx33(VaultSection, { children: /* @__PURE__ */ jsx33(Empty, { children: "Passkey import needs the desktop app." }) }) });
7132
7107
  }
7133
7108
  return /* @__PURE__ */ jsx33(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
7134
7109
  }
@@ -7175,25 +7150,25 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7175
7150
  /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Done" })
7176
7151
  ] }) : /* @__PURE__ */ jsx33(Button28, { variant: "quiet", onClick: onClose, children: "Close" });
7177
7152
  return /* @__PURE__ */ jsxs31(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
7178
- screen.kind === "idle" ? /* @__PURE__ */ jsxs31(Section, { children: [
7179
- /* @__PURE__ */ jsx33(Row, { label: "Save to", children: /* @__PURE__ */ jsx33(Select9, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
7180
- /* @__PURE__ */ jsx33(Row, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ jsx33(Button28, { variant: "outline", icon: /* @__PURE__ */ jsx33(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
7181
- /* @__PURE__ */ jsx33(Row, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ jsx33(Button28, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
7153
+ screen.kind === "idle" ? /* @__PURE__ */ jsxs31(VaultSection, { children: [
7154
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx33(Select9, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
7155
+ /* @__PURE__ */ jsx33(VaultRow, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ jsx33(Button28, { variant: "outline", icon: /* @__PURE__ */ jsx33(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
7156
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ jsx33(Button28, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
7182
7157
  ] }) : null,
7183
- preview ? /* @__PURE__ */ jsx33(Section, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ jsx33(
7158
+ preview ? /* @__PURE__ */ jsx33(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ jsx33(
7184
7159
  Windowed,
7185
7160
  {
7186
7161
  items: preview.slots,
7187
- render: (slot) => /* @__PURE__ */ jsx33(Row, { label: /* @__PURE__ */ jsx33(Badge9, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ jsx33("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
7162
+ render: (slot) => /* @__PURE__ */ jsx33(VaultRow, { label: /* @__PURE__ */ jsx33(Badge9, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ jsx33("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
7188
7163
  }
7189
7164
  ) }) : null,
7190
- status && !preview ? /* @__PURE__ */ jsxs31(Section, { title: `${accounted(status)} of ${status.total} done`, children: [
7191
- /* @__PURE__ */ jsx33(Row, { label: "Imported", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.committed }) }),
7192
- /* @__PURE__ */ jsx33(Row, { label: "Already there", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.already_present }) }),
7193
- /* @__PURE__ */ jsx33(Row, { label: "Can't import", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.unsupported }) }),
7194
- /* @__PURE__ */ jsx33(Row, { label: "Failed", children: /* @__PURE__ */ jsx33("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
7195
- status.uncertain > 0 ? /* @__PURE__ */ jsx33(Row, { label: "Needs recovery", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.uncertain }) }) : null,
7196
- status.not_attempted > 0 ? /* @__PURE__ */ jsx33(Row, { label: "Not tried", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.not_attempted }) }) : null
7165
+ status && !preview ? /* @__PURE__ */ jsxs31(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
7166
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Imported", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.committed }) }),
7167
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Already there", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.already_present }) }),
7168
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Can't import", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.unsupported }) }),
7169
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx33("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
7170
+ status.uncertain > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Needs recovery", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.uncertain }) }) : null,
7171
+ status.not_attempted > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.not_attempted }) }) : null
7197
7172
  ] }) : null,
7198
7173
  screen.message ? /* @__PURE__ */ jsx33("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
7199
7174
  /* @__PURE__ */ jsx33(ErrorLine, { message: limitError })
@@ -7204,6 +7179,7 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7204
7179
  import { useState as useState38 } from "react";
7205
7180
  import { DropdownMenu as DropdownMenu5, DropdownMenuContent as DropdownMenuContent5, DropdownMenuItem as DropdownMenuItem4, DropdownMenuTrigger as DropdownMenuTrigger5, SiteIcon } from "@ai-matrx/design-system";
7206
7181
  import { Button as Button32 } from "@ai-matrx/design-system/controls";
7182
+ import { GlobeIcon as GlobeIcon4 } from "@ai-matrx/design-system/icons";
7207
7183
 
7208
7184
  // src/extension/CaptureCard.tsx
7209
7185
  import { useState as useState35, useSyncExternalStore as useSyncExternalStore3 } from "react";
@@ -7346,6 +7322,7 @@ function FillSetupCard({ fillSetup }) {
7346
7322
  import { useState as useState37 } from "react";
7347
7323
  import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2 } from "@ai-matrx/design-system";
7348
7324
  import { Button as Button31 } from "@ai-matrx/design-system/controls";
7325
+ import { CopyIcon as CopyIcon7 } from "@ai-matrx/design-system/icons";
7349
7326
  import { Fragment as Fragment20, jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
7350
7327
  var HOLD_MS = 6e4;
7351
7328
  function PageGenerator({ fields }) {
@@ -7399,11 +7376,11 @@ function PageGenerator({ fields }) {
7399
7376
  const value = held.value;
7400
7377
  return /* @__PURE__ */ jsxs34(Fragment20, { children: [
7401
7378
  /* @__PURE__ */ jsx36(
7402
- Row,
7379
+ VaultRow,
7403
7380
  {
7404
7381
  label: "New password",
7405
7382
  actions: /* @__PURE__ */ jsxs34(Fragment20, { children: [
7406
- value ? /* @__PURE__ */ jsx36(Button31, { variant: "quiet", icon: /* @__PURE__ */ jsx36(CopyGlyph, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
7383
+ value ? /* @__PURE__ */ jsx36(Button31, { variant: "quiet", icon: /* @__PURE__ */ jsx36(CopyIcon7, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
7407
7384
  /* @__PURE__ */ jsxs34(Popover2, { open, onOpenChange: setOpen, children: [
7408
7385
  /* @__PURE__ */ jsx36(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx36(Button31, { variant: "outline", icon: /* @__PURE__ */ jsx36(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
7409
7386
  /* @__PURE__ */ jsx36(PopoverContent2, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ jsx36(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
@@ -7412,7 +7389,7 @@ function PageGenerator({ fields }) {
7412
7389
  children: said ? /* @__PURE__ */ jsx36("span", { role: "status", className: said.tone === "success" ? "line-clamp-2 text-xs text-foreground" : "line-clamp-2 text-xs text-muted-foreground", children: said.text }) : targets.length > 0 ? /* @__PURE__ */ jsx36("span", { className: "text-xs text-muted-foreground", children: "Choose the boxes to fill." }) : /* @__PURE__ */ jsx36("span", { className: "text-xs text-disabled-foreground", children: "Fills the page\u2019s new-password box" })
7413
7390
  }
7414
7391
  ),
7415
- value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ jsx36(Row, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ jsx36(Button31, { variant: "primary", icon: /* @__PURE__ */ jsx36(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ jsx36("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
7392
+ value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ jsx36(VaultRow, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ jsx36(Button31, { variant: "primary", icon: /* @__PURE__ */ jsx36(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ jsx36("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
7416
7393
  ] });
7417
7394
  }
7418
7395
 
@@ -7474,7 +7451,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7474
7451
  return /* @__PURE__ */ jsx37("div", { className: "flex h-full min-h-0 flex-col overflow-y-auto bg-background text-foreground", children: /* @__PURE__ */ jsxs35("div", { className: "flex flex-col gap-3 px-3 pb-4 pt-3", children: [
7475
7452
  header,
7476
7453
  /* @__PURE__ */ jsxs35("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
7477
- /* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback: GlobeGlyph, className: "size-4" }),
7454
+ /* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback: GlobeIcon4, className: "size-4" }),
7478
7455
  /* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
7479
7456
  page.refresh ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
7480
7457
  onBrowse ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
@@ -7482,7 +7459,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7482
7459
  fillSetup ? /* @__PURE__ */ jsx37(FillSetupCard, { fillSetup }) : null,
7483
7460
  capture ? /* @__PURE__ */ jsx37(CaptureCard, { capture, onChanged }) : null,
7484
7461
  /* @__PURE__ */ jsx37(
7485
- Section,
7462
+ VaultSection,
7486
7463
  {
7487
7464
  title: "This site",
7488
7465
  actions: canSave ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
@@ -7490,7 +7467,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7490
7467
  }
7491
7468
  ),
7492
7469
  said ? /* @__PURE__ */ jsx37(Outcome, { said, onDismiss: () => setSaid(null) }) : page.blocked && page.url && state.status === "ready" ? /* @__PURE__ */ jsx37("p", { className: "px-1 text-xs text-muted-foreground", children: BLOCK_WORDS[page.blocked] }) : null,
7493
- newPasswordFields && canSave ? /* @__PURE__ */ jsx37(Section, { children: /* @__PURE__ */ jsx37(PageGenerator, { fields: newPasswordFields }) }) : null
7470
+ newPasswordFields && canSave ? /* @__PURE__ */ jsx37(VaultSection, { children: /* @__PURE__ */ jsx37(PageGenerator, { fields: newPasswordFields }) }) : null
7494
7471
  ] }) });
7495
7472
  }
7496
7473
  function Outcome({ said, onDismiss }) {
@@ -7550,8 +7527,9 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
7550
7527
 
7551
7528
  // src/Sidebar.tsx
7552
7529
  import { useState as useState39 } from "react";
7553
- import { cn as cn15 } from "@ai-matrx/design-system";
7530
+ import { cn as cn15, useLook as useLook2 } from "@ai-matrx/design-system";
7554
7531
  import { Select as Select10 } from "@ai-matrx/design-system/controls";
7532
+ import { GlobeIcon as GlobeIcon5 } from "@ai-matrx/design-system/icons";
7555
7533
  import { jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
7556
7534
  function vaultChoices(items, organizations, current) {
7557
7535
  const n = (f) => items.filter(f).length;
@@ -7567,7 +7545,7 @@ function vaultChoices(items, organizations, current) {
7567
7545
  function VaultSelect({ value, choices, onChange }) {
7568
7546
  return /* @__PURE__ */ jsx38(Select10, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
7569
7547
  }
7570
- var CATEGORY_GLYPHS = { logins: GlobeGlyph, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
7548
+ var CATEGORY_GLYPHS = { logins: GlobeIcon5, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
7571
7549
  var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
7572
7550
  function itemCategory(item, definitions) {
7573
7551
  return categoryOf(item.definitionKey, familyOf(item.definitionKey, definitions));
@@ -7610,13 +7588,14 @@ function viewOptions(views, allCount, deletedCount, hasFavorites, hasRecents, ha
7610
7588
  ];
7611
7589
  }
7612
7590
  function Entry({ on, glyph: Icon, label, count: count2, onClick }) {
7591
+ const desktop = useLook2() === "desktop";
7613
7592
  return /* @__PURE__ */ jsxs36(
7614
7593
  "button",
7615
7594
  {
7616
7595
  type: "button",
7617
7596
  "aria-current": on ? "page" : void 0,
7618
7597
  onClick,
7619
- className: cn15("flex h-8 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm", on ? "bg-sidebar-accent font-medium text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent"),
7598
+ className: cn15("flex h-8 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm", on ? desktop ? "bg-sidebar-accent text-primary" : "bg-sidebar-accent font-medium text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent"),
7620
7599
  children: [
7621
7600
  /* @__PURE__ */ jsx38(Icon, { className: "size-4 shrink-0" }),
7622
7601
  /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate", children: label }),
@@ -7631,7 +7610,7 @@ function Group({ title, children }) {
7631
7610
  children
7632
7611
  ] });
7633
7612
  }
7634
- function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
7613
+ function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
7635
7614
  const [tagsOpen, setTagsOpen] = useState39(view.startsWith("tag:"));
7636
7615
  return /* @__PURE__ */ jsxs36("nav", { "aria-label": "Vault", className: "flex h-full min-h-0 flex-col border-r border-sidebar-border bg-sidebar-background text-sidebar-foreground", children: [
7637
7616
  /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
@@ -7640,7 +7619,7 @@ function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views,
7640
7619
  ] }),
7641
7620
  /* @__PURE__ */ jsxs36("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
7642
7621
  /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5", children: [
7643
- hasPage ? /* @__PURE__ */ jsx38(Entry, { on: view === "page", glyph: GlobeGlyph, label: "This page", onClick: () => onView("page") }) : null,
7622
+ hasPage ? /* @__PURE__ */ jsx38(Entry, { on: view === "page", glyph: GlobeIcon5, label: "This page", onClick: () => onView("page") }) : null,
7644
7623
  /* @__PURE__ */ jsx38(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
7645
7624
  hasFavorites ? /* @__PURE__ */ jsx38(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
7646
7625
  hasRecents ? /* @__PURE__ */ jsx38(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
@@ -7680,7 +7659,7 @@ var NO_HOST = {};
7680
7659
  var ITEM_PANELS = {
7681
7660
  share: SharePanel,
7682
7661
  move: MovePanel,
7683
- history: HistoryPanel,
7662
+ history: ItemHistoryPanel,
7684
7663
  activity: ActivityPanel,
7685
7664
  settings: ItemSettingsPanel,
7686
7665
  field: FieldSettingsPanel,
@@ -7713,7 +7692,7 @@ function VaultApp(props) {
7713
7692
  const lock = props.host?.lock;
7714
7693
  const locked = useLocked(lock);
7715
7694
  const port = useMemo6(() => lock ? guardPort(props.port, () => lock.locked()) : props.port, [props.port, lock]);
7716
- return /* @__PURE__ */ jsx39("div", { className: "relative h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39(NoticeProvider, { notify: props.notify, children: lock && locked ? /* @__PURE__ */ jsx39(LockedScreen, { lock }) : /* @__PURE__ */ jsx39(ClipboardProvider, { clipboard: props.host?.clipboard, children: /* @__PURE__ */ jsx39(RevealSecondsProvider, { seconds: props.host?.revealSeconds, children: /* @__PURE__ */ jsx39(IdentityGate, { identity: props.host?.identity, children: /* @__PURE__ */ jsx39(GeneratorLimitsProvider, { resolve: generatorLimitsFrom(props.host?.knobs), children: /* @__PURE__ */ jsx39(Workspace, { ...props, port }) }) }) }) }) }) });
7695
+ return /* @__PURE__ */ jsx39(LookScope, { look: props.look ?? "web", className: "h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39("div", { className: "relative h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39(NoticeProvider, { notify: props.notify, children: lock && locked ? /* @__PURE__ */ jsx39(LockedScreen, { lock }) : /* @__PURE__ */ jsx39(ClipboardProvider, { clipboard: props.host?.clipboard, children: /* @__PURE__ */ jsx39(RevealSecondsProvider, { seconds: props.host?.revealSeconds, children: /* @__PURE__ */ jsx39(IdentityGate, { identity: props.host?.identity, children: /* @__PURE__ */ jsx39(GeneratorLimitsProvider, { resolve: generatorLimitsFrom(props.host?.knobs), children: /* @__PURE__ */ jsx39(Workspace, { ...props, port }) }) }) }) }) }) }) });
7717
7696
  }
7718
7697
  function LockedScreen({ lock }) {
7719
7698
  const [busy, setBusy] = useState40(false);
@@ -8071,7 +8050,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8071
8050
  ] }) : null,
8072
8051
  /* @__PURE__ */ jsxs37("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
8073
8052
  mode === "full" ? /* @__PURE__ */ jsx39(
8074
- Sidebar,
8053
+ VaultSidebar,
8075
8054
  {
8076
8055
  vault: loc.vault,
8077
8056
  choices,