@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.cjs CHANGED
@@ -222,6 +222,7 @@ var import_design_system2 = require("@ai-matrx/design-system");
222
222
  var import_controls = require("@ai-matrx/design-system/controls");
223
223
 
224
224
  // src/glyphs.tsx
225
+ var import_icons = require("@ai-matrx/design-system/icons");
225
226
  var import_jsx_runtime2 = require("react/jsx-runtime");
226
227
  function glyph(paths, air = [1, 1]) {
227
228
  const style = { "--matrx-glyph-air-l": air[0], "--matrx-glyph-air-r": air[1] };
@@ -233,10 +234,6 @@ var KeyGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_ru
233
234
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "7.5", cy: "15.5", r: "5.5" }),
234
235
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m21 2-9.6 9.6M15.5 7.5l3 3" })
235
236
  ] }), [1, 2]);
236
- var GlobeGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
237
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "10" }),
238
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" })
239
- ] }), [1, 1]);
240
237
  var NoteGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
241
238
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M15 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V7Z" }),
242
239
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M16 13H8M16 17H8" })
@@ -266,10 +263,6 @@ var FileGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_r
266
263
  var CodeGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m16 18 6-6-6-6M8 6l-6 6 6 6" }) }), [1, 1]);
267
264
  var StarGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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]);
268
265
  var PlusGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M12 5v14M5 12h14" }), [4, 4]);
269
- var CopyGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
270
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "9", y: "9", width: "13", height: "13", rx: "2" }),
271
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1" })
272
- ] }), [1, 1]);
273
266
  var EyeGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
274
267
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M2 12s3.6-7 10-7 10 7 10 7-3.6 7-10 7-10-7-10-7z" }),
275
268
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "3" })
@@ -294,11 +287,6 @@ var BuildingGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_j
294
287
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
295
288
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M9 22v-4h6v4M8 6h.01M16 6h.01M12 6h.01M12 10h.01M12 14h.01M16 10h.01M16 14h.01M8 10h.01M8 14h.01" })
296
289
  ] }), [3, 3]);
297
- var UsersGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
298
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M16 21v-2a4 4 0 0 0-4-4H6a4 4 0 0 0-4 4v2" }),
299
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "9", cy: "7", r: "4" }),
300
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M22 21v-2a4 4 0 0 0-3-3.9M16 3.1a4 4 0 0 1 0 7.8" })
301
- ] }), [1, 1]);
302
290
  var ChevronLeftGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m15 18-6-6 6-6" }), [8, 8]);
303
291
  var GridGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
304
292
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
@@ -317,7 +305,7 @@ var FAMILY_GLYPHS = {
317
305
  cloud_infrastructure: ServerGlyph
318
306
  };
319
307
  function definitionGlyph(key, family) {
320
- if (key === "username_password" || key === "website_login") return GlobeGlyph;
308
+ if (key === "username_password" || key === "website_login") return import_icons.GlobeIcon;
321
309
  return FAMILY_GLYPHS[family] ?? KeyGlyph;
322
310
  }
323
311
  var XGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }), [5, 5]);
@@ -335,15 +323,7 @@ var MoreGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_r
335
323
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "5", cy: "12", r: "1" })
336
324
  ] }), [3, 3]);
337
325
  var ShareGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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]);
338
- var HistoryGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
339
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8" }),
340
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M3 3v5h5M12 7v5l4 2" })
341
- ] }), [2, 2]);
342
326
  var ListGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M8 6h13M8 12h13M8 18h13M3 6h.01M3 12h.01M3 18h.01" }), [2, 2]);
343
- var SettingsGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
344
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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" }),
345
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "3" })
346
- ] }), [2, 2]);
347
327
  var ImportGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4M7 10l5 5 5-5M12 15V3" }), [2, 2]);
348
328
  var ExportGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("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]);
349
329
  var ChevronDownGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" }), [5, 5]);
@@ -384,10 +364,6 @@ var RefreshGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_js
384
364
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 3v5h-5M3 21v-5h5" })
385
365
  ] }), [2, 2]);
386
366
  var SlidersGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(import_jsx_runtime2.Fragment, { children: /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M4 21v-7M4 10V3M12 21v-9M12 8V3M20 21v-5M20 12V3M1 14h6M9 8h6M17 16h6" }) }), [0, 0]);
387
- var DownloadGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
388
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
389
- /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m7 10 5 5 5-5M12 15V3" })
390
- ] }), [2, 2]);
391
367
  var UploadGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
392
368
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
393
369
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m17 8-5-5-5 5M12 3v12" })
@@ -469,7 +445,7 @@ var Ctx2 = (0, import_react2.createContext)((run) => run());
469
445
  function useConfirmed() {
470
446
  return (0, import_react2.useContext)(Ctx2);
471
447
  }
472
- var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack" };
448
+ var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack", browser: "Browser", touch_id: "Touch ID" };
473
449
  var providerLabel = (p) => PROVIDER_LABEL[p] ?? p.charAt(0).toUpperCase() + p.slice(1);
474
450
  function IdentityGate({ identity, children }) {
475
451
  const [asking, setAsking] = (0, import_react2.useState)(false);
@@ -539,10 +515,21 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
539
515
  ] }),
540
516
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-col gap-3", children: [
541
517
  identity.dev ? /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(import_controls.Button, { variant: "primary", disabled: busy, onClick: () => void attempt(() => identity.dev?.() ?? Promise.resolve()), children: "Sign in again (dev)" }) : null,
542
- account10?.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(import_controls.Button, { variant: identity.dev ? "outline" : "primary", disabled: busy, onClick: () => void attempt(() => identity.withProvider(p), false), children: [
543
- "Continue with ",
544
- providerLabel(p)
545
- ] }, p)),
518
+ account10?.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
519
+ import_controls.Button,
520
+ {
521
+ variant: identity.dev ? "outline" : "primary",
522
+ disabled: busy,
523
+ onClick: () => void attempt(async () => {
524
+ if (await identity.withProvider(p) === "confirmed") onDone();
525
+ }, false),
526
+ children: [
527
+ "Continue with ",
528
+ providerLabel(p)
529
+ ]
530
+ },
531
+ p
532
+ )),
546
533
  account10?.hasPassword ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { className: "flex gap-2", onSubmit: (e) => {
547
534
  e.preventDefault();
548
535
  if (password) void attempt(() => identity.withPassword(password));
@@ -569,6 +556,7 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
569
556
  var import_react5 = require("react");
570
557
  var import_controls2 = require("@ai-matrx/design-system/controls");
571
558
  var import_design_system5 = require("@ai-matrx/design-system");
559
+ var import_icons2 = require("@ai-matrx/design-system/icons");
572
560
 
573
561
  // src/hooks.ts
574
562
  var import_react3 = require("react");
@@ -637,7 +625,7 @@ function useRoomOf(ref) {
637
625
  return room;
638
626
  }
639
627
  var RoomProvider = Room.Provider;
640
- function Section({ title, actions, children, className }) {
628
+ function VaultSection({ title, actions, children, className }) {
641
629
  const flat = (0, import_react4.useContext)(InPanel);
642
630
  const desktop = (0, import_design_system4.useLook)() === "desktop";
643
631
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: (0, import_design_system4.cn)("flex flex-col gap-1.5", className), children: [
@@ -653,7 +641,7 @@ var ROW_GRID = {
653
641
  roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
654
642
  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"
655
643
  };
656
- function Row({ label, hint, children, actions, top = false, className }) {
644
+ function VaultRow({ label, hint, children, actions, top = false, className }) {
657
645
  const room = (0, import_react4.useContext)(Room);
658
646
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: (0, import_design_system4.cn)("grid min-h-11 py-1", ROW_GRID[room ?? "viewport"], top ? "items-start" : "items-center", className), children: [
659
647
  /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { className: (0, import_design_system4.cn)("flex min-w-0 flex-col text-xs leading-tight text-muted-foreground", top && "pt-2.5"), children: [
@@ -674,11 +662,6 @@ function Panel({ title, open = true, onClose, children, footer, size = "lg" }) {
674
662
  footer ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.DialogFooter, { children: footer }) : null
675
663
  ] }) });
676
664
  }
677
- function formatBytes(n) {
678
- if (n < 1024) return `${n} B`;
679
- if (n < 1024 * 1024) return `${(n / 1024).toFixed(n < 10 * 1024 ? 1 : 0)} KB`;
680
- return `${(n / 1024 / 1024).toFixed(1)} MB`;
681
- }
682
665
  var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
683
666
 
684
667
  // src/FieldRows.tsx
@@ -737,14 +720,14 @@ function SecretRow({ port, item, field, extra }) {
737
720
  const multiline = field.kind === "multiline";
738
721
  const shown = visible ? plain : secret.value;
739
722
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
740
- Row,
723
+ VaultRow,
741
724
  {
742
725
  label: field.label,
743
726
  top: multiline && shown !== null,
744
727
  actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
745
728
  extra,
746
729
  canSee && !visible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EyeOffGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(EyeGlyph, {}), "aria-label": secret.value !== null ? `Hide ${field.label}` : `Show ${field.label}`, disabled: busy, onClick: () => void toggle2() }) : null,
747
- canSee ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CopyGlyph, {}), "aria-label": `Copy ${field.label}`, disabled: busy, onClick: () => void copy() }) : null
730
+ canSee ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons2.CopyIcon, {}), "aria-label": `Copy ${field.label}`, disabled: busy, onClick: () => void copy() }) : null
748
731
  ] }),
749
732
  children: sealed ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(LockGlyph, {}), children: "Sealed" }) : off ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-muted-foreground", children: "Turned off" }) : error ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "truncate text-destructive", title: error, children: error }) : shown !== null ? visible ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: (0, import_design_system5.cn)("block", multiline ? "whitespace-pre-wrap break-words" : "truncate"), children: shown || "\u2014" }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(SecretText, { value: shown, multiline }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: (0, import_design_system5.cn)("block truncate text-muted-foreground", !visible && "tracking-widest"), children: visible ? "\u2026" : MASK })
750
733
  }
@@ -754,7 +737,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
754
737
  const copyValue2 = useCopy();
755
738
  const isUrl = /^https?:\/\//i.test(value);
756
739
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
757
- Row,
740
+ VaultRow,
758
741
  {
759
742
  label,
760
743
  hint,
@@ -762,7 +745,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
762
745
  actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
763
746
  extra,
764
747
  isUrl && openUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExternalGlyph, {}), "aria-label": `Open ${value}`, onClick: () => openUrl(value) }) : null,
765
- /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CopyGlyph, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void copyValue2(value, typeof label === "string" && label ? label : "Value", { secret: false }) })
748
+ /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_icons2.CopyIcon, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void copyValue2(value, typeof label === "string" && label ? label : "Value", { secret: false }) })
766
749
  ] }),
767
750
  children: isUrl && openUrl ? (
768
751
  // A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
@@ -785,12 +768,12 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
785
768
  );
786
769
  }
