@ai-matrx/vault 0.1.9 → 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
@@ -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";
@@ -579,7 +567,7 @@ 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);
584
572
  const desktop = useLook() === "desktop";
585
573
  return /* @__PURE__ */ jsxs4("section", { className: cn2("flex flex-col gap-1.5", className), children: [
@@ -595,7 +583,7 @@ var ROW_GRID = {
595
583
  roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
596
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"
597
585
  };
598
- function Row({ label, hint, children, actions, top = false, className }) {
586
+ function VaultRow({ label, hint, children, actions, top = false, className }) {
599
587
  const room = useContext4(Room);
600
588
  return /* @__PURE__ */ jsxs4("div", { className: cn2("grid min-h-11 py-1", ROW_GRID[room ?? "viewport"], top ? "items-start" : "items-center", className), children: [
601
589
  /* @__PURE__ */ jsxs4("div", { className: cn2("flex min-w-0 flex-col text-xs leading-tight text-muted-foreground", top && "pt-2.5"), children: [
@@ -616,11 +604,6 @@ function Panel({ title, open = true, onClose, children, footer, size = "lg" }) {
616
604
  footer ? /* @__PURE__ */ jsx4(DialogFooter, { children: footer }) : null
617
605
  ] }) });
618
606
  }
619
- function formatBytes(n) {
620
- if (n < 1024) return `${n} B`;
621
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
622
- return `${(n / 1024 / 1024).toFixed(1)} MB`;
623
- }
624
607
  var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
625
608
 
626
609
  // src/FieldRows.tsx
@@ -679,14 +662,14 @@ function SecretRow({ port, item, field, extra }) {
679
662
  const multiline = field.kind === "multiline";
680
663
  const shown = visible ? plain : secret.value;
681
664
  return /* @__PURE__ */ jsx5(
682
- Row,
665
+ VaultRow,
683
666
  {
684
667
  label: field.label,
685
668
  top: multiline && shown !== null,
686
669
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
687
670
  extra,
688
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,
689
- 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
690
673
  ] }),
691
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 })
692
675
  }
@@ -696,7 +679,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
696
679
  const copyValue2 = useCopy();
697
680
  const isUrl = /^https?:\/\//i.test(value);
698
681
  return /* @__PURE__ */ jsx5(
699
- Row,
682
+ VaultRow,
700
683
  {
701
684
  label,
702
685
  hint,
@@ -704,7 +687,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
704
687
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
705
688
  extra,
706
689
  isUrl && openUrl ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: /* @__PURE__ */ jsx5(ExternalGlyph, {}), "aria-label": `Open ${value}`, onClick: () => openUrl(value) }) : null,
707
- /* @__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 }) })
708
691
  ] }),
709
692
  children: isUrl && openUrl ? (
710
693
  // A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
@@ -727,12 +710,12 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
727
710
  );
728
711
  }
729
712
  function AddRow({ label, onAdd, children = "Add" }) {
730
- 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" }) });
731
714
  }
732
715
  function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
733
716
  const [shown, setShown] = useState5(false);
734
717
  return /* @__PURE__ */ jsx5(
735
- Row,
718
+ VaultRow,
736
719
  {
737
720
  label,
738
721
  hint,
@@ -749,7 +732,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
749
732
  function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
750
733
  const [shown, setShown] = useState5(false);
751
734
  return /* @__PURE__ */ jsx5(
752
- Row,
735
+ VaultRow,
753
736
  {
754
737
  label: /* @__PURE__ */ jsx5(Field2, { className: "w-full", value: label, onChange: (e) => onLabel(e.target.value), placeholder: "Name", "aria-label": "Field name" }),
755
738
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
@@ -762,6 +745,7 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
762
745
  }
763
746
 
764
747
  // src/activity/HistoryPanel.tsx
748
+ import { CopyIcon as CopyIcon2 } from "@ai-matrx/design-system/icons";
765
749
  import { formatAbsoluteDate as formatAbsoluteDate2 } from "@ai-matrx/kit/format";
766
750
 
767
751
  // src/activity/logic.ts
@@ -1254,7 +1238,7 @@ function ActivityPanel({ item, port, onClose }) {
1254
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,
1255
1239
  children: [
1256
1240
  error ? /* @__PURE__ */ jsx6("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
1257
- 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(
1258
1242
  day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
1259
1243
  (r) => `${r.s.what}|${r.s.who ?? ""}`
1260
1244
  ).map(({ row: { entry, s }, times }) => {
@@ -1277,7 +1261,7 @@ function ActivityPanel({ item, port, onClose }) {
1277
1261
  import { Fragment as Fragment3, jsx as jsx7, jsxs as jsxs7 } from "react/jsx-runtime";
1278
1262
  var MASK2 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
1279
1263
  var messageOf = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
1280
- function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1264
+ function ItemHistoryPanel({ item, port, arg, onClose, onChanged }) {
1281
1265
  const eligible = historyEligible(item);
1282
1266
  const [page, setPage] = useState7(null);
1283
1267
  const [loading, setLoading] = useState7(eligible);
@@ -1339,7 +1323,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1339
1323
  error ? /* @__PURE__ */ jsx7("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
1340
1324
  notice ? /* @__PURE__ */ jsx7("p", { role: "status", className: "px-1 text-sm text-success", children: notice }) : null,
1341
1325
  page && groups.length === 0 ? /* @__PURE__ */ jsx7(Empty, { children: "No earlier values yet." }) : null,
1342
- 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,
1343
1327
  page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ jsxs7("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
1344
1328
  page.captureStartedAt ? /* @__PURE__ */ jsxs7("span", { className: "text-muted-foreground", children: [
1345
1329
  "Kept since ",
@@ -1400,12 +1384,12 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1400
1384
  }
1401
1385
  }
1402
1386
  return /* @__PURE__ */ jsx7(
1403
- Row,
1387
+ VaultRow,
1404
1388
  {
1405
1389
  label: when,
1406
1390
  actions: entry.available ? /* @__PURE__ */ jsxs7(Fragment3, { children: [
1407
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() }),
1408
- /* @__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() }),
1409
1393
  canRestore(page, entry) ? /* @__PURE__ */ jsx7(Button4, { variant: "quiet", icon: /* @__PURE__ */ jsx7(RestoreGlyph, {}), "aria-label": "Restore", disabled: busy, onClick: () => void restore() }) : null
1410
1394
  ] }) : null,
1411
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 })
@@ -1417,6 +1401,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1417
1401
  import { useEffect as useEffect11, useState as useState13 } from "react";
1418
1402
  import { Button as Button9 } from "@ai-matrx/design-system/controls";
1419
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";
1420
1405
 
1421
1406
  // src/authenticator/AddOtpPanel.tsx
1422
1407
  import { useState as useState12 } from "react";
@@ -1426,8 +1411,11 @@ import { Button as Button8, Field as Field4, Select as Select2 } from "@ai-matrx
1426
1411
  import { useEffect as useEffect8, useRef as useRef6, useState as useState8 } from "react";
1427
1412
  import { Button as Button5 } from "@ai-matrx/design-system/controls";
1428
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";
1429
1416
 
1430
1417
  // src/authenticator/otpauth.ts
1418
+ import { groupCode } from "@ai-matrx/kit/format";
1431
1419
  var TOTP_DEFAULT_DIGITS = 6;
1432
1420
  var TOTP_DEFAULT_PERIOD = 30;
1433
1421
  var TOTP_DEFAULT_ALGORITHM = "SHA1";
@@ -1495,12 +1483,6 @@ function describeEnrollment(parsed) {
1495
1483
  const parts = [parsed.issuer, parsed.account].filter((p) => Boolean(p));
1496
1484
  return parts.length ? parts.join(" \xB7 ") : "Setup key";
1497
1485
  }
1498
- function groupCode(code) {
1499
- const c = code.replace(/\s/g, "");
1500
- if (c.length < 6) return c;
1501
- const head = Math.ceil(c.length / 2);
1502
- return `${c.slice(0, head)} ${c.slice(head)}`;
1503
- }
1504
1486
  function maskedCode(digits = TOTP_DEFAULT_DIGITS) {
1505
1487
  return groupCode("\u2022".repeat(Math.max(6, digits)));
1506
1488
  }
@@ -1578,7 +1560,7 @@ function useCopied() {
1578
1560
  }
1579
1561
  function CodeButton({ live, digits, size = "md", label }) {
1580
1562
  const { copied, copy } = useCopied();
1581
- const shown = live.code ? groupCode(live.code) : maskedCode(digits);
1563
+ const shown = live.code ? groupCode2(live.code) : maskedCode(digits);
1582
1564
  return /* @__PURE__ */ jsxs8(
1583
1565
  "button",
1584
1566
  {
@@ -1597,7 +1579,7 @@ function CodeButton({ live, digits, size = "md", label }) {
1597
1579
  }
1598
1580
  function CopyCodeButton({ live, label }) {
1599
1581
  const { copied, copy } = useCopied();
1600
- 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) });
1601
1583
  }
1602
1584
 
1603
1585
  // src/authenticator/live-code.ts
@@ -1869,7 +1851,7 @@ function OtpSetupRow({ value, onChange, label = "One-time password", placeholder
1869
1851
  className: dragging ? "rounded-lg bg-accent" : void 0,
1870
1852
  children: [
1871
1853
  /* @__PURE__ */ jsxs9(
1872
- Row,
1854
+ VaultRow,
1873
1855
  {
1874
1856
  label,
1875
1857
  actions: /* @__PURE__ */ jsxs9(Fragment4, { children: [
@@ -2019,7 +2001,7 @@ function TotpRow({ port, item, onChanged }) {
2019
2001
  ] })
2020
2002
  ] }) : null;
2021
2003
  return /* @__PURE__ */ jsx10(
2022
- Row,
2004
+ VaultRow,
2023
2005
  {
2024
2006
  label: "One-time password",
2025
2007
  actions: /* @__PURE__ */ jsxs10(Fragment5, { children: [
@@ -2078,7 +2060,7 @@ function TwoFactorMethodRow({ port, item, onChanged }) {
2078
2060
  const [busy, setBusy] = useState11(false);
2079
2061
  const [error, setError] = useState11(null);
2080
2062
  const canEdit = item.capabilities.canEdit || item.capabilities.canManage;
2081
- 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(
2082
2064
  Select,
2083
2065
  {
2084
2066
  value: value ?? "none",
@@ -2193,7 +2175,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2193
2175
  /* @__PURE__ */ jsx11(Button8, { variant: "primary", disabled: !ready, onClick: () => void save(), children: busy ? "Adding\u2026" : "Add" })
2194
2176
  ] }),
2195
2177
  children: [
2196
- /* @__PURE__ */ jsxs11(Section, { children: [
2178
+ /* @__PURE__ */ jsxs11(VaultSection, { children: [
2197
2179
  /* @__PURE__ */ jsx11(
2198
2180
  OtpSetupRow,
2199
2181
  {
@@ -2215,7 +2197,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2215
2197
  status: image ? `QR image ready \xB7 ${image.name}` : null
2216
2198
  }
2217
2199
  ),
2218
- /* @__PURE__ */ jsx11(Row, { label: "Add to", children: /* @__PURE__ */ jsx11(
2200
+ /* @__PURE__ */ jsx11(VaultRow, { label: "Add to", children: /* @__PURE__ */ jsx11(
2219
2201
  Select2,
2220
2202
  {
2221
2203
  value: target,
@@ -2229,7 +2211,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2229
2211
  }
2230
2212
  ) }),
2231
2213
  isNew ? /* @__PURE__ */ jsxs11(Fragment6, { children: [
2232
- /* @__PURE__ */ jsx11(Row, { label: "Name", children: /* @__PURE__ */ jsx11(
2214
+ /* @__PURE__ */ jsx11(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx11(
2233
2215
  Field4,
2234
2216
  {
2235
2217
  className: "w-full",
@@ -2243,7 +2225,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2243
2225
  "aria-label": "Name"
2244
2226
  }
2245
2227
  ) }),
2246
- /* @__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 }) })
2247
2229
  ] }) : null
2248
2230
  ] }),
2249
2231
  error ? /* @__PURE__ */ jsx11("p", { className: "px-1 text-sm text-destructive", role: "alert", children: error }) : null
@@ -2311,7 +2293,7 @@ function AuthenticatorView({ port, items, definitions, query, onOpen, onChanged,
2311
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" }) }),
2312
2294
  /* @__PURE__ */ jsx12("p", { className: "text-sm font-medium text-foreground", children: "No one-time passwords yet" }),
2313
2295
  /* @__PURE__ */ jsx12(Button9, { variant: "primary", icon: /* @__PURE__ */ jsx12(PlusGlyph, {}), onClick: () => setAdding(true), children: "Add one-time password" })
2314
- ] }) : 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(
2315
2297
  OtpListRow,
2316
2298
  {
2317
2299
  port,
@@ -2405,7 +2387,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2405
2387
  "Open login"
2406
2388
  ] }),
2407
2389
  live.code ? /* @__PURE__ */ jsxs12(DropdownMenuItem2, { onSelect: () => live.code && void copy(live.code), children: [
2408
- /* @__PURE__ */ jsx12(CopyGlyph, { className: "size-4" }),
2390
+ /* @__PURE__ */ jsx12(CopyIcon4, { className: "size-4" }),
2409
2391
  "Copy code"
2410
2392
  ] }) : null,
2411
2393
  canManage ? /* @__PURE__ */ jsxs12(Fragment7, { children: [
@@ -2432,6 +2414,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2432
2414
  import { useRef as useRef9, useState as useState14 } from "react";
2433
2415
  import { Badge as Badge3, Button as Button10, DisclosureHeader, Field as Field5, SegmentedControl, Select as Select3, Switch } from "@ai-matrx/design-system/controls";
2434
2416
  import { confirm as confirm3 } from "@ai-matrx/kit/confirm-opener";
2417
+ import { GlobeIcon as GlobeIcon2 } from "@ai-matrx/design-system/icons";
2435
2418
 
2436
2419
  // src/fields/rules.ts
2437
2420
  var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -2581,7 +2564,7 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2581
2564
  const locked = !canEdit || busy !== null;
2582
2565
  return /* @__PURE__ */ jsxs13(Panel, { title: `${field.label} settings`, size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
2583
2566
  !canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
2584
- /* @__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(
2585
2568
  SegmentedControl,
2586
2569
  {
2587
2570
  "aria-label": "Who can see it",
@@ -2590,8 +2573,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2590
2573
  data: handlingChoices(field.handling).map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint, disabled: locked }))
2591
2574
  }
2592
2575
  ) }) }),
2593
- /* @__PURE__ */ jsxs13(Section, { title: "Automation", children: [
2594
- /* @__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(
2595
2578
  Field5,
2596
2579
  {
2597
2580
  ref: envRef,
@@ -2611,10 +2594,10 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2611
2594
  }
2612
2595
  }
2613
2596
  ) }),
2614
- /* @__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) }) })
2615
2598
  ] }),
2616
- /* @__PURE__ */ jsxs13(Section, { title: "Field", children: [
2617
- /* @__PURE__ */ jsx13(Row, { label: "Description", children: /* @__PURE__ */ jsx13(
2599
+ /* @__PURE__ */ jsxs13(VaultSection, { title: "Field", children: [
2600
+ /* @__PURE__ */ jsx13(VaultRow, { label: "Description", children: /* @__PURE__ */ jsx13(
2618
2601
  Field5,
2619
2602
  {
2620
2603
  className: "w-full",
@@ -2630,8 +2613,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2630
2613
  }
2631
2614
  }
2632
2615
  ) }),
2633
- /* @__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 }) }) }),
2634
- /* @__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 }) }) })
2635
2618
  ] }),
2636
2619
  error ? /* @__PURE__ */ jsx13(Problem, { children: error }) : null
2637
2620
  ] });
@@ -2662,8 +2645,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2662
2645
  const fillHint = !hasWebsite ? "Add a website first" : item.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically";
2663
2646
  return /* @__PURE__ */ jsxs13(Panel, { title: "Item settings", size: "md", onClose, footer: /* @__PURE__ */ jsx13(Button10, { variant: "primary", onClick: onClose, children: "Done" }), children: [
2664
2647
  !canEdit ? /* @__PURE__ */ jsx13("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
2665
- /* @__PURE__ */ jsxs13(Section, { title: "In the browser", children: [
2666
- /* @__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(
2667
2650
  Select3,
2668
2651
  {
2669
2652
  "aria-label": "Website matching",
@@ -2673,13 +2656,13 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2673
2656
  onValueChange: (m) => void save("match", () => port.fields.updateItem(item, { uriMatchMode: m }))
2674
2657
  }
2675
2658
  ) }),
2676
- /* @__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 })) }) }),
2677
2660
  promotable.map((f) => /* @__PURE__ */ jsx13(
2678
- Row,
2661
+ VaultRow,
2679
2662
  {
2680
2663
  label: f.label,
2681
2664
  hint: quietHint("Encrypted, so the browser can\u2019t match it"),
2682
- 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" }),
2683
2666
  children: /* @__PURE__ */ jsx13("span", { className: "text-muted-foreground", children: "Not a website yet" })
2684
2667
  },
2685
2668
  f.id
@@ -2687,8 +2670,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2687
2670
  ] }),
2688
2671
  /* @__PURE__ */ jsxs13("div", { className: "flex flex-col gap-1.5", children: [
2689
2672
  /* @__PURE__ */ jsx13(DisclosureHeader, { open: advanced, title: "Advanced", meta: item.fields.length ? `${item.fields.length} fields` : void 0, onClick: () => setAdvanced((a) => !a) }),
2690
- advanced ? /* @__PURE__ */ jsx13(Section, { children: item.fields.length === 0 ? /* @__PURE__ */ jsx13(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ jsx13(
2691
- 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,
2692
2675
  {
2693
2676
  label: f.label,
2694
2677
  actions: /* @__PURE__ */ jsx13(Button10, { variant: "quiet", icon: /* @__PURE__ */ jsx13(SlidersGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) }),
@@ -2713,6 +2696,7 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2713
2696
  import { createContext as createContext5, useContext as useContext5, useEffect as useEffect12, useRef as useRef10, useState as useState15 } from "react";
2714
2697
  import { Popover, PopoverContent, PopoverTrigger, cn as cn7 } from "@ai-matrx/design-system";
2715
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";
2716
2700
 
2717
2701
  // src/generator/generate.ts
2718
2702
  import {
@@ -2870,7 +2854,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
2870
2854
  /* @__PURE__ */ jsxs14("div", { className: "flex min-h-7 items-start gap-1", children: [
2871
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" }),
2872
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) }),
2873
- /* @__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() }),
2874
2858
  /* @__PURE__ */ jsx14(Button11, { variant: "quiet", icon: /* @__PURE__ */ jsx14(RefreshGlyph, {}), "aria-label": "Generate another", onClick: () => change(settings) })
2875
2859
  ] }),
2876
2860
  strength && candidate ? /* @__PURE__ */ jsxs14("p", { className: "text-xs", children: [
@@ -2997,6 +2981,7 @@ function useLocked(lock) {
2997
2981
  }
2998
2982
 
2999
2983
  // src/io/BackupPanel.tsx
2984
+ import { formatFileSize } from "@ai-matrx/kit/format";
3000
2985
  import { useEffect as useEffect13, useRef as useRef11, useState as useState17 } from "react";
3001
2986
  import { Button as Button13, Field as Field6, SegmentedControl as SegmentedControl3, Switch as Switch3 } from "@ai-matrx/design-system/controls";
3002
2987
  import { downloadFile } from "@ai-matrx/kit/download";
@@ -3138,17 +3123,17 @@ function omissionText(o) {
3138
3123
  return `${o.count ?? "Some"} ${what}: ${o.reason.replaceAll("_", " ")}`;
3139
3124
  }
3140
3125
  function Summary({ value }) {
3141
- return /* @__PURE__ */ jsxs16(Section, { children: [
3142
- /* @__PURE__ */ jsx16(Row, { label: "Credentials", children: value.record_count }),
3143
- /* @__PURE__ */ jsx16(Row, { label: "Protected fields", children: value.field_count }),
3144
- /* @__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" })
3145
3130
  ] });
3146
3131
  }
3147
3132
  function Omissions({ omissions, accepted, onAccepted, verb }) {
3148
3133
  if (omissions.length === 0) return null;
3149
- return /* @__PURE__ */ jsxs16(Section, { title: "Left out", children: [
3150
- 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}`)),
3151
- /* @__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` }) })
3152
3137
  ] });
3153
3138
  }
3154
3139
  function BackupPanel({ port, items, onClose, onChanged }) {
@@ -3283,7 +3268,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3283
3268
  ),
3284
3269
  mode === "backup" ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
3285
3270
  /* @__PURE__ */ jsx16(
3286
- Section,
3271
+ VaultSection,
3287
3272
  {
3288
3273
  title: `${selected.size} of ${plural(items.length, "credential")}`,
3289
3274
  actions: /* @__PURE__ */ jsxs16(Fragment9, { children: [
@@ -3302,13 +3287,13 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3302
3287
  backup ? /* @__PURE__ */ jsxs16(Fragment9, { children: [
3303
3288
  /* @__PURE__ */ jsx16(Summary, { value: backup }),
3304
3289
  /* @__PURE__ */ jsx16(Omissions, { omissions: backup.omissions, accepted, onAccepted: setAccepted, verb: "Back up" }),
3305
- /* @__PURE__ */ jsxs16(Section, { children: [
3306
- /* @__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) }) }),
3307
- /* @__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) }) })
3308
3293
  ] })
3309
3294
  ] }) : null
3310
- ] }) : /* @__PURE__ */ jsx16(Fragment9, { children: !restorePreview ? /* @__PURE__ */ jsxs16(Section, { children: [
3311
- /* @__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: [
3312
3297
  /* @__PURE__ */ jsx16(Button13, { variant: "outline", disabled: busy, onClick: () => fileInput.current?.click(), children: "Choose a backup" }),
3313
3298
  /* @__PURE__ */ jsx16(
3314
3299
  "input",
@@ -3324,11 +3309,11 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3324
3309
  }
3325
3310
  )
3326
3311
  ] }),
3327
- /* @__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) }) })
3328
3313
  ] }) : /* @__PURE__ */ jsxs16(Fragment9, { children: [
3329
3314
  /* @__PURE__ */ jsx16(Summary, { value: restorePreview }),
3330
3315
  !result ? /* @__PURE__ */ jsx16(Omissions, { omissions: restorePreview.omissions, accepted, onAccepted: setAccepted, verb: "Restore" }) : null,
3331
- !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: [
3332
3317
  RECORD_STATUS[r.status],
3333
3318
  r.reason === "alias_conflict" ? " \xB7 name in use" : ""
3334
3319
  ] }) }, r.source_item_id)) })
@@ -3433,7 +3418,7 @@ function ExportPanel({ port, items, onClose }) {
3433
3418
  ] })
3434
3419
  ] }),
3435
3420
  children: [
3436
- /* @__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(
3437
3422
  Select5,
3438
3423
  {
3439
3424
  value: profile,
@@ -3446,7 +3431,7 @@ function ExportPanel({ port, items, onClose }) {
3446
3431
  }
3447
3432
  ) }) }),
3448
3433
  /* @__PURE__ */ jsx17(
3449
- Section,
3434
+ VaultSection,
3450
3435
  {
3451
3436
  title: `${selected.size} of ${plural(logins.length, "login")}`,
3452
3437
  actions: /* @__PURE__ */ jsxs17(Fragment10, { children: [
@@ -4517,13 +4502,13 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4517
4502
  /* @__PURE__ */ jsx18(Button15, { variant: "primary", onClick: onClose, children: "Done" })
4518
4503
  ] });
4519
4504
  return /* @__PURE__ */ jsxs18(Panel, { title: "Import", size: "xl", onClose, footer, children: [
4520
- stage === "choose" ? /* @__PURE__ */ jsxs18(Section, { children: [
4521
- /* @__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) => {
4522
4507
  setSource(s);
4523
4508
  setError(null);
4524
4509
  } }) }),
4525
- 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,
4526
- /* @__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: [
4527
4512
  /* @__PURE__ */ jsx18(Button15, { variant: "outline", disabled: reading, onClick: () => fileInput.current?.click(), children: reading ? "Reading\u2026" : source === "env" ? "Load a file" : "Choose a file" }),
4528
4513
  /* @__PURE__ */ jsx18(
4529
4514
  "input",
@@ -4540,12 +4525,12 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4540
4525
  }
4541
4526
  )
4542
4527
  ] }),
4543
- 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
4544
4529
  ] }) : null,
4545
4530
  stage === "review" && draft ? /* @__PURE__ */ jsxs18(Fragment11, { children: [
4546
- 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,
4547
4532
  /* @__PURE__ */ jsx18(
4548
- Section,
4533
+ VaultSection,
4549
4534
  {
4550
4535
  title: draft.kind === "env" ? plural(envKeys.length, "value") : summary(counts, lines.length),
4551
4536
  actions: /* @__PURE__ */ jsxs18(Fragment11, { children: [
@@ -4573,11 +4558,11 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4573
4558
  )
4574
4559
  }
4575
4560
  ),
4576
- 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,
4577
4562
  draft.kind === "file" ? /* @__PURE__ */ jsx18(Notices, { draft }) : null,
4578
- draft.kind === "file" ? /* @__PURE__ */ jsx18(More, { children: /* @__PURE__ */ jsxs18(Section, { children: [
4579
- /* @__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" }) }),
4580
- 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(
4581
4566
  Select6,
4582
4567
  {
4583
4568
  value: draft.mapping[index] ?? "keep",
@@ -4589,16 +4574,16 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4589
4574
  ] }) }) : null,
4590
4575
  ambiguous ? /* @__PURE__ */ jsx18(ErrorLine, { message: "Each of name, username, password, notes and one-time password can be used by one column." }) : null
4591
4576
  ] }) : null,
4592
- stage === "done" && done ? /* @__PURE__ */ jsxs18(Section, { title: "Result", children: [
4593
- /* @__PURE__ */ jsx18(Row, { label: "Created", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.created.length }) }),
4594
- /* @__PURE__ */ jsx18(Row, { label: "Skipped", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.skipped }) }),
4595
- /* @__PURE__ */ jsx18(Row, { label: "Failed", children: /* @__PURE__ */ jsx18("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
4596
- done.untried.length > 0 ? /* @__PURE__ */ jsx18(Row, { label: "Not tried", children: /* @__PURE__ */ jsx18("span", { className: "text-foreground", children: done.untried.length }) }) : null,
4597
- 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: [
4598
4583
  plural(done.withOtp, "login"),
4599
4584
  " still need the one-time password added."
4600
4585
  ] }) }) : null,
4601
- 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))
4602
4587
  ] }) : null,
4603
4588
  /* @__PURE__ */ jsx18(ErrorLine, { message: error })
4604
4589
  ] });
@@ -4658,11 +4643,13 @@ import { Badge as Badge7, Button as Button21, CONTROLS_CONTAINER_CLASS, OptionCo
4658
4643
  import { confirm as confirm9 } from "@ai-matrx/kit/confirm-opener";
4659
4644
 
4660
4645
  // src/activity/FilesSection.tsx
4646
+ import { formatFileSize as formatFileSize2 } from "@ai-matrx/kit/format";
4661
4647
  import { useRef as useRef13, useState as useState20 } from "react";
4662
4648
  import { Badge as Badge5, Button as Button16, Field as Field7, SegmentedControl as SegmentedControl4 } from "@ai-matrx/design-system/controls";
4663
4649
  import { cn as cn9 } from "@ai-matrx/design-system";
4664
4650
  import { confirm as confirm6 } from "@ai-matrx/kit/confirm-opener";
4665
4651
  import { downloadFile as downloadFile3 } from "@ai-matrx/kit/download";
4652
+ import { DownloadIcon } from "@ai-matrx/design-system/icons";
4666
4653
  import { Fragment as Fragment12, jsx as jsx20, jsxs as jsxs19 } from "react/jsx-runtime";
4667
4654
  var messageOf2 = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
4668
4655
  var TOO_BIG = "Files over 25 MB can't be stored.";
@@ -4721,7 +4708,7 @@ function FilesSection({ item, port, editing, onChanged }) {
4721
4708
  onDragLeave: canEdit ? () => setDragging(false) : void 0,
4722
4709
  onDrop: canEdit ? drop : void 0,
4723
4710
  children: /* @__PURE__ */ jsxs19(
4724
- Section,
4711
+ VaultSection,
4725
4712
  {
4726
4713
  title: "Files",
4727
4714
  actions: canEdit ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
@@ -4732,11 +4719,11 @@ function FilesSection({ item, port, editing, onChanged }) {
4732
4719
  } }) : null,
4733
4720
  item.attachments.map(
4734
4721
  (a) => canEdit ? /* @__PURE__ */ jsx20(EditableFile, { port, item, file: a, busy, run, onDownload: () => void download(a), onTooBig: () => setError(TOO_BIG) }, a.id) : /* @__PURE__ */ jsx20(
4735
- Row,
4722
+ VaultRow,
4736
4723
  {
4737
4724
  label: a.label,
4738
4725
  hint: a.description || void 0,
4739
- 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,
4740
4727
  children: /* @__PURE__ */ jsx20(FileName, { file: a })
4741
4728
  },
4742
4729
  a.id
@@ -4762,12 +4749,12 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4762
4749
  }
4763
4750
  return /* @__PURE__ */ jsxs19(Fragment12, { children: [
4764
4751
  /* @__PURE__ */ jsx20(
4765
- Row,
4752
+ VaultRow,
4766
4753
  {
4767
4754
  label: a.label,
4768
4755
  hint: a.description || void 0,
4769
4756
  actions: /* @__PURE__ */ jsxs19(Fragment12, { children: [
4770
- 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,
4771
4758
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PencilGlyph, {}), "aria-label": `Edit ${a.label}`, pressed: open, disabled: b !== null, onClick: () => setOpen((o) => !o) }),
4772
4759
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(UploadGlyph, {}), "aria-label": `Replace ${a.fileName}`, disabled: b !== null, onClick: () => replacer.current?.click() }),
4773
4760
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(TrashGlyph, {}), "aria-label": `Delete ${a.label}`, disabled: b !== null, onClick: () => void remove() }),
@@ -4798,7 +4785,7 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4798
4785
  function FileName({ file }) {
4799
4786
  return /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
4800
4787
  /* @__PURE__ */ jsx20("span", { className: "truncate", children: file.fileName }),
4801
- /* @__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) })
4802
4789
  ] });
4803
4790
  }
4804
4791
  function Protection({ value, locked, onChange }) {
@@ -4821,13 +4808,13 @@ function NewFile({ file, busy, onAdd, onCancel }) {
4821
4808
  await onAdd({ label: label.trim(), description: description.trim() || null, handling });
4822
4809
  }
4823
4810
  return /* @__PURE__ */ jsxs19(Fragment12, { children: [
4824
- /* @__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: [
4825
4812
  /* @__PURE__ */ jsx20("span", { className: "truncate", children: file.name }),
4826
- /* @__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) })
4827
4814
  ] }) }),
4828
- /* @__PURE__ */ jsx20(Row, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4829
- /* @__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) }) }),
4830
- /* @__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 }) }),
4831
4818
  /* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4832
4819
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4833
4820
  /* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !label.trim(), onClick: () => void add(), children: busy ? "Adding\u2026" : "Add file" })
@@ -4845,10 +4832,10 @@ function FileDetailsRows({ file, busy, onSave, onCancel }) {
4845
4832
  await onSave({ label: label.trim(), description: description.trim() || null, fileName: fileName.trim(), handling });
4846
4833
  }
4847
4834
  return /* @__PURE__ */ jsxs19(Fragment12, { children: [
4848
- /* @__PURE__ */ jsx20(Row, { label: "Name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4849
- /* @__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) }) }),
4850
- /* @__PURE__ */ jsx20(Row, { label: "File name", children: /* @__PURE__ */ jsx20(Field7, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
4851
- /* @__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 }) }),
4852
4839
  /* @__PURE__ */ jsxs19("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4853
4840
  /* @__PURE__ */ jsx20(Button16, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4854
4841
  /* @__PURE__ */ jsx20(Button16, { variant: "primary", disabled: busy || !changed || !label.trim() || !fileName.trim(), onClick: () => void save(), children: busy ? "Saving\u2026" : "Save" })
@@ -4867,6 +4854,7 @@ function confirmSeal(label) {
4867
4854
  // src/fields/RecoveryCodesRow.tsx
4868
4855
  import { useState as useState21 } from "react";
4869
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";
4870
4858
  import { Fragment as Fragment13, jsx as jsx21, jsxs as jsxs20 } from "react/jsx-runtime";
4871
4859
  var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
4872
4860
  var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
@@ -4907,7 +4895,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4907
4895
  };
4908
4896
  if (draft !== null) {
4909
4897
  return /* @__PURE__ */ jsxs20(
4910
- Row,
4898
+ VaultRow,
4911
4899
  {
4912
4900
  label: "Recovery codes",
4913
4901
  top: true,
@@ -4927,7 +4915,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4927
4915
  }
4928
4916
  if (!field) {
4929
4917
  if (!canEdit) return null;
4930
- 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" }) });
4931
4919
  }
4932
4920
  const sealed = field.handling === "sealed";
4933
4921
  const canSee = !sealed && item.capabilities.canReveal;
@@ -4949,7 +4937,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4949
4937
  });
4950
4938
  };
4951
4939
  return /* @__PURE__ */ jsx21(
4952
- Row,
4940
+ VaultRow,
4953
4941
  {
4954
4942
  label: "Recovery codes",
4955
4943
  top: codes !== null,
@@ -4960,7 +4948,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4960
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: [
4961
4949
  codes.map((code, i) => /* @__PURE__ */ jsxs20("li", { className: "flex min-h-7 items-center gap-1", children: [
4962
4950
  /* @__PURE__ */ jsx21("code", { className: "min-w-0 flex-1 break-all font-mono text-sm text-foreground", children: code }),
4963
- /* @__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") }),
4964
4952
  canEdit ? /* @__PURE__ */ jsx21(Button17, { variant: "quiet", icon: /* @__PURE__ */ jsx21(CheckGlyph, {}), disabled: busy, onClick: () => void markUsed(i), children: "Mark used" }) : null
4965
4953
  ] }, `${i}-${code}`)),
4966
4954
  error ? /* @__PURE__ */ jsx21("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
@@ -4969,33 +4957,17 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4969
4957
  );
4970
4958
  }
4971
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
+
4972
4964
  // src/draft-keep.ts
4973
4965
  var PREFIX = "matrx.vault.draft:";
4974
4966
  function draftKey(itemId, definitionKey) {
4975
4967
  return `${PREFIX}${itemId ?? `new:${definitionKey ?? "custom"}`}`;
4976
4968
  }
4977
- function keepDraft(key, basedOn, d) {
4978
- const kept = { basedOn, draft: { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom } };
4979
- try {
4980
- globalThis.sessionStorage?.setItem(key, JSON.stringify(kept));
4981
- } catch {
4982
- }
4983
- }
4984
- function readKeptDraft(key, basedOn) {
4985
- try {
4986
- const raw = globalThis.sessionStorage?.getItem(key);
4987
- if (!raw) return null;
4988
- const kept = JSON.parse(raw);
4989
- return kept.basedOn === basedOn ? kept.draft : null;
4990
- } catch {
4991
- return null;
4992
- }
4993
- }
4994
- function dropKeptDraft(key) {
4995
- try {
4996
- globalThis.sessionStorage?.removeItem(key);
4997
- } catch {
4998
- }
4969
+ function keptFieldsOf(d) {
4970
+ return { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom };
4999
4971
  }
5000
4972
 
5001
4973
  // src/extension/page-logic.ts
@@ -5142,6 +5114,7 @@ import { useEffect as useEffect15, useState as useState25 } from "react";
5142
5114
  import { confirm as confirm8 } from "@ai-matrx/kit/confirm-opener";
5143
5115
  import { Button as Button20, DisclosureHeader as DisclosureHeader3, Field as Field9, RegionSkeleton, Select as Select8 } from "@ai-matrx/design-system/controls";
5144
5116
  import { cn as cn11 } from "@ai-matrx/design-system";
5117
+ import { UsersIcon } from "@ai-matrx/design-system/icons";
5145
5118
 
5146
5119
  // src/sharing/logic.ts
5147
5120
  var LEVEL_OPTIONS = [
@@ -5173,7 +5146,7 @@ function copyRefusal(message2) {
5173
5146
  return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
5174
5147
  }
5175
5148
  var isPasskey = (item) => item.definitionKey === "native_passkey" || item.definitionKey === "passkey_private";
5176
- function moveConsequence(item, to) {
5149
+ function itemMoveConsequence(item, to) {
5177
5150
  if (item.authenticator) return "One-time password stays behind; set it up again";
5178
5151
  return to ? "Its members get access; people you shared with lose it" : "Only you; organization members lose access";
5179
5152
  }
@@ -5263,7 +5236,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5263
5236
  const to = destinationOf(moveChoice.value);
5264
5237
  const ok = await confirm7({
5265
5238
  title: `Move to ${moveChoice.label}?`,
5266
- 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)}.`,
5267
5240
  confirmLabel: "Move"
5268
5241
  });
5269
5242
  if (!ok) return;
@@ -5299,17 +5272,17 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5299
5272
  /* @__PURE__ */ jsx24(StatusLine, { error, notice }),
5300
5273
  /* @__PURE__ */ jsx24(Button19, { variant: "outline", className: "ml-auto", onClick: onClose, children: "Close" })
5301
5274
  ] }),
5302
- 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: [
5303
5276
  canMove && moves.length > 0 ? /* @__PURE__ */ jsx24(
5304
- Row,
5277
+ VaultRow,
5305
5278
  {
5306
5279
  label: "Move to",
5307
- hint: moveChoice ? moveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5280
+ hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5308
5281
  actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
5309
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] })
5310
5283
  }
5311
5284
  ) : null,
5312
- 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(
5313
5286
  Field8,
5314
5287
  {
5315
5288
  className: "w-full",
@@ -5323,7 +5296,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5323
5296
  onChange: (e) => setEmail(e.target.value)
5324
5297
  }
5325
5298
  ) }) : null,
5326
- 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
5327
5300
  ] })
5328
5301
  }
5329
5302
  );
@@ -5405,7 +5378,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5405
5378
  }
5406
5379
  };
5407
5380
  if (!item.capabilities.canManage) {
5408
- 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." }) }) });
5409
5382
  }
5410
5383
  return /* @__PURE__ */ jsxs23(
5411
5384
  Panel,
@@ -5418,9 +5391,9 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5418
5391
  /* @__PURE__ */ jsx25(Button20, { variant: "primary", className: "ml-auto", onClick: onClose, children: "Done" })
5419
5392
  ] }),
5420
5393
  children: [
5421
- /* @__PURE__ */ jsxs23(Section, { title: "Who has access", children: [
5394
+ /* @__PURE__ */ jsxs23(VaultSection, { title: "Who has access", children: [
5422
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" }) }),
5423
- 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(
5424
5397
  Select8,
5425
5398
  {
5426
5399
  variant: "inline",
@@ -5481,7 +5454,7 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
5481
5454
  const [level, setLevel] = useState25("use");
5482
5455
  const chosen = open.find((o) => o.id === target);
5483
5456
  if (item.owner.kind !== "me") return null;
5484
- 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: [
5485
5458
  /* @__PURE__ */ jsxs23("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5486
5459
  /* @__PURE__ */ jsx25(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5487
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 }))] }),
@@ -5531,7 +5504,7 @@ function MemberAccess({ port, organizationId, organizationName }) {
5531
5504
  const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
5532
5505
  if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
5533
5506
  };
5534
- return /* @__PURE__ */ jsxs23(Section, { title: `${organizationName} vault access`, children: [
5507
+ return /* @__PURE__ */ jsxs23(VaultSection, { title: `${organizationName} vault access`, children: [
5535
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(
5536
5509
  Select8,
5537
5510
  {
@@ -5607,7 +5580,7 @@ function ItemPane(props) {
5607
5580
  if (was && was.id === id && was.mode === mode && editing) {
5608
5581
  setDraft((d) => rebaseDraft(was.base, base, d));
5609
5582
  } else {
5610
- const kept = editing ? readKeptDraft(keepKey, item?.updatedAt ?? "new") : null;
5583
+ const kept = editing ? readKeptDraft(keepKey, { basedOn: item?.updatedAt ?? "new" })?.value ?? null : null;
5611
5584
  setDraft(kept ? { ...base, ...kept } : base);
5612
5585
  setTagsText((kept ?? base).tags.join(", "));
5613
5586
  setError(null);
@@ -5622,7 +5595,7 @@ function ItemPane(props) {
5622
5595
  useEffect16(() => onDirty(dirty), [dirty, onDirty]);
5623
5596
  const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
5624
5597
  useEffect16(() => {
5625
- if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new", draft);
5598
+ if (editing && dirty) keepDraft(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
5626
5599
  else if (!editing) dropKeptDraft(keepKey);
5627
5600
  }, [editing, dirty, draft, keepKey, item?.updatedAt]);
5628
5601
  useEffect16(() => {
@@ -5709,7 +5682,7 @@ function ItemPane(props) {
5709
5682
  const viewCustom = (item?.custom ?? []).filter((c) => !declaredKeys.has(c.key) && c.key !== MFA_METHOD_KEY && !isAuthenticatorStorage(c.key));
5710
5683
  const isLogin = (item?.definitionKey ?? definition?.key) === "website_login" || (item?.definitionKey ?? definition?.key) === "username_password";
5711
5684
  const typeLabel = definition?.label ?? item?.definitionLabel ?? "";
5712
- 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;
5713
5686
  const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
5714
5687
  const descriptionVisible = showDescription || draft.description !== "";
5715
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: [
@@ -5766,7 +5739,7 @@ function ItemPane(props) {
5766
5739
  "Send securely"
5767
5740
  ] }) : null,
5768
5741
  /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("history"), children: [
5769
- /* @__PURE__ */ jsx26(HistoryGlyph, { className: "size-4" }),
5742
+ /* @__PURE__ */ jsx26(HistoryIcon, { className: "size-4" }),
5770
5743
  "Password history"
5771
5744
  ] }),
5772
5745
  /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("activity"), children: [
@@ -5774,7 +5747,7 @@ function ItemPane(props) {
5774
5747
  "Activity"
5775
5748
  ] }),
5776
5749
  canEdit ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("settings"), children: [
5777
- /* @__PURE__ */ jsx26(SettingsGlyph, { className: "size-4" }),
5750
+ /* @__PURE__ */ jsx26(SettingsIcon, { className: "size-4" }),
5778
5751
  "Settings"
5779
5752
  ] }) : null,
5780
5753
  canManage ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
@@ -5794,8 +5767,8 @@ function ItemPane(props) {
5794
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,
5795
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,
5796
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: [
5797
- /* @__PURE__ */ jsxs24(Section, { children: [
5798
- 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(
5799
5772
  OptionCombobox,
5800
5773
  {
5801
5774
  value: owner,
@@ -5816,7 +5789,7 @@ function ItemPane(props) {
5816
5789
  /* @__PURE__ */ jsx26(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
5817
5790
  mode === "new" && owner === "person" ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
5818
5791
  /* @__PURE__ */ jsx26(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
5819
- 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
5820
5793
  ] }) : null,
5821
5794
  declared.map((f) => {
5822
5795
  const existing = item?.fields.find((x) => x.key === f.key);
@@ -5836,7 +5809,7 @@ function ItemPane(props) {
5836
5809
  actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
5837
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,
5838
5811
  secretKind ? /* @__PURE__ */ jsx26(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
5839
- 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
5840
5813
  ] })
5841
5814
  },
5842
5815
  f.key
@@ -5854,7 +5827,7 @@ function ItemPane(props) {
5854
5827
  removeLabel: `Delete ${f.label}`,
5855
5828
  actions: /* @__PURE__ */ jsxs24(Fragment15, { children: [
5856
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,
5857
- /* @__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}`) })
5858
5831
  ] })
5859
5832
  },
5860
5833
  f.id
@@ -5887,9 +5860,9 @@ function ItemPane(props) {
5887
5860
  /* @__PURE__ */ jsx26(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator), item, port, onEnrolled: onChanged }),
5888
5861
  item && isLogin && !item.authenticator ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
5889
5862
  ] }),
5890
- /* @__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 }) }) }),
5891
5864
  /* @__PURE__ */ jsxs24(
5892
- Section,
5865
+ VaultSection,
5893
5866
  {
5894
5867
  title: "More",
5895
5868
  actions: /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
@@ -5923,7 +5896,7 @@ function ItemPane(props) {
5923
5896
  ),
5924
5897
  filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: true }) : null
5925
5898
  ] }) : item ? /* @__PURE__ */ jsxs24(Fragment15, { children: [
5926
- /* @__PURE__ */ jsxs24(Section, { children: [
5899
+ /* @__PURE__ */ jsxs24(VaultSection, { children: [
5927
5900
  declared.map((f) => {
5928
5901
  if (f.storage === "metadata") {
5929
5902
  const v = metaValue(f.key);
@@ -5938,10 +5911,10 @@ function ItemPane(props) {
5938
5911
  item.authenticator ? /* @__PURE__ */ jsx26(TotpRow, { port, item, onChanged }) : /* @__PURE__ */ jsx26(AddRow, { label: "One-time password", onAdd: canEdit ? () => onMode("edit") : null, children: "Set up" }),
5939
5912
  !item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
5940
5913
  ] }),
5941
- /* @__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" }) }),
5942
- 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: [
5943
5916
  item.description ? /* @__PURE__ */ jsx26(PlainRow, { label: "Description", value: item.description }) : null,
5944
- 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,
5945
5918
  viewCustom.map((c) => /* @__PURE__ */ jsx26(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
5946
5919
  ] }) : null,
5947
5920
  filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: false }) : null,
@@ -6189,13 +6162,13 @@ function RestorePanel({ lists, item, restore, onClose }) {
6189
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" })
6190
6163
  ] }),
6191
6164
  children: [
6192
- loading ? /* @__PURE__ */ jsx28(Section, { children: /* @__PURE__ */ jsx28(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ jsxs26(Section, { title: "Comes back", children: [
6193
- /* @__PURE__ */ jsx28(Row, { label: "Fields", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
6194
- /* @__PURE__ */ jsx28(Row, { label: "Files", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
6195
- 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,
6196
- /* @__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" }) }),
6197
- 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
6198
- ] }) : 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." }) }),
6199
6172
  error ? /* @__PURE__ */ jsx28("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
6200
6173
  ]
6201
6174
  }
@@ -6227,7 +6200,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6227
6200
  };
6228
6201
  return /* @__PURE__ */ jsxs27("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
6229
6202
  header,
6230
- /* @__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) => (
6231
6204
  // A list row, not a field row: the name gets the whole width (on a phone a label column
6232
6205
  // left "Vau…" for every row), the deletion date sits under it.
6233
6206
  /* @__PURE__ */ jsxs27("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
@@ -6247,6 +6220,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6247
6220
  import { useMemo as useMemo4, useState as useState30 } from "react";
6248
6221
  import { cn as cn14 } from "@ai-matrx/design-system";
6249
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";
6250
6224
  import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
6251
6225
  function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6252
6226
  const [search, setSearch] = useState30("");
@@ -6281,7 +6255,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6281
6255
  "aria-label": "Website address",
6282
6256
  inputMode: "url",
6283
6257
  autoFocus: true,
6284
- icon: /* @__PURE__ */ jsx30(GlobeGlyph, {})
6258
+ icon: /* @__PURE__ */ jsx30(GlobeIcon3, {})
6285
6259
  }
6286
6260
  ),
6287
6261
  guess && login ? /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
@@ -6531,9 +6505,9 @@ function SecureLinkPanel({ item, port, onClose }) {
6531
6505
  ] }),
6532
6506
  children: [
6533
6507
  remedy ? /* @__PURE__ */ jsx31("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
6534
- /* @__PURE__ */ jsxs29(Section, { title: "Recipient", children: [
6535
- /* @__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" }) }),
6536
- /* @__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(
6537
6511
  Field11,
6538
6512
  {
6539
6513
  type: "tel",
@@ -6549,8 +6523,8 @@ function SecureLinkPanel({ item, port, onClose }) {
6549
6523
  className: "w-full"
6550
6524
  }
6551
6525
  ) }),
6552
- /* @__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" }) }),
6553
- 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(
6554
6528
  SegmentedControl5,
6555
6529
  {
6556
6530
  "aria-label": "Send the link by",
@@ -6562,26 +6536,26 @@ function SecureLinkPanel({ item, port, onClose }) {
6562
6536
  ]
6563
6537
  }
6564
6538
  ) }) : null,
6565
- 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
6566
6540
  ] }),
6567
- /* @__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: [
6568
6542
  /* @__PURE__ */ jsx31(Checkbox2, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
6569
6543
  /* @__PURE__ */ jsx31("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
6570
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
6571
6545
  ] }, f.key)) }),
6572
- /* @__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) }) }) }),
6573
- options ? /* @__PURE__ */ jsxs29(Section, { title: "Link", children: [
6574
- /* @__PURE__ */ jsx31(Row, { label: "Opens", children: /* @__PURE__ */ jsx31("span", { className: "text-foreground", children: "Once" }) }),
6575
- /* @__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: [
6576
6550
  "After ",
6577
6551
  lifetimeWords(options.linkMinutes)
6578
6552
  ] }) }),
6579
- /* @__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: [
6580
6554
  "After ",
6581
6555
  lifetimeWords(options.codeMinutes)
6582
6556
  ] }) })
6583
6557
  ] }) : null,
6584
- 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: [
6585
6559
  /* @__PURE__ */ jsx31(Badge8, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
6586
6560
  row.status === "pending" ? /* @__PURE__ */ jsx31(Button26, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
6587
6561
  ] }, row.id)) }) : null
@@ -6723,10 +6697,10 @@ function DevicesPanel({ port, onClose }) {
6723
6697
  };
6724
6698
  return /* @__PURE__ */ jsxs30(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
6725
6699
  /* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
6726
- /* @__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) => {
6727
6701
  const off = isRevoked(device);
6728
6702
  return /* @__PURE__ */ jsx32(
6729
- Row,
6703
+ VaultRow,
6730
6704
  {
6731
6705
  label: off ? "Turned off" : "Can fill",
6732
6706
  hint: off ? formatAbsoluteDate6(device.revokedAt, DAY_FORMAT, "") : void 0,
@@ -6814,18 +6788,18 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6814
6788
  /* @__PURE__ */ jsx32(Button27, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
6815
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
6816
6790
  ] });
6817
- 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: [
6818
6792
  "This link names no key. Start again from ",
6819
6793
  where,
6820
6794
  "."
6821
6795
  ] }) }) : /* @__PURE__ */ jsxs30(Fragment17, { children: [
6822
- /* @__PURE__ */ jsxs30(Section, { title: "What is asking", children: [
6823
- /* @__PURE__ */ jsx32(Row, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
6824
- name ? /* @__PURE__ */ jsx32(Row, { label: "Name", children: /* @__PURE__ */ jsx32("span", { className: "block truncate", children: name }) }) : null,
6825
- /* @__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) }) })
6826
6800
  ] }),
6827
6801
  /* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
6828
- /* @__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: [
6829
6803
  "Return to ",
6830
6804
  where,
6831
6805
  " by ",
@@ -6836,7 +6810,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6836
6810
  where,
6837
6811
  "."
6838
6812
  ] }) : !here ? /* @__PURE__ */ jsx32(
6839
- Row,
6813
+ VaultRow,
6840
6814
  {
6841
6815
  label: "Passkey",
6842
6816
  hint: `Passkeys work only on ${passkeys.rpId}`,
@@ -6844,14 +6818,14 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6844
6818
  children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: "Not on this page" })
6845
6819
  }
6846
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(
6847
- Row,
6821
+ VaultRow,
6848
6822
  {
6849
6823
  label: "Passkey",
6850
6824
  hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
6851
6825
  actions: /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
6852
6826
  children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
6853
6827
  }
6854
- ) : /* @__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" }) }) })
6855
6829
  ] }) });
6856
6830
  }
6857
6831
 
@@ -7129,7 +7103,7 @@ var TONE = {
7129
7103
  };
7130
7104
  function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
7131
7105
  if (!bridge) {
7132
- 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." }) }) });
7133
7107
  }
7134
7108
  return /* @__PURE__ */ jsx33(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
7135
7109
  }
@@ -7176,25 +7150,25 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7176
7150
  /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Done" })
7177
7151
  ] }) : /* @__PURE__ */ jsx33(Button28, { variant: "quiet", onClick: onClose, children: "Close" });
7178
7152
  return /* @__PURE__ */ jsxs31(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
7179
- screen.kind === "idle" ? /* @__PURE__ */ jsxs31(Section, { children: [
7180
- /* @__PURE__ */ jsx33(Row, { label: "Save to", children: /* @__PURE__ */ jsx33(Select9, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
7181
- /* @__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" }) }),
7182
- /* @__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" }) })
7183
7157
  ] }) : null,
7184
- 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(
7185
7159
  Windowed,
7186
7160
  {
7187
7161
  items: preview.slots,
7188
- 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)
7189
7163
  }
7190
7164
  ) }) : null,
7191
- status && !preview ? /* @__PURE__ */ jsxs31(Section, { title: `${accounted(status)} of ${status.total} done`, children: [
7192
- /* @__PURE__ */ jsx33(Row, { label: "Imported", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.committed }) }),
7193
- /* @__PURE__ */ jsx33(Row, { label: "Already there", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.already_present }) }),
7194
- /* @__PURE__ */ jsx33(Row, { label: "Can't import", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.unsupported }) }),
7195
- /* @__PURE__ */ jsx33(Row, { label: "Failed", children: /* @__PURE__ */ jsx33("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
7196
- status.uncertain > 0 ? /* @__PURE__ */ jsx33(Row, { label: "Needs recovery", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.uncertain }) }) : null,
7197
- 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
7198
7172
  ] }) : null,
7199
7173
  screen.message ? /* @__PURE__ */ jsx33("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
7200
7174
  /* @__PURE__ */ jsx33(ErrorLine, { message: limitError })
@@ -7205,6 +7179,7 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7205
7179
  import { useState as useState38 } from "react";
7206
7180
  import { DropdownMenu as DropdownMenu5, DropdownMenuContent as DropdownMenuContent5, DropdownMenuItem as DropdownMenuItem4, DropdownMenuTrigger as DropdownMenuTrigger5, SiteIcon } from "@ai-matrx/design-system";
7207
7181
  import { Button as Button32 } from "@ai-matrx/design-system/controls";
7182
+ import { GlobeIcon as GlobeIcon4 } from "@ai-matrx/design-system/icons";
7208
7183
 
7209
7184
  // src/extension/CaptureCard.tsx
7210
7185
  import { useState as useState35, useSyncExternalStore as useSyncExternalStore3 } from "react";
@@ -7347,6 +7322,7 @@ function FillSetupCard({ fillSetup }) {
7347
7322
  import { useState as useState37 } from "react";
7348
7323
  import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2 } from "@ai-matrx/design-system";
7349
7324
  import { Button as Button31 } from "@ai-matrx/design-system/controls";
7325
+ import { CopyIcon as CopyIcon7 } from "@ai-matrx/design-system/icons";
7350
7326
  import { Fragment as Fragment20, jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
7351
7327
  var HOLD_MS = 6e4;
7352
7328
  function PageGenerator({ fields }) {
@@ -7400,11 +7376,11 @@ function PageGenerator({ fields }) {
7400
7376
  const value = held.value;
7401
7377
  return /* @__PURE__ */ jsxs34(Fragment20, { children: [
7402
7378
  /* @__PURE__ */ jsx36(
7403
- Row,
7379
+ VaultRow,
7404
7380
  {
7405
7381
  label: "New password",
7406
7382
  actions: /* @__PURE__ */ jsxs34(Fragment20, { children: [
7407
- 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,
7408
7384
  /* @__PURE__ */ jsxs34(Popover2, { open, onOpenChange: setOpen, children: [
7409
7385
  /* @__PURE__ */ jsx36(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx36(Button31, { variant: "outline", icon: /* @__PURE__ */ jsx36(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
7410
7386
  /* @__PURE__ */ jsx36(PopoverContent2, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ jsx36(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
@@ -7413,7 +7389,7 @@ function PageGenerator({ fields }) {
7413
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" })
7414
7390
  }
7415
7391
  ),
7416
- 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
7417
7393
  ] });
7418
7394
  }
7419
7395
 
@@ -7475,7 +7451,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7475
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: [
7476
7452
  header,
7477
7453
  /* @__PURE__ */ jsxs35("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
7478
- /* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback: GlobeGlyph, className: "size-4" }),
7454
+ /* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback: GlobeIcon4, className: "size-4" }),
7479
7455
  /* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
7480
7456
  page.refresh ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
7481
7457
  onBrowse ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
@@ -7483,7 +7459,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7483
7459
  fillSetup ? /* @__PURE__ */ jsx37(FillSetupCard, { fillSetup }) : null,
7484
7460
  capture ? /* @__PURE__ */ jsx37(CaptureCard, { capture, onChanged }) : null,
7485
7461
  /* @__PURE__ */ jsx37(
7486
- Section,
7462
+ VaultSection,
7487
7463
  {
7488
7464
  title: "This site",
7489
7465
  actions: canSave ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
@@ -7491,7 +7467,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7491
7467
  }
7492
7468
  ),
7493
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,
7494
- 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
7495
7471
  ] }) });
7496
7472
  }
7497
7473
  function Outcome({ said, onDismiss }) {
@@ -7553,6 +7529,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
7553
7529
  import { useState as useState39 } from "react";
7554
7530
  import { cn as cn15, useLook as useLook2 } from "@ai-matrx/design-system";
7555
7531
  import { Select as Select10 } from "@ai-matrx/design-system/controls";
7532
+ import { GlobeIcon as GlobeIcon5 } from "@ai-matrx/design-system/icons";
7556
7533
  import { jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
7557
7534
  function vaultChoices(items, organizations, current) {
7558
7535
  const n = (f) => items.filter(f).length;
@@ -7568,7 +7545,7 @@ function vaultChoices(items, organizations, current) {
7568
7545
  function VaultSelect({ value, choices, onChange }) {
7569
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) })) });
7570
7547
  }
7571
- 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 };
7572
7549
  var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
7573
7550
  function itemCategory(item, definitions) {
7574
7551
  return categoryOf(item.definitionKey, familyOf(item.definitionKey, definitions));
@@ -7633,7 +7610,7 @@ function Group({ title, children }) {
7633
7610
  children
7634
7611
  ] });
7635
7612
  }
7636
- 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 }) {
7637
7614
  const [tagsOpen, setTagsOpen] = useState39(view.startsWith("tag:"));
7638
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: [
7639
7616
  /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
@@ -7642,7 +7619,7 @@ function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views,
7642
7619
  ] }),
7643
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: [
7644
7621
  /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5", children: [
7645
- 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,
7646
7623
  /* @__PURE__ */ jsx38(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
7647
7624
  hasFavorites ? /* @__PURE__ */ jsx38(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
7648
7625
  hasRecents ? /* @__PURE__ */ jsx38(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
@@ -7682,7 +7659,7 @@ var NO_HOST = {};
7682
7659
  var ITEM_PANELS = {
7683
7660
  share: SharePanel,
7684
7661
  move: MovePanel,
7685
- history: HistoryPanel,
7662
+ history: ItemHistoryPanel,
7686
7663
  activity: ActivityPanel,
7687
7664
  settings: ItemSettingsPanel,
7688
7665
  field: FieldSettingsPanel,
@@ -8073,7 +8050,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8073
8050
  ] }) : null,
8074
8051
  /* @__PURE__ */ jsxs37("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
8075
8052
  mode === "full" ? /* @__PURE__ */ jsx39(
8076
- Sidebar,
8053
+ VaultSidebar,
8077
8054
  {
8078
8055
  vault: loc.vault,
8079
8056
  choices,