787
770
  function AddRow({ label, onAdd, children = "Add" }) {
788
- return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(Row, { label, children: onAdd ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "text-sm text-muted-foreground hover:text-primary", onClick: onAdd, children }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-disabled-foreground", children: "\u2014" }) });
771
+ return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(VaultRow, { label, children: onAdd ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("button", { type: "button", className: "text-sm text-muted-foreground hover:text-primary", onClick: onAdd, children }) : /* @__PURE__ */ (0, import_jsx_runtime5.jsx)("span", { className: "text-disabled-foreground", children: "\u2014" }) });
789
772
  }
790
773
  function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
791
774
  const [shown, setShown] = (0, import_react5.useState)(false);
792
775
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
793
- Row,
776
+ VaultRow,
794
777
  {
795
778
  label,
796
779
  hint,
@@ -807,7 +790,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
807
790
  function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
808
791
  const [shown, setShown] = (0, import_react5.useState)(false);
809
792
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
810
- Row,
793
+ VaultRow,
811
794
  {
812
795
  label: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Field, { className: "w-full", value: label, onChange: (e) => onLabel(e.target.value), placeholder: "Name", "aria-label": "Field name" }),
813
796
  actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
@@ -820,6 +803,7 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
820
803
  }
821
804
 
822
805
  // src/activity/HistoryPanel.tsx
806
+ var import_icons3 = require("@ai-matrx/design-system/icons");
823
807
  var import_format3 = require("@ai-matrx/kit/format");
824
808
 
825
809
  // src/activity/logic.ts
@@ -1312,7 +1296,7 @@ function ActivityPanel({ item, port, onClose }) {
1312
1296
  footer: hasMore ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(import_controls3.Button, { variant: "outline", disabled: loading, onClick: () => setLimit((n) => Math.min(MAX, n * 2)), children: loading ? "Loading\u2026" : "Show more" }) : void 0,
1313
1297
  children: [
1314
1298
  error ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
1315
- entries === null ? loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Section, { title: day.label, children: collapseRuns(
1299
+ entries === null ? loading ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Reading activity\u2026" }) : null : entries.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(Empty, { children: "Nothing has happened yet." }) : groupByDay(entries, now).map((day) => /* @__PURE__ */ (0, import_jsx_runtime6.jsx)(VaultSection, { title: day.label, children: collapseRuns(
1316
1300
  day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
1317
1301
  (r) => `${r.s.what}|${r.s.who ?? ""}`
1318
1302
  ).map(({ row: { entry, s }, times }) => {
@@ -1335,7 +1319,7 @@ function ActivityPanel({ item, port, onClose }) {
1335
1319
  var import_jsx_runtime7 = require("react/jsx-runtime");
1336
1320
  var MASK2 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
1337
1321
  var messageOf = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
1338
- function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1322
+ function ItemHistoryPanel({ item, port, arg, onClose, onChanged }) {
1339
1323
  const eligible = historyEligible(item);
1340
1324
  const [page, setPage] = (0, import_react7.useState)(null);
1341
1325
  const [loading, setLoading] = (0, import_react7.useState)(eligible);
@@ -1397,7 +1381,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1397
1381
  error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
1398
1382
  notice ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "status", className: "px-1 text-sm text-success", children: notice }) : null,
1399
1383
  page && groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Empty, { children: "No earlier values yet." }) : null,
1400
- page ? groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(Section, { title: g.label, children: g.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HistoryRow, { item, port, page, entry, label: g.label, onRestored: restored, onConflict: conflicted, onError: setError }, `${item.id}:${entry.fieldId}:${entry.revision}`)) }, g.fieldId)) : null,
1384
+ page ? groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(VaultSection, { title: g.label, children: g.entries.map((entry) => /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(HistoryRow, { item, port, page, entry, label: g.label, onRestored: restored, onConflict: conflicted, onError: setError }, `${item.id}:${entry.fieldId}:${entry.revision}`)) }, g.fieldId)) : null,
1401
1385
  page && (page.captureStartedAt || page.incomplete) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("div", { className: "flex flex-wrap gap-x-3 gap-y-1 px-1 text-xs", children: [
1402
1386
  page.captureStartedAt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-muted-foreground", children: [
1403
1387
  "Kept since ",
@@ -1458,12 +1442,12 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1458
1442
  }
1459
1443
  }
1460
1444
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1461
- Row,
1445
+ VaultRow,
1462
1446
  {
1463
1447
  label: when,
1464
1448
  actions: entry.available ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1465
1449
  /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: secret.value !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EyeOffGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(EyeGlyph, {}), "aria-label": secret.value !== null ? "Hide" : "Show", disabled: busy, onClick: () => void toggle2() }),
1466
- /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(CopyGlyph, {}), "aria-label": "Copy", disabled: busy, onClick: () => void copy() }),
1450
+ /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_icons3.CopyIcon, {}), "aria-label": "Copy", disabled: busy, onClick: () => void copy() }),
1467
1451
  canRestore(page, entry) ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(RestoreGlyph, {}), "aria-label": "Restore", disabled: busy, onClick: () => void restore() }) : null
1468
1452
  ] }) : null,
1469
1453
  children: !entry.available ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(import_controls4.Badge, { children: "Not kept" }) : secret.value !== null ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(SecretText, { value: secret.value, multiline: false }) : /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("span", { className: "block truncate tracking-widest text-muted-foreground", children: MASK2 })
@@ -1475,6 +1459,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1475
1459
  var import_react13 = require("react");
1476
1460
  var import_controls9 = require("@ai-matrx/design-system/controls");
1477
1461
  var import_design_system9 = require("@ai-matrx/design-system");
1462
+ var import_icons5 = require("@ai-matrx/design-system/icons");
1478
1463
 
1479
1464
  // src/authenticator/AddOtpPanel.tsx
1480
1465
  var import_react12 = require("react");
@@ -1484,8 +1469,11 @@ var import_controls8 = require("@ai-matrx/design-system/controls");
1484
1469
  var import_react8 = require("react");
1485
1470
  var import_controls5 = require("@ai-matrx/design-system/controls");
1486
1471
  var import_design_system7 = require("@ai-matrx/design-system");
1472
+ var import_icons4 = require("@ai-matrx/design-system/icons");
1473
+ var import_format5 = require("@ai-matrx/kit/format");
1487
1474
 
1488
1475
  // src/authenticator/otpauth.ts
1476
+ var import_format4 = require("@ai-matrx/kit/format");
1489
1477
  var TOTP_DEFAULT_DIGITS = 6;
1490
1478
  var TOTP_DEFAULT_PERIOD = 30;
1491
1479
  var TOTP_DEFAULT_ALGORITHM = "SHA1";
@@ -1553,14 +1541,8 @@ function describeEnrollment(parsed) {
1553
1541
  const parts = [parsed.issuer, parsed.account].filter((p) => Boolean(p));
1554
1542
  return parts.length ? parts.join(" \xB7 ") : "Setup key";
1555
1543
  }
1556
- function groupCode(code) {
1557
- const c = code.replace(/\s/g, "");
1558
- if (c.length < 6) return c;
1559
- const head = Math.ceil(c.length / 2);
1560
- return `${c.slice(0, head)} ${c.slice(head)}`;
1561
- }
1562
1544
  function maskedCode(digits = TOTP_DEFAULT_DIGITS) {
1563
- return groupCode("\u2022".repeat(Math.max(6, digits)));
1545
+ return (0, import_format4.groupCode)("\u2022".repeat(Math.max(6, digits)));
1564
1546
  }
1565
1547
  function accountOfLabel(label, issuer) {
1566
1548
  const l = label?.trim();
@@ -1636,7 +1618,7 @@ function useCopied() {
1636
1618
  }
1637
1619
  function CodeButton({ live, digits, size = "md", label }) {
1638
1620
  const { copied, copy } = useCopied();
1639
- const shown = live.code ? groupCode(live.code) : maskedCode(digits);
1621
+ const shown = live.code ? (0, import_format5.groupCode)(live.code) : maskedCode(digits);
1640
1622
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1641
1623
  "button",
1642
1624
  {
@@ -1655,7 +1637,7 @@ function CodeButton({ live, digits, size = "md", label }) {
1655
1637
  }
1656
1638
  function CopyCodeButton({ live, label }) {
1657
1639
  const { copied, copy } = useCopied();
1658
- return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_controls5.Button, { variant: "quiet", icon: copied ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CopyGlyph, {}), ...copied ? { glyphTone: "success" } : {}, "aria-label": `Copy ${label} code`, disabled: !live.code, onClick: () => live.code && void copy(live.code) });
1640
+ return /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_controls5.Button, { variant: "quiet", icon: copied ? /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(CheckGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime8.jsx)(import_icons4.CopyIcon, {}), ...copied ? { glyphTone: "success" } : {}, "aria-label": `Copy ${label} code`, disabled: !live.code, onClick: () => live.code && void copy(live.code) });
1659
1641
  }
1660
1642
 
1661
1643
  // src/authenticator/live-code.ts
@@ -1927,7 +1909,7 @@ function OtpSetupRow({ value, onChange, label = "One-time password", placeholder
1927
1909
  className: dragging ? "rounded-lg bg-accent" : void 0,
1928
1910
  children: [
1929
1911
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1930
- Row,
1912
+ VaultRow,
1931
1913
  {
1932
1914
  label,
1933
1915
  actions: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
@@ -2077,7 +2059,7 @@ function TotpRow({ port, item, onChanged }) {
2077
2059
  ] })
2078
2060
  ] }) : null;
2079
2061
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2080
- Row,
2062
+ VaultRow,
2081
2063
  {
2082
2064
  label: "One-time password",
2083
2065
  actions: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
@@ -2136,7 +2118,7 @@ function TwoFactorMethodRow({ port, item, onChanged }) {
2136
2118
  const [busy, setBusy] = (0, import_react11.useState)(false);
2137
2119
  const [error, setError] = (0, import_react11.useState)(null);
2138
2120
  const canEdit = item.capabilities.canEdit || item.capabilities.canManage;
2139
- return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(Row, { label: "Two-factor", hint: error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-destructive", children: error }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2121
+ return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(VaultRow, { label: "Two-factor", hint: error ? /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "text-destructive", children: error }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2140
2122
  import_controls7.Select,
2141
2123
  {
2142
2124
  value: value ?? "none",
@@ -2251,7 +2233,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2251
2233
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_controls8.Button, { variant: "primary", disabled: !ready, onClick: () => void save(), children: busy ? "Adding\u2026" : "Add" })
2252
2234
  ] }),
2253
2235
  children: [
2254
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Section, { children: [
2236
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(VaultSection, { children: [
2255
2237
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2256
2238
  OtpSetupRow,
2257
2239
  {
@@ -2273,7 +2255,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2273
2255
  status: image ? `QR image ready \xB7 ${image.name}` : null
2274
2256
  }
2275
2257
  ),
2276
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Row, { label: "Add to", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2258
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Add to", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2277
2259
  import_controls8.Select,
2278
2260
  {
2279
2261
  value: target,
@@ -2287,7 +2269,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2287
2269
  }
2288
2270
  ) }),
2289
2271
  isNew ? /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(import_jsx_runtime11.Fragment, { children: [
2290
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Row, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2272
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2291
2273
  import_controls8.Field,
2292
2274
  {
2293
2275
  className: "w-full",
@@ -2301,7 +2283,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2301
2283
  "aria-label": "Name"
2302
2284
  }
2303
2285
  ) }),
2304
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Row, { label: "Website", hint: websiteBad ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-destructive", children: "Not a web address" }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_controls8.Field, { 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 }) })
2286
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Website", hint: websiteBad ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("span", { className: "text-destructive", children: "Not a web address" }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_controls8.Field, { 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 }) })
2305
2287
  ] }) : null
2306
2288
  ] }),
2307
2289
  error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "px-1 text-sm text-destructive", role: "alert", children: error }) : null
@@ -2369,7 +2351,7 @@ function AuthenticatorView({ port, items, definitions, query, onOpen, onChanged,
2369
2351
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("span", { className: "flex size-12 items-center justify-center rounded-full bg-muted text-muted-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(ShieldGlyph, { className: "size-6" }) }),
2370
2352
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-medium text-foreground", children: "No one-time passwords yet" }),
2371
2353
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_controls9.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(PlusGlyph, {}), onClick: () => setAdding(true), children: "Add one-time password" })
2372
- ] }) : groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(Section, { ...groups.length > 1 ? { title: g.label } : {}, className: "[&>div]:px-1", children: g.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2354
+ ] }) : groups.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "px-4 py-10 text-center text-sm text-muted-foreground", children: "Nothing matches." }) : /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto px-3 pb-6 pt-1 sm:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5", children: groups.map((g) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(VaultSection, { ...groups.length > 1 ? { title: g.label } : {}, className: "[&>div]:px-1", children: g.items.map((item) => /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(
2373
2355
  OtpListRow,
2374
2356
  {
2375
2357
  port,
@@ -2463,7 +2445,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2463
2445
  "Open login"
2464
2446
  ] }),
2465
2447
  live.code ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_design_system9.DropdownMenuItem, { onSelect: () => live.code && void copy(live.code), children: [
2466
- /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(CopyGlyph, { className: "size-4" }),
2448
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_icons5.CopyIcon, { className: "size-4" }),
2467
2449
  "Copy code"
2468
2450
  ] }) : null,
2469
2451
  canManage ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
@@ -2490,6 +2472,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2490
2472
  var import_react14 = require("react");
2491
2473
  var import_controls10 = require("@ai-matrx/design-system/controls");
2492
2474
  var import_confirm_opener3 = require("@ai-matrx/kit/confirm-opener");
2475
+ var import_icons6 = require("@ai-matrx/design-system/icons");
2493
2476
 
2494
2477
  // src/fields/rules.ts
2495
2478
  var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -2639,7 +2622,7 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2639
2622
  const locked = !canEdit || busy !== null;
2640
2623
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Panel, { title: `${field.label} settings`, size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: [
2641
2624
  !canEdit ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
2642
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Section, { title: "Who can see it", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Value", hint: quietHint(handling.hint), children: field.handling === "sealed" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LockGlyph, {}), children: "Sealed for good" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2625
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultSection, { title: "Who can see it", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Value", hint: quietHint(handling.hint), children: field.handling === "sealed" ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(LockGlyph, {}), children: "Sealed for good" }) : /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2643
2626
  import_controls10.SegmentedControl,
2644
2627
  {
2645
2628
  "aria-label": "Who can see it",
@@ -2648,8 +2631,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2648
2631
  data: handlingChoices(field.handling).map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint, disabled: locked }))
2649
2632
  }
2650
2633
  ) }) }),
2651
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Section, { title: "Automation", children: [
2652
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Env key", hint: envProblem ? quietHint(envProblem, "destructive") : quietHint("The name sandboxes and workflows use"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2634
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "Automation", children: [
2635
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Env key", hint: envProblem ? quietHint(envProblem, "destructive") : quietHint("The name sandboxes and workflows use"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2653
2636
  import_controls10.Field,
2654
2637
  {
2655
2638
  ref: envRef,
@@ -2669,10 +2652,10 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2669
2652
  }
2670
2653
  }
2671
2654
  ) }),
2672
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Use in sandbox", hint: blocker && !field.injectIntoSandbox ? quietHint(blocker) : quietHint("Sandboxes get it as an env variable"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Use in sandbox", checked: field.injectIntoSandbox, disabled: locked, onCheckedChange: (v) => void setSandbox(v) }) })
2655
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Use in sandbox", hint: blocker && !field.injectIntoSandbox ? quietHint(blocker) : quietHint("Sandboxes get it as an env variable"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Use in sandbox", checked: field.injectIntoSandbox, disabled: locked, onCheckedChange: (v) => void setSandbox(v) }) })
2673
2656
  ] }),
2674
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Section, { title: "Field", children: [
2675
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Description", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2657
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "Field", children: [
2658
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Description", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2676
2659
  import_controls10.Field,
2677
2660
  {
2678
2661
  className: "w-full",
@@ -2688,8 +2671,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2688
2671
  }
2689
2672
  }
2690
2673
  ) }),
2691
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Editable", hint: quietHint(field.editable ? "The value can be changed" : "The value is locked"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Editable", checked: field.editable, disabled: locked, onCheckedChange: (v) => void update("editable", { editable: v }) }) }),
2692
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Active", hint: quietHint(field.active ? "In use" : "Kept, but nothing uses it"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Active", checked: field.active, disabled: locked, onCheckedChange: (v) => void update("active", { active: v }) }) })
2674
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Editable", hint: quietHint(field.editable ? "The value can be changed" : "The value is locked"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Editable", checked: field.editable, disabled: locked, onCheckedChange: (v) => void update("editable", { editable: v }) }) }),
2675
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Active", hint: quietHint(field.active ? "In use" : "Kept, but nothing uses it"), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Active", checked: field.active, disabled: locked, onCheckedChange: (v) => void update("active", { active: v }) }) })
2693
2676
  ] }),
2694
2677
  error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Problem, { children: error }) : null
2695
2678
  ] });
@@ -2720,8 +2703,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2720
2703
  const fillHint = !hasWebsite ? "Add a website first" : item.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically";
2721
2704
  return /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Panel, { title: "Item settings", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: [
2722
2705
  !canEdit ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("p", { className: "px-1 text-sm text-muted-foreground", children: "View only: you can\u2019t change these settings." }) : null,
2723
- /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(Section, { title: "In the browser", children: [
2724
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Website matching", hint: quietHint(MATCH_WORDS[item.uriMatchMode].hint), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2706
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "In the browser", children: [
2707
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Website matching", hint: quietHint(MATCH_WORDS[item.uriMatchMode].hint), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2725
2708
  import_controls10.Select,
2726
2709
  {
2727
2710
  "aria-label": "Website matching",
@@ -2731,13 +2714,13 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2731
2714
  onValueChange: (m) => void save("match", () => port.fields.updateItem(item, { uriMatchMode: m }))
2732
2715
  }
2733
2716
  ) }),
2734
- /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Row, { label: "Fill in browser", hint: quietHint(fillHint), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Fill in browser", checked: hasWebsite && item.browserFillEnabled, disabled: locked || !hasWebsite, onCheckedChange: (v) => void save("fill", () => port.fields.updateItem(item, { browserFillEnabled: v })) }) }),
2717
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Fill in browser", hint: quietHint(fillHint), children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Switch, { "aria-label": "Fill in browser", checked: hasWebsite && item.browserFillEnabled, disabled: locked || !hasWebsite, onCheckedChange: (v) => void save("fill", () => port.fields.updateItem(item, { browserFillEnabled: v })) }) }),
2735
2718
  promotable.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2736
- Row,
2719
+ VaultRow,
2737
2720
  {
2738
2721
  label: f.label,
2739
2722
  hint: quietHint("Encrypted, so the browser can\u2019t match it"),
2740
- actions: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(GlobeGlyph, {}), disabled: locked, onClick: () => void promote(f), children: "Use as website" }),
2723
+ actions: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_icons6.GlobeIcon, {}), disabled: locked, onClick: () => void promote(f), children: "Use as website" }),
2741
2724
  children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-muted-foreground", children: "Not a website yet" })
2742
2725
  },
2743
2726
  f.id
@@ -2745,8 +2728,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2745
2728
  ] }),
2746
2729
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
2747
2730
  /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.DisclosureHeader, { open: advanced, title: "Advanced", meta: item.fields.length ? `${item.fields.length} fields` : void 0, onClick: () => setAdvanced((a) => !a) }),
2748
- advanced ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Section, { children: item.fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2749
- Row,
2731
+ advanced ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultSection, { children: item.fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Empty, { children: "No encrypted fields." }) : item.fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2732
+ VaultRow,
2750
2733
  {
2751
2734
  label: f.label,
2752
2735
  actions: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(import_controls10.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(SlidersGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) }),
@@ -2771,6 +2754,7 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2771
2754
  var import_react15 = require("react");
2772
2755
  var import_design_system10 = require("@ai-matrx/design-system");
2773
2756
  var import_controls11 = require("@ai-matrx/design-system/controls");
2757
+ var import_icons7 = require("@ai-matrx/design-system/icons");
2774
2758
 
2775
2759
  // src/generator/generate.ts
2776
2760
  var import_credential_generator = require("@ai-matrx/kit/credential-generator");
@@ -2925,7 +2909,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
2925
2909
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-h-7 items-start gap-1", children: [
2926
2910
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)("code", { className: (0, import_design_system10.cn)("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" }),
2927
2911
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: revealed ? /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(EyeOffGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(EyeGlyph, {}), "aria-label": revealed ? "Hide" : "Reveal", disabled: !candidate, onClick: () => setRevealed((r) => !r) }),
2928
- /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(CopyGlyph, {}), "aria-label": "Copy", disabled: !candidate, onClick: () => void copy() }),
2912
+ /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_icons7.CopyIcon, {}), "aria-label": "Copy", disabled: !candidate, onClick: () => void copy() }),
2929
2913
  /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(import_controls11.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime14.jsx)(RefreshGlyph, {}), "aria-label": "Generate another", onClick: () => change(settings) })
2930
2914
  ] }),
2931
2915
  strength && candidate ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "text-xs", children: [
@@ -3052,6 +3036,7 @@ function useLocked(lock) {
3052
3036
  }
3053
3037
 
3054
3038
  // src/io/BackupPanel.tsx
3039
+ var import_format6 = require("@ai-matrx/kit/format");
3055
3040
  var import_react18 = require("react");
3056
3041
  var import_controls13 = require("@ai-matrx/design-system/controls");
3057
3042
  var import_download = require("@ai-matrx/kit/download");
@@ -3193,17 +3178,17 @@ function omissionText(o) {
3193
3178
  return `${o.count ?? "Some"} ${what}: ${o.reason.replaceAll("_", " ")}`;
3194
3179
  }
3195
3180
  function Summary({ value }) {
3196
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Section, { children: [
3197
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: "Credentials", children: value.record_count }),
3198
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: "Protected fields", children: value.field_count }),
3199
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: "Files", children: value.attachment_count > 0 ? `${value.attachment_count} \xB7 ${formatBytes(value.attachment_bytes)}` : "0" })
3181
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
3182
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Credentials", children: value.record_count }),
3183
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Protected fields", children: value.field_count }),
3184
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Files", children: value.attachment_count > 0 ? `${value.attachment_count} \xB7 ${(0, import_format6.formatFileSize)(value.attachment_bytes)}` : "0" })
3200
3185
  ] });
3201
3186
  }
3202
3187
  function Omissions({ omissions, accepted, onAccepted, verb }) {
3203
3188
  if (omissions.length === 0) return null;
3204
- return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Section, { title: "Left out", children: [
3205
- omissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: o.component.replaceAll("_", " "), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "block truncate text-muted-foreground", title: omissionText(o), children: omissionText(o) }) }, `${o.component}-${o.source_item_id ?? i}`)),
3206
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: "Accept", hint: `${verb} without these`, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Switch, { checked: accepted, onCheckedChange: onAccepted, "aria-label": `${verb} without these` }) })
3189
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { title: "Left out", children: [
3190
+ omissions.map((o, i) => /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: o.component.replaceAll("_", " "), children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("span", { className: "block truncate text-muted-foreground", title: omissionText(o), children: omissionText(o) }) }, `${o.component}-${o.source_item_id ?? i}`)),
3191
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Accept", hint: `${verb} without these`, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Switch, { checked: accepted, onCheckedChange: onAccepted, "aria-label": `${verb} without these` }) })
3207
3192
  ] });
3208
3193
  }
3209
3194
  function BackupPanel({ port, items, onClose, onChanged }) {
@@ -3338,7 +3323,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3338
3323
  ),
3339
3324
  mode === "backup" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3340
3325
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3341
- Section,
3326
+ VaultSection,
3342
3327
  {
3343
3328
  title: `${selected.size} of ${plural(items.length, "credential")}`,
3344
3329
  actions: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
@@ -3357,13 +3342,13 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3357
3342
  backup ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3358
3343
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Summary, { value: backup }),
3359
3344
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Omissions, { omissions: backup.omissions, accepted, onAccepted: setAccepted, verb: "Back up" }),
3360
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Section, { children: [
3361
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: "Passphrase", hint: "Not saved. It can't be recovered.", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) }),
3362
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: "Repeat", ...mismatch ? { hint: "Doesn't match" } : {}, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: repeat, autoComplete: "new-password", "aria-label": "Repeat the passphrase", onChange: (e) => setRepeat(e.target.value) }) })
3345
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
3346
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Passphrase", hint: "Not saved. It can't be recovered.", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: passphrase, autoComplete: "new-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) }),
3347
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Repeat", ...mismatch ? { hint: "Doesn't match" } : {}, children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: repeat, autoComplete: "new-password", "aria-label": "Repeat the passphrase", onChange: (e) => setRepeat(e.target.value) }) })
3363
3348
  ] })
3364
3349
  ] }) : null
3365
- ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: !restorePreview ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Section, { children: [
3366
- /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(Row, { label: "File", ...file ? { hint: file.name } : {}, children: [
3350
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: !restorePreview ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
3351
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultRow, { label: "File", ...file ? { hint: file.name } : {}, children: [
3367
3352
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Button, { variant: "outline", disabled: busy, onClick: () => fileInput.current?.click(), children: "Choose a backup" }),
3368
3353
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3369
3354
  "input",
@@ -3379,11 +3364,11 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3379
3364
  }
3380
3365
  )
3381
3366
  ] }),
3382
- /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Row, { label: "Passphrase", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: passphrase, autoComplete: "current-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) })
3367
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Passphrase", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Field, { type: "password", value: passphrase, autoComplete: "current-password", "aria-label": "Backup passphrase", onChange: (e) => setPassphrase(e.target.value) }) })
3383
3368
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3384
3369
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Summary, { value: restorePreview }),
3385
3370
  !result ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Omissions, { omissions: restorePreview.omissions, accepted, onAccepted: setAccepted, verb: "Restore" }) : null,
3386
- !result ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(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__ */ (0, import_jsx_runtime16.jsx)(Row, { label: names.get(r.source_item_id) ?? "Credential", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: r.status === "refused" || r.status === "retryable_failure" ? "text-destructive" : "text-foreground", children: [
3371
+ !result ? /* @__PURE__ */ (0, import_jsx_runtime16.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: "Restored items start disabled and restricted." }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(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__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: names.get(r.source_item_id) ?? "Credential", children: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)("span", { className: r.status === "refused" || r.status === "retryable_failure" ? "text-destructive" : "text-foreground", children: [
3387
3372
  RECORD_STATUS[r.status],
3388
3373
  r.reason === "alias_conflict" ? " \xB7 name in use" : ""
3389
3374
  ] }) }, r.source_item_id)) })
@@ -3488,7 +3473,7 @@ function ExportPanel({ port, items, onClose }) {
3488
3473
  ] })
3489
3474
  ] }),
3490
3475
  children: [
3491
- /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(Row, { label: "Format", hint: format?.hint, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3476
+ /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(VaultRow, { label: "Format", hint: format?.hint, children: /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3492
3477
  import_controls14.Select,
3493
3478
  {
3494
3479
  value: profile,
@@ -3501,7 +3486,7 @@ function ExportPanel({ port, items, onClose }) {
3501
3486
  }
3502
3487
  ) }) }),
3503
3488
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3504
- Section,
3489
+ VaultSection,
3505
3490
  {
3506
3491
  title: `${selected.size} of ${plural(logins.length, "login")}`,
3507
3492
  actions: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
@@ -4572,13 +4557,13 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4572
4557
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "primary", onClick: onClose, children: "Done" })
4573
4558
  ] });
4574
4559
  return /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Panel, { title: "Import", size: "xl", onClose, footer, children: [
4575
- stage === "choose" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Section, { children: [
4576
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Source", actions: help && host.openUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "quiet", onClick: () => host.openUrl?.(help), children: "How to export" }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Select, { value: source, options: SOURCE_OPTIONS, "aria-label": "Source", onValueChange: (s) => {
4560
+ stage === "choose" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { children: [
4561
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Source", actions: help && host.openUrl ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "quiet", onClick: () => host.openUrl?.(help), children: "How to export" }) : void 0, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Select, { value: source, options: SOURCE_OPTIONS, "aria-label": "Source", onValueChange: (s) => {
4577
4562
  setSource(s);
4578
4563
  setError(null);
4579
4564
  } }) }),
4580
- source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: ".env text", hint: "Same key updates in place", top: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Textarea, { 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,
4581
- /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Row, { label: "File", hint: fileName ?? void 0, children: [
4565
+ source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: ".env text", hint: "Same key updates in place", top: true, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Textarea, { 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,
4566
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultRow, { label: "File", hint: fileName ?? void 0, children: [
4582
4567
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "outline", disabled: reading, onClick: () => fileInput.current?.click(), children: reading ? "Reading\u2026" : source === "env" ? "Load a file" : "Choose a file" }),
4583
4568
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4584
4569
  "input",
@@ -4595,12 +4580,12 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4595
4580
  }
4596
4581
  )
4597
4582
  ] }),
4598
- source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Sandboxes", hint: "Pass these values to agent sandboxes", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: injectSandbox, onCheckedChange: setInjectSandbox, "aria-label": "Use in sandboxes" }) }) : null
4583
+ source === "env" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Sandboxes", hint: "Pass these values to agent sandboxes", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: injectSandbox, onCheckedChange: setInjectSandbox, "aria-label": "Use in sandboxes" }) }) : null
4599
4584
  ] }) : null,
4600
4585
  stage === "review" && draft ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
4601
- organizations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Select, { value: destination, options: destinationOptions, "aria-label": "Save to", onValueChange: (v) => draft.kind === "file" ? restart({ destination: v }) : setDestination(v) }) }) }) : null,
4586
+ organizations.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Select, { value: destination, options: destinationOptions, "aria-label": "Save to", onValueChange: (v) => draft.kind === "file" ? restart({ destination: v }) : setDestination(v) }) }) }) : null,
4602
4587
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4603
- Section,
4588
+ VaultSection,
4604
4589
  {
4605
4590
  title: draft.kind === "env" ? plural(envKeys.length, "value") : summary(counts, lines.length),
4606
4591
  actions: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
@@ -4628,11 +4613,11 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4628
4613
  )
4629
4614
  }
4630
4615
  ),
4631
- draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Visible details", hint: "Approve saving websites and public keys in the clear", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: approvedVisible, disabled: busy, onCheckedChange: setApprovedVisible, "aria-label": "Approve visible details" }) }) }) : null,
4616
+ draft.kind === "file" && draft.parsed.kind === "structured" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Visible details", hint: "Approve saving websites and public keys in the clear", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: approvedVisible, disabled: busy, onCheckedChange: setApprovedVisible, "aria-label": "Approve visible details" }) }) }) : null,
4632
4617
  draft.kind === "file" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Notices, { draft }) : null,
4633
- draft.kind === "file" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(More, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Section, { children: [
4634
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Browser fill", hint: "Needs username, password and an https address", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: browserFill, disabled: busy, onCheckedChange: (on) => restart({ browserFill: on }), "aria-label": "Browser fill" }) }),
4635
- draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: header || `Column ${index + 1}`, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4618
+ draft.kind === "file" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(More, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { children: [
4619
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Browser fill", hint: "Needs username, password and an https address", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Switch, { checked: browserFill, disabled: busy, onCheckedChange: (on) => restart({ browserFill: on }), "aria-label": "Browser fill" }) }),
4620
+ draft.parsed.kind === "csv" ? draft.parsed.preview.headers.map((header, index) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: header || `Column ${index + 1}`, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4636
4621
  import_controls15.Select,
4637
4622
  {
4638
4623
  value: draft.mapping[index] ?? "keep",
@@ -4644,16 +4629,16 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4644
4629
  ] }) }) : null,
4645
4630
  ambiguous ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorLine, { message: "Each of name, username, password, notes and one-time password can be used by one column." }) : null
4646
4631
  ] }) : null,
4647
- stage === "done" && done ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(Section, { title: "Result", children: [
4648
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Created", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.created.length }) }),
4649
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Skipped", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.skipped }) }),
4650
- /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Failed", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
4651
- done.untried.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Not tried", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.untried.length }) }) : null,
4652
- done.withOtp > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: "Codes", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-muted-foreground", children: [
4632
+ stage === "done" && done ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { title: "Result", children: [
4633
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Created", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.created.length }) }),
4634
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Skipped", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.skipped }) }),
4635
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Failed", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: done.failed.length > 0 ? "text-destructive" : "text-foreground", children: done.failed.length }) }),
4636
+ done.untried.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Not tried", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.untried.length }) }) : null,
4637
+ done.withOtp > 0 ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Codes", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)("span", { className: "text-muted-foreground", children: [
4653
4638
  plural(done.withOtp, "login"),
4654
4639
  " still need the one-time password added."
4655
4640
  ] }) }) : null,
4656
- done.failed.map((f) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(Row, { label: f.title, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "block truncate text-destructive", title: f.reason, children: f.reason }) }, f.key))
4641
+ done.failed.map((f) => /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: f.title, children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "block truncate text-destructive", title: f.reason, children: f.reason }) }, f.key))
4657
4642
  ] }) : null,
4658
4643
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorLine, { message: error })
4659
4644
  ] });
@@ -4713,11 +4698,13 @@ var import_controls21 = require("@ai-matrx/design-system/controls");
4713
4698
  var import_confirm_opener9 = require("@ai-matrx/kit/confirm-opener");
4714
4699
 
4715
4700
  // src/activity/FilesSection.tsx
4701
+ var import_format7 = require("@ai-matrx/kit/format");
4716
4702
  var import_react21 = require("react");
4717
4703
  var import_controls16 = require("@ai-matrx/design-system/controls");
4718
4704
  var import_design_system13 = require("@ai-matrx/design-system");
4719
4705
  var import_confirm_opener6 = require("@ai-matrx/kit/confirm-opener");
4720
4706
  var import_download3 = require("@ai-matrx/kit/download");
4707
+ var import_icons8 = require("@ai-matrx/design-system/icons");
4721
4708
  var import_jsx_runtime20 = require("react/jsx-runtime");
4722
4709
  var messageOf2 = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
4723
4710
  var TOO_BIG = "Files over 25 MB can't be stored.";
@@ -4776,7 +4763,7 @@ function FilesSection({ item, port, editing, onChanged }) {
4776
4763
  onDragLeave: canEdit ? () => setDragging(false) : void 0,
4777
4764
  onDrop: canEdit ? drop : void 0,
4778
4765
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4779
- Section,
4766
+ VaultSection,
4780
4767
  {
4781
4768
  title: "Files",
4782
4769
  actions: canEdit ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
@@ -4787,11 +4774,11 @@ function FilesSection({ item, port, editing, onChanged }) {
4787
4774
  } }) : null,
4788
4775
  item.attachments.map(
4789
4776
  (a) => canEdit ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(EditableFile, { port, item, file: a, busy, run, onDownload: () => void download(a), onTooBig: () => setError(TOO_BIG) }, a.id) : /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4790
- Row,
4777
+ VaultRow,
4791
4778
  {
4792
4779
  label: a.label,
4793
4780
  hint: a.description || void 0,
4794
- actions: a.handling === "sealed" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DownloadGlyph, {}), "aria-label": `Download ${a.fileName}`, disabled: busy !== null, onClick: () => void download(a) }) : null,
4781
+ actions: a.handling === "sealed" ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(LockGlyph, {}), children: "Sealed" }) : canDownload(item, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons8.DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: busy !== null, onClick: () => void download(a) }) : null,
4795
4782
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FileName, { file: a })
4796
4783
  },
4797
4784
  a.id
@@ -4817,12 +4804,12 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4817
4804
  }
4818
4805
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4819
4806
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4820
- Row,
4807
+ VaultRow,
4821
4808
  {
4822
4809
  label: a.label,
4823
4810
  hint: a.description || void 0,
4824
4811
  actions: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4825
- canDownload(it, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(DownloadGlyph, {}), "aria-label": `Download ${a.fileName}`, disabled: b !== null, onClick: onDownload }) : null,
4812
+ canDownload(it, a) ? /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_icons8.DownloadIcon, {}), "aria-label": `Download ${a.fileName}`, disabled: b !== null, onClick: onDownload }) : null,
4826
4813
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(PencilGlyph, {}), "aria-label": `Edit ${a.label}`, pressed: open, disabled: b !== null, onClick: () => setOpen((o) => !o) }),
4827
4814
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(UploadGlyph, {}), "aria-label": `Replace ${a.fileName}`, disabled: b !== null, onClick: () => replacer.current?.click() }),
4828
4815
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(TrashGlyph, {}), "aria-label": `Delete ${a.label}`, disabled: b !== null, onClick: () => void remove() }),
@@ -4853,7 +4840,7 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4853
4840
  function FileName({ file }) {
4854
4841
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "flex min-w-0 items-center gap-2", children: [
4855
4842
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate", children: file.fileName }),
4856
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatBytes(file.sizeBytes) })
4843
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: (0, import_format7.formatFileSize)(file.sizeBytes) })
4857
4844
  ] });
4858
4845
  }
4859
4846
  function Protection({ value, locked, onChange }) {
@@ -4876,13 +4863,13 @@ function NewFile({ file, busy, onAdd, onCancel }) {
4876
4863
  await onAdd({ label: label.trim(), description: description.trim() || null, handling });
4877
4864
  }
4878
4865
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4879
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "New file", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "flex min-w-0 items-center gap-2", children: [
4866
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "New file", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "flex min-w-0 items-center gap-2", children: [
4880
4867
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "truncate", children: file.name }),
4881
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatBytes(file.size) })
4868
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: (0, import_format7.formatFileSize)(file.size) })
4882
4869
  ] }) }),
4883
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4884
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "Purpose", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4885
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "Protection", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Protection, { value: handling, locked: false, onChange: setHandling }) }),
4870
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4871
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Purpose", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4872
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Protection", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Protection, { value: handling, locked: false, onChange: setHandling }) }),
4886
4873
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4887
4874
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4888
4875
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "primary", disabled: busy || !label.trim(), onClick: () => void add(), children: busy ? "Adding\u2026" : "Add file" })
@@ -4900,10 +4887,10 @@ function FileDetailsRows({ file, busy, onSave, onCancel }) {
4900
4887
  await onSave({ label: label.trim(), description: description.trim() || null, fileName: fileName.trim(), handling });
4901
4888
  }
4902
4889
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4903
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4904
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "Purpose", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4905
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "File name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
4906
- /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Row, { label: "Protection", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Protection, { value: handling, locked: file.handling === "sealed", onChange: setHandling }) }),
4890
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Name", value: label, onChange: (e) => setLabel(e.target.value) }) }),
4891
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Purpose", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "Purpose", placeholder: "What it is for", value: description, onChange: (e) => setDescription(e.target.value) }) }),
4892
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "File name", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Field, { "aria-label": "File name", value: fileName, onChange: (e) => setFileName(e.target.value) }) }),
4893
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Protection", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Protection, { value: handling, locked: file.handling === "sealed", onChange: setHandling }) }),
4907
4894
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4908
4895
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4909
4896
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "primary", disabled: busy || !changed || !label.trim() || !fileName.trim(), onClick: () => void save(), children: busy ? "Saving\u2026" : "Save" })
@@ -4922,6 +4909,7 @@ function confirmSeal(label) {
4922
4909
  // src/fields/RecoveryCodesRow.tsx
4923
4910
  var import_react22 = require("react");
4924
4911
  var import_controls17 = require("@ai-matrx/design-system/controls");
4912
+ var import_icons9 = require("@ai-matrx/design-system/icons");
4925
4913
  var import_jsx_runtime21 = require("react/jsx-runtime");
4926
4914
  var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
4927
4915
  var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
@@ -4962,7 +4950,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4962
4950
  };
4963
4951
  if (draft !== null) {
4964
4952
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4965
- Row,
4953
+ VaultRow,
4966
4954
  {
4967
4955
  label: "Recovery codes",
4968
4956
  top: true,
@@ -4982,7 +4970,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4982
4970
  }
4983
4971
  if (!field) {
4984
4972
  if (!canEdit) return null;
4985
- return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(Row, { label: "Recovery codes", actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PlusGlyph, {}), "aria-label": "Add recovery codes", onClick: () => setDraft("") }), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "None" }) });
4973
+ return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(VaultRow, { label: "Recovery codes", actions: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(PlusGlyph, {}), "aria-label": "Add recovery codes", onClick: () => setDraft("") }), children: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("span", { className: "text-muted-foreground", children: "None" }) });
4986
4974
  }
4987
4975
  const sealed = field.handling === "sealed";
4988
4976
  const canSee = !sealed && item.capabilities.canReveal;
@@ -5004,7 +4992,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
5004
4992
  });
5005
4993
  };
5006
4994
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5007
- Row,
4995
+ VaultRow,
5008
4996
  {
5009
4997
  label: "Recovery codes",
5010
4998
  top: codes !== null,
@@ -5015,7 +5003,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
5015
5003
  children: sealed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LockGlyph, {}), children: "Sealed" }) : codes ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("ul", { className: "flex flex-col gap-0.5", "aria-label": "Recovery codes", children: [
5016
5004
  codes.map((code, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "flex min-h-7 items-center gap-1", children: [
5017
5005
  /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("code", { className: "min-w-0 flex-1 break-all font-mono text-sm text-foreground", children: code }),
5018
- /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopyGlyph, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
5006
+ /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_icons9.CopyIcon, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
5019
5007
  canEdit ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CheckGlyph, {}), disabled: busy, onClick: () => void markUsed(i), children: "Mark used" }) : null
5020
5008
  ] }, `${i}-${code}`)),
5021
5009
  error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
@@ -5024,33 +5012,17 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
5024
5012
  );
5025
5013
  }
5026
5014
 
5015
+ // src/ItemPane.tsx
5016
+ var import_icons11 = require("@ai-matrx/design-system/icons");
5017
+ var import_drafts = require("@ai-matrx/kit/drafts");
5018
+
5027
5019
  // src/draft-keep.ts
5028
5020
  var PREFIX = "matrx.vault.draft:";
5029
5021
  function draftKey(itemId, definitionKey) {
5030
5022
  return `${PREFIX}${itemId ?? `new:${definitionKey ?? "custom"}`}`;
5031
5023
  }
5032
- function keepDraft(key, basedOn, d) {
5033
- const kept = { basedOn, draft: { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom } };
5034
- try {
5035
- globalThis.sessionStorage?.setItem(key, JSON.stringify(kept));
5036
- } catch {
5037
- }
5038
- }
5039
- function readKeptDraft(key, basedOn) {
5040
- try {
5041
- const raw = globalThis.sessionStorage?.getItem(key);
5042
- if (!raw) return null;
5043
- const kept = JSON.parse(raw);
5044
- return kept.basedOn === basedOn ? kept.draft : null;
5045
- } catch {
5046
- return null;
5047
- }
5048
- }
5049
- function dropKeptDraft(key) {
5050
- try {
5051
- globalThis.sessionStorage?.removeItem(key);
5052
- } catch {
5053
- }
5024
+ function keptFieldsOf(d) {
5025
+ return { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom };
5054
5026
  }
5055
5027
 
5056
5028
  // src/extension/page-logic.ts
@@ -5197,6 +5169,7 @@ var import_react26 = require("react");
5197
5169
  var import_confirm_opener8 = require("@ai-matrx/kit/confirm-opener");
5198
5170
  var import_controls20 = require("@ai-matrx/design-system/controls");
5199
5171
  var import_design_system15 = require("@ai-matrx/design-system");
5172
+ var import_icons10 = require("@ai-matrx/design-system/icons");
5200
5173
 
5201
5174
  // src/sharing/logic.ts
5202
5175
  var LEVEL_OPTIONS = [
@@ -5228,7 +5201,7 @@ function copyRefusal(message2) {
5228
5201
  return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
5229
5202
  }
5230
5203
  var isPasskey = (item) => item.definitionKey === "native_passkey" || item.definitionKey === "passkey_private";
5231
- function moveConsequence(item, to) {
5204
+ function itemMoveConsequence(item, to) {
5232
5205
  if (item.authenticator) return "One-time password stays behind; set it up again";
5233
5206
  return to ? "Its members get access; people you shared with lose it" : "Only you; organization members lose access";
5234
5207
  }
@@ -5318,7 +5291,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5318
5291
  const to = destinationOf(moveChoice.value);
5319
5292
  const ok = await (0, import_confirm_opener7.confirm)({
5320
5293
  title: `Move to ${moveChoice.label}?`,
5321
- description: `"${item.name}" stays the same item, so everything using it keeps working. ${moveConsequence(item, to)}.`,
5294
+ description: `"${item.name}" stays the same item, so everything using it keeps working. ${itemMoveConsequence(item, to)}.`,
5322
5295
  confirmLabel: "Move"
5323
5296
  });
5324
5297
  if (!ok) return;
@@ -5354,17 +5327,17 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5354
5327
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusLine, { error, notice }),
5355
5328
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", className: "ml-auto", onClick: onClose, children: "Close" })
5356
5329
  ] }),
5357
- children: nothing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(Section, { children: [
5330
+ children: nothing ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ (0, import_jsx_runtime24.jsxs)(VaultSection, { children: [
5358
5331
  canMove && moves.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5359
- Row,
5332
+ VaultRow,
5360
5333
  {
5361
5334
  label: "Move to",
5362
- hint: moveChoice ? moveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5335
+ hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5363
5336
  actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
5364
5337
  children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Select, { className: "w-full", "aria-label": "Move to", value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
5365
5338
  }
5366
5339
  ) : null,
5367
- canGive ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Row, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5340
+ canGive ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(VaultRow, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5368
5341
  import_controls19.Field,
5369
5342
  {
5370
5343
  className: "w-full",
@@ -5378,7 +5351,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5378
5351
  onChange: (e) => setEmail(e.target.value)
5379
5352
  }
5380
5353
  ) }) : null,
5381
- canCopy && copies.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(Row, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Select, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
5354
+ canCopy && copies.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Select, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
5382
5355
  ] })
5383
5356
  }
5384
5357
  );
@@ -5460,7 +5433,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5460
5433
  }
5461
5434
  };
5462
5435
  if (!item.capabilities.canManage) {
5463
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Empty, { children: "Only the owner can change who has access." }) }) });
5436
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Button, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Empty, { children: "Only the owner can change who has access." }) }) });
5464
5437
  }
5465
5438
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5466
5439
  Panel,
@@ -5473,9 +5446,9 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5473
5446
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Button, { variant: "primary", className: "ml-auto", onClick: onClose, children: "Done" })
5474
5447
  ] }),
5475
5448
  children: [
5476
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Section, { title: "Who has access", children: [
5449
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(VaultSection, { title: "Who has access", children: [
5477
5450
  isOrg ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: BuildingGlyph, who: `${orgName} admins`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: PersonGlyph, who: "You", meta: "Owner", children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }),
5478
- isOrg ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: UsersGlyph, who: `${orgName} members`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5451
+ isOrg ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: import_icons10.UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5479
5452
  import_controls20.Select,
5480
5453
  {
5481
5454
  variant: "inline",
@@ -5536,7 +5509,7 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
5536
5509
  const [level, setLevel] = (0, import_react26.useState)("use");
5537
5510
  const chosen = open.find((o) => o.id === target);
5538
5511
  if (item.owner.kind !== "me") return null;
5539
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Section, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5512
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
5540
5513
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5541
5514
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5542
5515
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Select, { 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 }))] }),
@@ -5586,7 +5559,7 @@ function MemberAccess({ port, organizationId, organizationName }) {
5586
5559
  const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
5587
5560
  if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
5588
5561
  };
5589
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Section, { title: `${organizationName} vault access`, children: [
5562
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(VaultSection, { title: `${organizationName} vault access`, children: [
5590
5563
  loadError ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Empty, { children: loadError }) : list === null ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.RegionSkeleton, { shape: "rows", count: 3, "aria-label": "Loading member access", className: "px-3 sm:px-4" }) : list.members.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Empty, { children: "No members yet." }) : list.members.map((m) => /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: PersonGlyph, who: m.email || m.userId, meta: m.role, children: m.effective === "admin" ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)("span", { className: "px-2 text-sm text-muted-foreground", children: MEMBER_ACCESS_LABEL.admin }) : /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5591
5564
  import_controls20.Select,
5592
5565
  {
@@ -5621,7 +5594,7 @@ function SharingSummary({ item, port, className }) {
5621
5594
  }
5622
5595
 
5623
5596
  // src/ItemPane.tsx
5624
- var import_format4 = require("@ai-matrx/kit/format");
5597
+ var import_format8 = require("@ai-matrx/kit/format");
5625
5598
  var import_jsx_runtime26 = require("react/jsx-runtime");
5626
5599
  var USERNAME_KEYS = /^(username|user_name|email|login|username_or_email|account_email)$/;
5627
5600
  function ItemPane(props) {
@@ -5662,7 +5635,7 @@ function ItemPane(props) {
5662
5635
  if (was && was.id === id && was.mode === mode && editing) {
5663
5636
  setDraft((d) => rebaseDraft(was.base, base, d));
5664
5637
  } else {
5665
- const kept = editing ? readKeptDraft(keepKey, item?.updatedAt ?? "new") : null;
5638
+ const kept = editing ? (0, import_drafts.readKeptDraft)(keepKey, { basedOn: item?.updatedAt ?? "new" })?.value ?? null : null;
5666
5639
  setDraft(kept ? { ...base, ...kept } : base);
5667
5640
  setTagsText((kept ?? base).tags.join(", "));
5668
5641
  setError(null);
@@ -5677,8 +5650,8 @@ function ItemPane(props) {
5677
5650
  (0, import_react27.useEffect)(() => onDirty(dirty), [dirty, onDirty]);
5678
5651
  const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
5679
5652
  (0, import_react27.useEffect)(() => {
5680
- if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new", draft);
5681
- else if (!editing) dropKeptDraft(keepKey);
5653
+ if (editing && dirty) (0, import_drafts.keepDraft)(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
5654
+ else if (!editing) (0, import_drafts.dropKeptDraft)(keepKey);
5682
5655
  }, [editing, dirty, draft, keepKey, item?.updatedAt]);
5683
5656
  (0, import_react27.useEffect)(() => {
5684
5657
  if (!editing || !item) return;
@@ -5715,7 +5688,7 @@ function ItemPane(props) {
5715
5688
  if (item) {
5716
5689
  const r = await port.save(item, definition, out);
5717
5690
  const [next, n] = await withOtp(r.item, r.notice);
5718
- dropKeptDraft(keepKey);
5691
+ (0, import_drafts.dropKeptDraft)(keepKey);
5719
5692
  onSaved(next, false, n);
5720
5693
  } else if (definition && owner === "person") {
5721
5694
  const secretKey = declared.find((f) => f.storage === "encrypted" && f.kind === "secret")?.key ?? null;
@@ -5725,7 +5698,7 @@ function ItemPane(props) {
5725
5698
  } else if (definition) {
5726
5699
  const r = await port.create(definition, owner === "me" ? null : owner, out);
5727
5700
  const [next, n] = await withOtp(r.item, r.notice);
5728
- dropKeptDraft(keepKey);
5701
+ (0, import_drafts.dropKeptDraft)(keepKey);
5729
5702
  onSaved(next, true, n);
5730
5703
  }
5731
5704
  } catch (e) {
@@ -5764,7 +5737,7 @@ function ItemPane(props) {
5764
5737
  const viewCustom = (item?.custom ?? []).filter((c) => !declaredKeys.has(c.key) && c.key !== MFA_METHOD_KEY && !isAuthenticatorStorage(c.key));
5765
5738
  const isLogin = (item?.definitionKey ?? definition?.key) === "website_login" || (item?.definitionKey ?? definition?.key) === "username_password";
5766
5739
  const typeLabel = definition?.label ?? item?.definitionLabel ?? "";
5767
- const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(UsersGlyph, {}) } : null;
5740
+ const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(BuildingGlyph, {}) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.UsersIcon, {}) } : null;
5768
5741
  const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
5769
5742
  const descriptionVisible = showDescription || draft.description !== "";
5770
5743
  const header = /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("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: [
@@ -5821,7 +5794,7 @@ function ItemPane(props) {
5821
5794
  "Send securely"
5822
5795
  ] }) : null,
5823
5796
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenuItem, { onSelect: () => onPanel("history"), children: [
5824
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(HistoryGlyph, { className: "size-4" }),
5797
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.HistoryIcon, { className: "size-4" }),
5825
5798
  "Password history"
5826
5799
  ] }),
5827
5800
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenuItem, { onSelect: () => onPanel("activity"), children: [
@@ -5829,7 +5802,7 @@ function ItemPane(props) {
5829
5802
  "Activity"
5830
5803
  ] }),
5831
5804
  canEdit ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenuItem, { onSelect: () => onPanel("settings"), children: [
5832
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SettingsGlyph, { className: "size-4" }),
5805
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.SettingsIcon, { className: "size-4" }),
5833
5806
  "Settings"
5834
5807
  ] }) : null,
5835
5808
  canManage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
@@ -5849,8 +5822,8 @@ function ItemPane(props) {
5849
5822
  error ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { role: "alert", className: "border-b border-border bg-muted px-5 py-2 text-sm text-destructive", children: error }) : null,
5850
5823
  notice && !editing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { role: "status", className: "border-b border-border bg-muted px-5 py-2 text-sm text-warning", children: notice }) : null,
5851
5824
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("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__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5852
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Section, { children: [
5853
- mode === "new" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Row, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5825
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { children: [
5826
+ mode === "new" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultRow, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5854
5827
  import_controls21.OptionCombobox,
5855
5828
  {
5856
5829
  value: owner,
@@ -5871,7 +5844,7 @@ function ItemPane(props) {
5871
5844
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
5872
5845
  mode === "new" && owner === "person" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5873
5846
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
5874
- declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Row, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Switch, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
5847
+ declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultRow, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Switch, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
5875
5848
  ] }) : null,
5876
5849
  declared.map((f) => {
5877
5850
  const existing = item?.fields.find((x) => x.key === f.key);
@@ -5891,7 +5864,7 @@ function ItemPane(props) {
5891
5864
  actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5892
5865
  hidden && existing?.handling === "revealable" && item?.capabilities.canReveal ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
5893
5866
  secretKind ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
5894
- existing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SettingsGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
5867
+ existing ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
5895
5868
  ] })
5896
5869
  },
5897
5870
  f.key
@@ -5909,7 +5882,7 @@ function ItemPane(props) {
5909
5882
  removeLabel: `Delete ${f.label}`,
5910
5883
  actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5911
5884
  f.handling === "revealable" && !(f.key in loaded) && item?.capabilities.canReveal ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
5912
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(SettingsGlyph, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
5885
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_controls21.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
5913
5886
  ] })
5914
5887
  },
5915
5888
  f.id
@@ -5942,9 +5915,9 @@ function ItemPane(props) {
5942
5915
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator), item, port, onEnrolled: onChanged }),
5943
5916
  item && isLogin && !item.authenticator ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TwoFactorMethodRow, { port, item, onChanged }) : null
5944
5917
  ] }),
5945
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
5918
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
5946
5919
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5947
- Section,
5920
+ VaultSection,
5948
5921
  {
5949
5922
  title: "More",
5950
5923
  actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenu, { children: [
@@ -5978,7 +5951,7 @@ function ItemPane(props) {
5978
5951
  ),
5979
5952
  filesProps ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FilesSection, { ...filesProps, editing: true }) : null
5980
5953
  ] }) : item ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5981
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Section, { children: [
5954
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { children: [
5982
5955
  declared.map((f) => {
5983
5956
  if (f.storage === "metadata") {
5984
5957
  const v = metaValue(f.key);
@@ -5993,18 +5966,18 @@ function ItemPane(props) {
5993
5966
  item.authenticator ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TotpRow, { port, item, onChanged }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AddRow, { label: "One-time password", onAdd: canEdit ? () => onMode("edit") : null, children: "Set up" }),
5994
5967
  !item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TwoFactorMethodRow, { port, item, onChanged }) : null
5995
5968
  ] }),
5996
- /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Section, { children: item.notes ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
5997
- item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Section, { title: "More", children: [
5969
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultSection, { children: item.notes ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
5970
+ item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { title: "More", children: [
5998
5971
  item.description ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: "Description", value: item.description }) : null,
5999
- item.tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(Row, { label: "Tags", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
5972
+ item.tags.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultRow, { label: "Tags", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
6000
5973
  viewCustom.map((c) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
6001
5974
  ] }) : null,
6002
5975
  filesProps ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FilesSection, { ...filesProps, editing: false }) : null,
6003
5976
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: (0, import_design_system17.cn)("px-1 text-xs text-muted-foreground"), children: [
6004
5977
  "Modified ",
6005
- (0, import_format4.formatAbsoluteDate)(item.updatedAt, DAY_FORMAT, ""),
5978
+ (0, import_format8.formatAbsoluteDate)(item.updatedAt, DAY_FORMAT, ""),
6006
5979
  " \xB7 Created ",
6007
- (0, import_format4.formatAbsoluteDate)(item.createdAt, DAY_FORMAT, "")
5980
+ (0, import_format8.formatAbsoluteDate)(item.createdAt, DAY_FORMAT, "")
6008
5981
  ] })
6009
5982
  ] }) : null }) })
6010
5983
  ] }) });
@@ -6120,7 +6093,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
6120
6093
  // src/lists/TrashView.tsx
6121
6094
  var import_react30 = require("react");
6122
6095
  var import_controls24 = require("@ai-matrx/design-system/controls");
6123
- var import_format5 = require("@ai-matrx/kit/format");
6096
+ var import_format9 = require("@ai-matrx/kit/format");
6124
6097
 
6125
6098
  // src/lists/logic.ts
6126
6099
  var ENTITY_TYPE = "credential_item";
@@ -6244,13 +6217,13 @@ function RestorePanel({ lists, item, restore, onClose }) {
6244
6217
  refused ? null : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(import_controls23.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(RestoreGlyph, {}), disabled: busy || loading || lists.preview !== void 0 && preview === null, onClick: () => void run(), children: busy ? "Restoring\u2026" : "Restore" })
6245
6218
  ] }),
6246
6219
  children: [
6247
- loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(Section, { title: "Comes back", children: [
6248
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Row, { label: "Fields", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
6249
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Row, { label: "Files", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
6250
- preview.passkeys === 1 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Row, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
6251
- /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Row, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
6252
- preview.priorWasDisabled ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Row, { label: "Before", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
6253
- ] }) : preview ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
6220
+ loading ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ (0, import_jsx_runtime28.jsxs)(VaultSection, { title: "Comes back", children: [
6221
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Fields", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
6222
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Files", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
6223
+ preview.passkeys === 1 ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
6224
+ /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
6225
+ preview.priorWasDisabled ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultRow, { label: "Before", children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
6226
+ ] }) : preview ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime28.jsx)(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
6254
6227
  error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
6255
6228
  ]
6256
6229
  }
@@ -6282,13 +6255,13 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6282
6255
  };
6283
6256
  return /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
6284
6257
  header,
6285
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Section, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
6258
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(VaultSection, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
6286
6259
  // A list row, not a field row: the name gets the whole width (on a phone a label column
6287
6260
  // left "Vau…" for every row), the deletion date sits under it.
6288
6261
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
6289
6262
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6290
6263
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-sm text-foreground", children: item.name }),
6291
- /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${(0, import_format5.formatAbsoluteDate)(item.deletion.deletedAt, DAY_FORMAT, "")}` : null, item.owner.kind !== "me" ? item.owner.label : null].filter(Boolean).join(" \xB7 ") })
6264
+ /* @__PURE__ */ (0, import_jsx_runtime29.jsx)("span", { className: "truncate text-xs text-muted-foreground", children: [item.deletion?.deletedAt ? `Deleted ${(0, import_format9.formatAbsoluteDate)(item.deletion.deletedAt, DAY_FORMAT, "")}` : null, item.owner.kind !== "me" ? item.owner.label : null].filter(Boolean).join(" \xB7 ") })
6292
6265
  ] }),
6293
6266
  /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(import_controls24.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime29.jsx)(RestoreGlyph, {}), disabled: busyId !== null || !item.deletion, onClick: () => setRestoring(item), children: "Restore" })
6294
6267
  ] }, item.id)
@@ -6302,6 +6275,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6302
6275
  var import_react31 = require("react");
6303
6276
  var import_design_system20 = require("@ai-matrx/design-system");
6304
6277
  var import_controls25 = require("@ai-matrx/design-system/controls");
6278
+ var import_icons12 = require("@ai-matrx/design-system/icons");
6305
6279
  var import_jsx_runtime30 = require("react/jsx-runtime");
6306
6280
  function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6307
6281
  const [search, setSearch] = (0, import_react31.useState)("");
@@ -6336,7 +6310,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6336
6310
  "aria-label": "Website address",
6337
6311
  inputMode: "url",
6338
6312
  autoFocus: true,
6339
- icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(GlobeGlyph, {})
6313
+ icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_icons12.GlobeIcon, {})
6340
6314
  }
6341
6315
  ),
6342
6316
  guess && login ? /* @__PURE__ */ (0, import_jsx_runtime30.jsxs)("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
@@ -6375,10 +6349,10 @@ var import_react32 = require("react");
6375
6349
  var import_confirm_opener10 = require("@ai-matrx/kit/confirm-opener");
6376
6350
  var import_design_system21 = require("@ai-matrx/design-system");
6377
6351
  var import_controls26 = require("@ai-matrx/design-system/controls");
6378
- var import_format7 = require("@ai-matrx/kit/format");
6352
+ var import_format11 = require("@ai-matrx/kit/format");
6379
6353
 
6380
6354
  // src/sharing/secure-link-logic.ts
6381
- var import_format6 = require("@ai-matrx/kit/format");
6355
+ var import_format10 = require("@ai-matrx/kit/format");
6382
6356
  var SECURE_RESOURCE_TYPE = "credential_item";
6383
6357
  var NOTE_MAX = 1e3;
6384
6358
  var CHANNEL_WORD = { email: "email", sms: "text" };
@@ -6416,7 +6390,7 @@ function carriedWords(keys, fields) {
6416
6390
  const known = new Map(fields.map((f) => [f.key, f.label]));
6417
6391
  return keys.map((k) => known.get(k) ?? fieldNames([k])).join(", ");
6418
6392
  }
6419
- var lifetimeWords = (minutes) => (0, import_format6.formatDurationMinutes)(minutes, { style: "long" });
6393
+ var lifetimeWords = (minutes) => (0, import_format10.formatDurationMinutes)(minutes, { style: "long" });
6420
6394
  function remedyOf(e) {
6421
6395
  const body = e?.serverDetail;
6422
6396
  if (!body || typeof body !== "object") return null;
@@ -6586,9 +6560,9 @@ function SecureLinkPanel({ item, port, onClose }) {
6586
6560
  ] }),
6587
6561
  children: [
6588
6562
  remedy ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
6589
- /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(Section, { title: "Recipient", children: [
6590
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Email", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Field, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
6591
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6563
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(VaultSection, { title: "Recipient", children: [
6564
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Email", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Field, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
6565
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6592
6566
  import_controls26.Field,
6593
6567
  {
6594
6568
  type: "tel",
@@ -6604,8 +6578,8 @@ function SecureLinkPanel({ item, port, onClose }) {
6604
6578
  className: "w-full"
6605
6579
  }
6606
6580
  ) }),
6607
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Name", hint: "Optional", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Field, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
6608
- plan && !plan.same ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Link by", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6581
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Name", hint: "Optional", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Field, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
6582
+ plan && !plan.same ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Link by", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6609
6583
  import_controls26.SegmentedControl,
6610
6584
  {
6611
6585
  "aria-label": "Send the link by",
@@ -6617,26 +6591,26 @@ function SecureLinkPanel({ item, port, onClose }) {
6617
6591
  ]
6618
6592
  }
6619
6593
  ) }) : null,
6620
- email.trim() ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Delivery", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
6594
+ email.trim() ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Delivery", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
6621
6595
  ] }),
6622
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Section, { title: "Include", children: optionsError ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
6596
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultSection, { title: "Include", children: optionsError ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
6623
6597
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_design_system21.Checkbox, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
6624
6598
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
6625
6599
  !f.available && f.reason ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "min-w-0 max-w-[55%] truncate text-xs text-muted-foreground", title: f.reason, children: f.reason }) : null
6626
6600
  ] }, f.key)) }),
6627
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Section, { title: "Message", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Textarea, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
6628
- options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(Section, { title: "Link", children: [
6629
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Opens", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-foreground", children: "Once" }) }),
6630
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Link expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
6601
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultSection, { title: "Message", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Textarea, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
6602
+ options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(VaultSection, { title: "Link", children: [
6603
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Opens", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-foreground", children: "Once" }) }),
6604
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Link expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
6631
6605
  "After ",
6632
6606
  lifetimeWords(options.linkMinutes)
6633
6607
  ] }) }),
6634
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Code expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
6608
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Code expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
6635
6609
  "After ",
6636
6610
  lifetimeWords(options.codeMinutes)
6637
6611
  ] }) })
6638
6612
  ] }) : null,
6639
- sharing.sentSecureLinks ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Section, { title: "Sent links", children: sentError ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
6613
+ sharing.sentSecureLinks ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultSection, { title: "Sent links", children: sentError ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
6640
6614
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Badge, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
6641
6615
  row.status === "pending" ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Button, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
6642
6616
  ] }, row.id)) }) : null
@@ -6645,7 +6619,7 @@ function SecureLinkPanel({ item, port, onClose }) {
6645
6619
  );
6646
6620
  }
6647
6621
  function sentMeta(row, options) {
6648
- const when = row.status === "pending" ? `Until ${(0, import_format7.formatAbsoluteDate)(row.expiresAt, void 0, "")}` : row.status === "viewed" && row.viewedAt ? (0, import_format7.formatAbsoluteDate)(row.viewedAt, void 0, "") : (0, import_format7.formatAbsoluteDate)(row.createdAt, DAY_FORMAT, "");
6622
+ const when = row.status === "pending" ? `Until ${(0, import_format11.formatAbsoluteDate)(row.expiresAt, void 0, "")}` : row.status === "viewed" && row.viewedAt ? (0, import_format11.formatAbsoluteDate)(row.viewedAt, void 0, "") : (0, import_format11.formatAbsoluteDate)(row.createdAt, DAY_FORMAT, "");
6649
6623
  const carried = row.fieldKeys.length ? carriedWords(row.fieldKeys, options?.fields ?? []) : "";
6650
6624
  return [when, carried].filter(Boolean).join(" \xB7 ");
6651
6625
  }
@@ -6654,7 +6628,7 @@ function sentMeta(row, options) {
6654
6628
  var import_react33 = require("react");
6655
6629
  var import_confirm_opener11 = require("@ai-matrx/kit/confirm-opener");
6656
6630
  var import_controls27 = require("@ai-matrx/design-system/controls");
6657
- var import_format8 = require("@ai-matrx/kit/format");
6631
+ var import_format12 = require("@ai-matrx/kit/format");
6658
6632
 
6659
6633
  // src/devices/logic.ts
6660
6634
  var PASSKEY_RP_ID = "aimatrx.com";
@@ -6778,19 +6752,19 @@ function DevicesPanel({ port, onClose }) {
6778
6752
  };
6779
6753
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
6780
6754
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ErrorLine2, { text: error }),
6781
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Section, { children: devices === null ? error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
6755
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultSection, { children: devices === null ? error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
6782
6756
  const off = isRevoked(device);
6783
6757
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6784
- Row,
6758
+ VaultRow,
6785
6759
  {
6786
6760
  label: off ? "Turned off" : "Can fill",
6787
- hint: off ? (0, import_format8.formatAbsoluteDate)(device.revokedAt, DAY_FORMAT, "") : void 0,
6761
+ hint: off ? (0, import_format12.formatAbsoluteDate)(device.revokedAt, DAY_FORMAT, "") : void 0,
6788
6762
  actions: off ? null : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(PowerGlyph, {}), disabled: busyId !== null, onClick: () => void revoke(device), children: "Revoke" }),
6789
6763
  children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
6790
6764
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: off ? "truncate text-muted-foreground" : "truncate text-foreground", children: device.label }),
6791
6765
  /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "truncate text-xs text-muted-foreground", children: [
6792
- device.lastUsedAt ? `Last used ${(0, import_format8.formatAbsoluteDate)(device.lastUsedAt, void 0, "")}` : "Never used",
6793
- device.addedAt ? ` \xB7 added ${(0, import_format8.formatAbsoluteDate)(device.addedAt, DAY_FORMAT, "")}` : ""
6766
+ device.lastUsedAt ? `Last used ${(0, import_format12.formatAbsoluteDate)(device.lastUsedAt, void 0, "")}` : "Never used",
6767
+ device.addedAt ? ` \xB7 added ${(0, import_format12.formatAbsoluteDate)(device.addedAt, DAY_FORMAT, "")}` : ""
6794
6768
  ] })
6795
6769
  ] })
6796
6770
  },
@@ -6869,29 +6843,29 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6869
6843
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
6870
6844
  canApprove ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void approve(), children: busy === "approve" ? "Approving\u2026" : "Approve with passkey" }) : null
6871
6845
  ] });
6872
- return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Empty, { children: [
6846
+ return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Empty, { children: [
6873
6847
  "This link names no key. Start again from ",
6874
6848
  where,
6875
6849
  "."
6876
6850
  ] }) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(import_jsx_runtime32.Fragment, { children: [
6877
- /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Section, { title: "What is asking", children: [
6878
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Row, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
6879
- name ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Row, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "block truncate", children: name }) }) : null,
6880
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Row, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
6851
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(VaultSection, { title: "What is asking", children: [
6852
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
6853
+ name ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "block truncate", children: name }) }) : null,
6854
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
6881
6855
  ] }),
6882
6856
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(ErrorLine2, { text: error }),
6883
- /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Section, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Row, { label: "Approved", actions: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "text-foreground", children: [
6857
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultSection, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Approved", actions: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "text-foreground", children: [
6884
6858
  "Return to ",
6885
6859
  where,
6886
6860
  " by ",
6887
- (0, import_format8.formatAbsoluteDate)(approvedUntil, void 0, ""),
6861
+ (0, import_format12.formatAbsoluteDate)(approvedUntil, void 0, ""),
6888
6862
  "."
6889
6863
  ] }) }) : !passkeys ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Empty, { children: [
6890
6864
  "Approve with your password in ",
6891
6865
  where,
6892
6866
  "."
6893
6867
  ] }) : !here ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6894
- Row,
6868
+ VaultRow,
6895
6869
  {
6896
6870
  label: "Passkey",
6897
6871
  hint: `Passkeys work only on ${passkeys.rpId}`,
@@ -6899,14 +6873,14 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6899
6873
  children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-muted-foreground", children: "Not on this page" })
6900
6874
  }
6901
6875
  ) : methods === null ? error ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Empty, { children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.RegionSkeleton, { shape: "rows", count: 1, "aria-label": "Checking your account", className: "px-3 sm:px-4" }) : !methods.passkey ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6902
- Row,
6876
+ VaultRow,
6903
6877
  {
6904
6878
  label: "Passkey",
6905
6879
  hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
6906
6880
  actions: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
6907
6881
  children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
6908
6882
  }
6909
- ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(Row, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-foreground", children: "Ready" }) }) })
6883
+ ) : /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-foreground", children: "Ready" }) }) })
6910
6884
  ] }) });
6911
6885
  }
6912
6886
 
@@ -7184,7 +7158,7 @@ var TONE = {
7184
7158
  };
7185
7159
  function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
7186
7160
  if (!bridge) {
7187
- return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Empty, { children: "Passkey import needs the desktop app." }) }) });
7161
+ return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Empty, { children: "Passkey import needs the desktop app." }) }) });
7188
7162
  }
7189
7163
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
7190
7164
  }
@@ -7231,25 +7205,25 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7231
7205
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "primary", onClick: onClose, children: "Done" })
7232
7206
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "quiet", onClick: onClose, children: "Close" });
7233
7207
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
7234
- screen.kind === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Section, { children: [
7235
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Select, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
7236
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
7237
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
7208
+ screen.kind === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(VaultSection, { children: [
7209
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Select, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
7210
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
7211
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
7238
7212
  ] }) : null,
7239
- preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Section, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7213
+ preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7240
7214
  Windowed,
7241
7215
  {
7242
7216
  items: preview.slots,
7243
- render: (slot) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Badge, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
7217
+ render: (slot) => /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Badge, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
7244
7218
  }
7245
7219
  ) }) : null,
7246
- status && !preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(Section, { title: `${accounted(status)} of ${status.total} done`, children: [
7247
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Imported", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.committed }) }),
7248
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Already there", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.already_present }) }),
7249
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Can't import", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.unsupported }) }),
7250
- /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Failed", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
7251
- status.uncertain > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Needs recovery", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.uncertain }) }) : null,
7252
- status.not_attempted > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Row, { label: "Not tried", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.not_attempted }) }) : null
7220
+ status && !preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
7221
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Imported", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.committed }) }),
7222
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Already there", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.already_present }) }),
7223
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Can't import", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.unsupported }) }),
7224
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Failed", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
7225
+ status.uncertain > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Needs recovery", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.uncertain }) }) : null,
7226
+ status.not_attempted > 0 ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Not tried", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.not_attempted }) }) : null
7253
7227
  ] }) : null,
7254
7228
  screen.message ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
7255
7229
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ErrorLine, { message: limitError })
@@ -7260,6 +7234,7 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7260
7234
  var import_react39 = require("react");
7261
7235
  var import_design_system23 = require("@ai-matrx/design-system");
7262
7236
  var import_controls32 = require("@ai-matrx/design-system/controls");
7237
+ var import_icons14 = require("@ai-matrx/design-system/icons");
7263
7238
 
7264
7239
  // src/extension/CaptureCard.tsx
7265
7240
  var import_react36 = require("react");
@@ -7402,6 +7377,7 @@ function FillSetupCard({ fillSetup }) {
7402
7377
  var import_react38 = require("react");
7403
7378
  var import_design_system22 = require("@ai-matrx/design-system");
7404
7379
  var import_controls31 = require("@ai-matrx/design-system/controls");
7380
+ var import_icons13 = require("@ai-matrx/design-system/icons");
7405
7381
  var import_jsx_runtime36 = require("react/jsx-runtime");
7406
7382
  var HOLD_MS = 6e4;
7407
7383
  function PageGenerator({ fields }) {
@@ -7455,11 +7431,11 @@ function PageGenerator({ fields }) {
7455
7431
  const value = held.value;
7456
7432
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
7457
7433
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7458
- Row,
7434
+ VaultRow,
7459
7435
  {
7460
7436
  label: "New password",
7461
7437
  actions: /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
7462
- value ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CopyGlyph, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
7438
+ value ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_icons13.CopyIcon, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
7463
7439
  /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_design_system22.Popover, { open, onOpenChange: setOpen, children: [
7464
7440
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_design_system22.PopoverTrigger, { asChild: true, children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "outline", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
7465
7441
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_design_system22.PopoverContent, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
@@ -7468,7 +7444,7 @@ function PageGenerator({ fields }) {
7468
7444
  children: said ? /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("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__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-xs text-muted-foreground", children: "Choose the boxes to fill." }) : /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "text-xs text-disabled-foreground", children: "Fills the page\u2019s new-password box" })
7469
7445
  }
7470
7446
  ),
7471
- value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(Row, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
7447
+ value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(VaultRow, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(import_controls31.Button, { variant: "primary", icon: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
7472
7448
  ] });
7473
7449
  }
7474
7450
 
@@ -7530,7 +7506,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7530
7506
  return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex h-full min-h-0 flex-col overflow-y-auto bg-background text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-col gap-3 px-3 pb-4 pt-3", children: [
7531
7507
  header,
7532
7508
  /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
7533
- /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_design_system23.SiteIcon, { site: page.url, fallback: GlobeGlyph, className: "size-4" }),
7509
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_design_system23.SiteIcon, { site: page.url, fallback: import_icons14.GlobeIcon, className: "size-4" }),
7534
7510
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
7535
7511
  page.refresh ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
7536
7512
  onBrowse ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
@@ -7538,7 +7514,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7538
7514
  fillSetup ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(FillSetupCard, { fillSetup }) : null,
7539
7515
  capture ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CaptureCard, { capture, onChanged }) : null,
7540
7516
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7541
- Section,
7517
+ VaultSection,
7542
7518
  {
7543
7519
  title: "This site",
7544
7520
  actions: canSave ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
@@ -7546,7 +7522,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7546
7522
  }
7547
7523
  ),
7548
7524
  said ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Outcome, { said, onDismiss: () => setSaid(null) }) : page.blocked && page.url && state.status === "ready" ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("p", { className: "px-1 text-xs text-muted-foreground", children: BLOCK_WORDS[page.blocked] }) : null,
7549
- newPasswordFields && canSave ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(Section, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PageGenerator, { fields: newPasswordFields }) }) : null
7525
+ newPasswordFields && canSave ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PageGenerator, { fields: newPasswordFields }) }) : null
7550
7526
  ] }) });
7551
7527
  }
7552
7528
  function Outcome({ said, onDismiss }) {
@@ -7608,6 +7584,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
7608
7584
  var import_react40 = require("react");
7609
7585
  var import_design_system24 = require("@ai-matrx/design-system");
7610
7586
  var import_controls33 = require("@ai-matrx/design-system/controls");
7587
+ var import_icons15 = require("@ai-matrx/design-system/icons");
7611
7588
  var import_jsx_runtime38 = require("react/jsx-runtime");
7612
7589
  function vaultChoices(items, organizations, current) {
7613
7590
  const n = (f) => items.filter(f).length;
@@ -7623,7 +7600,7 @@ function vaultChoices(items, organizations, current) {
7623
7600
  function VaultSelect({ value, choices, onChange }) {
7624
7601
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(import_controls33.Select, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
7625
7602
  }
7626
- var CATEGORY_GLYPHS = { logins: GlobeGlyph, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
7603
+ var CATEGORY_GLYPHS = { logins: import_icons15.GlobeIcon, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
7627
7604
  var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
7628
7605
  function itemCategory(item, definitions) {
7629
7606
  return categoryOf(item.definitionKey, familyOf(item.definitionKey, definitions));
@@ -7688,7 +7665,7 @@ function Group({ title, children }) {
7688
7665
  children
7689
7666
  ] });
7690
7667
  }
7691
- function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
7668
+ function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
7692
7669
  const [tagsOpen, setTagsOpen] = (0, import_react40.useState)(view.startsWith("tag:"));
7693
7670
  return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("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: [
7694
7671
  /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
@@ -7697,7 +7674,7 @@ function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views,
7697
7674
  ] }),
7698
7675
  /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
7699
7676
  /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex flex-col gap-0.5", children: [
7700
- hasPage ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "page", glyph: GlobeGlyph, label: "This page", onClick: () => onView("page") }) : null,
7677
+ hasPage ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "page", glyph: import_icons15.GlobeIcon, label: "This page", onClick: () => onView("page") }) : null,
7701
7678
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
7702
7679
  hasFavorites ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
7703
7680
  hasRecents ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
@@ -7737,7 +7714,7 @@ var NO_HOST = {};
7737
7714
  var ITEM_PANELS = {
7738
7715
  share: SharePanel,
7739
7716
  move: MovePanel,
7740
- history: HistoryPanel,
7717
+ history: ItemHistoryPanel,
7741
7718
  activity: ActivityPanel,
7742
7719
  settings: ItemSettingsPanel,
7743
7720
  field: FieldSettingsPanel,
@@ -8128,7 +8105,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8128
8105
  ] }) : null,
8129
8106
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
8130
8107
  mode === "full" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8131
- Sidebar,
8108
+ VaultSidebar,
8132
8109
  {
8133
8110
  vault: loc.vault,
8134
8111
  choices,