@ai-matrx/vault 0.1.9 → 0.1.11

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
@@ -138,6 +138,7 @@ __export(src_exports, {
138
138
  CATEGORIES: () => CATEGORIES,
139
139
  DEFAULT_LOCATION: () => DEFAULT_LOCATION,
140
140
  GenerateButton: () => GenerateButton,
141
+ HIDDEN_ITEM_TAG: () => HIDDEN_ITEM_TAG,
141
142
  LOCKED_MESSAGE: () => LOCKED_MESSAGE,
142
143
  VaultApp: () => VaultApp,
143
144
  VaultLockedError: () => VaultLockedError,
@@ -148,6 +149,7 @@ __export(src_exports, {
148
149
  createVaultKnobs: () => createVaultKnobs,
149
150
  guardPort: () => guardPort,
150
151
  inferFromUrl: () => inferFromUrl,
152
+ isHiddenItem: () => isHiddenItem,
151
153
  locationFromParams: () => locationFromParams,
152
154
  locationToParams: () => locationToParams,
153
155
  loginSiteOf: () => loginSiteOf,
@@ -222,6 +224,7 @@ var import_design_system2 = require("@ai-matrx/design-system");
222
224
  var import_controls = require("@ai-matrx/design-system/controls");
223
225
 
224
226
  // src/glyphs.tsx
227
+ var import_icons = require("@ai-matrx/design-system/icons");
225
228
  var import_jsx_runtime2 = require("react/jsx-runtime");
226
229
  function glyph(paths, air = [1, 1]) {
227
230
  const style = { "--matrx-glyph-air-l": air[0], "--matrx-glyph-air-r": air[1] };
@@ -233,10 +236,6 @@ var KeyGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_ru
233
236
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "7.5", cy: "15.5", r: "5.5" }),
234
237
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m21 2-9.6 9.6M15.5 7.5l3 3" })
235
238
  ] }), [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
239
  var NoteGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
241
240
  /* @__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
241
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M14 2v4a2 2 0 0 0 2 2h4M16 13H8M16 17H8" })
@@ -266,10 +265,6 @@ var FileGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_r
266
265
  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
266
  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
267
  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
268
  var EyeGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
274
269
  /* @__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
270
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "12", cy: "12", r: "3" })
@@ -294,11 +289,6 @@ var BuildingGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_j
294
289
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "4", y: "2", width: "16", height: "20", rx: "2" }),
295
290
  /* @__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
291
  ] }), [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
292
  var ChevronLeftGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m15 18-6-6 6-6" }), [8, 8]);
303
293
  var GridGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
304
294
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("rect", { x: "3", y: "3", width: "7", height: "7", rx: "1" }),
@@ -317,7 +307,7 @@ var FAMILY_GLYPHS = {
317
307
  cloud_infrastructure: ServerGlyph
318
308
  };
319
309
  function definitionGlyph(key, family) {
320
- if (key === "username_password" || key === "website_login") return GlobeGlyph;
310
+ if (key === "username_password" || key === "website_login") return import_icons.GlobeIcon;
321
311
  return FAMILY_GLYPHS[family] ?? KeyGlyph;
322
312
  }
323
313
  var XGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M18 6 6 18M6 6l12 12" }), [5, 5]);
@@ -335,15 +325,7 @@ var MoreGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_r
335
325
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("circle", { cx: "5", cy: "12", r: "1" })
336
326
  ] }), [3, 3]);
337
327
  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
328
  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
329
  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
330
  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
331
  var ChevronDownGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m6 9 6 6 6-6" }), [5, 5]);
@@ -384,10 +366,6 @@ var RefreshGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_js
384
366
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 3v5h-5M3 21v-5h5" })
385
367
  ] }), [2, 2]);
386
368
  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
369
  var UploadGlyph = glyph(/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
392
370
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4" }),
393
371
  /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("path", { d: "m17 8-5-5-5 5M12 3v12" })
@@ -469,7 +447,7 @@ var Ctx2 = (0, import_react2.createContext)((run) => run());
469
447
  function useConfirmed() {
470
448
  return (0, import_react2.useContext)(Ctx2);
471
449
  }
472
- var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack" };
450
+ var PROVIDER_LABEL = { google: "Google", github: "GitHub", azure: "Microsoft", apple: "Apple", linkedin_oidc: "LinkedIn", slack_oidc: "Slack", browser: "Browser", touch_id: "Touch ID" };
473
451
  var providerLabel = (p) => PROVIDER_LABEL[p] ?? p.charAt(0).toUpperCase() + p.slice(1);
474
452
  function IdentityGate({ identity, children }) {
475
453
  const [asking, setAsking] = (0, import_react2.useState)(false);
@@ -539,10 +517,21 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
539
517
  ] }),
540
518
  /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("div", { className: "flex flex-col gap-3", children: [
541
519
  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)),
520
+ account10?.providers.map((p) => /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
521
+ import_controls.Button,
522
+ {
523
+ variant: identity.dev ? "outline" : "primary",
524
+ disabled: busy,
525
+ onClick: () => void attempt(async () => {
526
+ if (await identity.withProvider(p) === "confirmed") onDone();
527
+ }, false),
528
+ children: [
529
+ "Continue with ",
530
+ providerLabel(p)
531
+ ]
532
+ },
533
+ p
534
+ )),
546
535
  account10?.hasPassword ? /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)("form", { className: "flex gap-2", onSubmit: (e) => {
547
536
  e.preventDefault();
548
537
  if (password) void attempt(() => identity.withPassword(password));
@@ -569,6 +558,7 @@ function ConfirmIdentityDialog({ open, identity, onDone, onCancel }) {
569
558
  var import_react5 = require("react");
570
559
  var import_controls2 = require("@ai-matrx/design-system/controls");
571
560
  var import_design_system5 = require("@ai-matrx/design-system");
561
+ var import_icons2 = require("@ai-matrx/design-system/icons");
572
562
 
573
563
  // src/hooks.ts
574
564
  var import_react3 = require("react");
@@ -637,7 +627,7 @@ function useRoomOf(ref) {
637
627
  return room;
638
628
  }
639
629
  var RoomProvider = Room.Provider;
640
- function Section({ title, actions, children, className }) {
630
+ function VaultSection({ title, actions, children, className }) {
641
631
  const flat = (0, import_react4.useContext)(InPanel);
642
632
  const desktop = (0, import_design_system4.useLook)() === "desktop";
643
633
  return /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("section", { className: (0, import_design_system4.cn)("flex flex-col gap-1.5", className), children: [
@@ -653,7 +643,7 @@ var ROW_GRID = {
653
643
  roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
654
644
  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
645
  };
656
- function Row({ label, hint, children, actions, top = false, className }) {
646
+ function VaultRow({ label, hint, children, actions, top = false, className }) {
657
647
  const room = (0, import_react4.useContext)(Room);
658
648
  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
649
  /* @__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 +664,6 @@ function Panel({ title, open = true, onClose, children, footer, size = "lg" }) {
674
664
  footer ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(import_design_system3.DialogFooter, { children: footer }) : null
675
665
  ] }) });
676
666
  }
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
667
  var DAY_FORMAT = { year: "numeric", month: "short", day: "numeric" };
683
668
 
684
669
  // src/FieldRows.tsx
@@ -737,14 +722,14 @@ function SecretRow({ port, item, field, extra }) {
737
722
  const multiline = field.kind === "multiline";
738
723
  const shown = visible ? plain : secret.value;
739
724
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
740
- Row,
725
+ VaultRow,
741
726
  {
742
727
  label: field.label,
743
728
  top: multiline && shown !== null,
744
729
  actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
745
730
  extra,
746
731
  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
732
+ 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
733
  ] }),
749
734
  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
735
  }
@@ -754,7 +739,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
754
739
  const copyValue2 = useCopy();
755
740
  const isUrl = /^https?:\/\//i.test(value);
756
741
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
757
- Row,
742
+ VaultRow,
758
743
  {
759
744
  label,
760
745
  hint,
@@ -762,7 +747,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
762
747
  actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
763
748
  extra,
764
749
  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 }) })
750
+ /* @__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
751
  ] }),
767
752
  children: isUrl && openUrl ? (
768
753
  // A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
@@ -785,12 +770,12 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
785
770
  );
786
771
  }
787
772
  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" }) });
773
+ 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
774
  }
790
775
  function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
791
776
  const [shown, setShown] = (0, import_react5.useState)(false);
792
777
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
793
- Row,
778
+ VaultRow,
794
779
  {
795
780
  label,
796
781
  hint,
@@ -807,7 +792,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
807
792
  function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
808
793
  const [shown, setShown] = (0, import_react5.useState)(false);
809
794
  return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
810
- Row,
795
+ VaultRow,
811
796
  {
812
797
  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
798
  actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
@@ -820,6 +805,7 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
820
805
  }
821
806
 
822
807
  // src/activity/HistoryPanel.tsx
808
+ var import_icons3 = require("@ai-matrx/design-system/icons");
823
809
  var import_format3 = require("@ai-matrx/kit/format");
824
810
 
825
811
  // src/activity/logic.ts
@@ -872,6 +858,8 @@ function matchesQuery(item, query) {
872
858
  if (!q) return true;
873
859
  return [item.name, item.definitionLabel, ...item.tags, ...item.loginUrls, ...item.custom.map((c) => `${c.label} ${c.value}`)].some((h) => h.toLowerCase().includes(q));
874
860
  }
861
+ var HIDDEN_ITEM_TAG = "matrx:hidden";
862
+ var isHiddenItem = (item) => (item.tags ?? []).includes(HIDDEN_ITEM_TAG);
875
863
  var isAuthenticatorStorage = (key) => key === "totp_seed" || key.startsWith("totp_") || key === "authenticator_last_time_step";
876
864
  function loginSiteOf(item) {
877
865
  const raw = item.loginUrls[0];
@@ -1312,7 +1300,7 @@ function ActivityPanel({ item, port, onClose }) {
1312
1300
  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
1301
  children: [
1314
1302
  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(
1303
+ 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
1304
  day.entries.map((entry) => ({ entry, s: auditSentence(entry, item, me) })),
1317
1305
  (r) => `${r.s.what}|${r.s.who ?? ""}`
1318
1306
  ).map(({ row: { entry, s }, times }) => {
@@ -1335,7 +1323,7 @@ function ActivityPanel({ item, port, onClose }) {
1335
1323
  var import_jsx_runtime7 = require("react/jsx-runtime");
1336
1324
  var MASK2 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
1337
1325
  var messageOf = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
1338
- function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1326
+ function ItemHistoryPanel({ item, port, arg, onClose, onChanged }) {
1339
1327
  const eligible = historyEligible(item);
1340
1328
  const [page, setPage] = (0, import_react7.useState)(null);
1341
1329
  const [loading, setLoading] = (0, import_react7.useState)(eligible);
@@ -1397,7 +1385,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
1397
1385
  error ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null,
1398
1386
  notice ? /* @__PURE__ */ (0, import_jsx_runtime7.jsx)("p", { role: "status", className: "px-1 text-sm text-success", children: notice }) : null,
1399
1387
  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,
1388
+ 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
1389
  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
1390
  page.captureStartedAt ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)("span", { className: "text-muted-foreground", children: [
1403
1391
  "Kept since ",
@@ -1458,12 +1446,12 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1458
1446
  }
1459
1447
  }
1460
1448
  return /* @__PURE__ */ (0, import_jsx_runtime7.jsx)(
1461
- Row,
1449
+ VaultRow,
1462
1450
  {
1463
1451
  label: when,
1464
1452
  actions: entry.available ? /* @__PURE__ */ (0, import_jsx_runtime7.jsxs)(import_jsx_runtime7.Fragment, { children: [
1465
1453
  /* @__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() }),
1454
+ /* @__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
1455
  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
1456
  ] }) : null,
1469
1457
  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 +1463,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
1475
1463
  var import_react13 = require("react");
1476
1464
  var import_controls9 = require("@ai-matrx/design-system/controls");
1477
1465
  var import_design_system9 = require("@ai-matrx/design-system");
1466
+ var import_icons5 = require("@ai-matrx/design-system/icons");
1478
1467
 
1479
1468
  // src/authenticator/AddOtpPanel.tsx
1480
1469
  var import_react12 = require("react");
@@ -1484,8 +1473,11 @@ var import_controls8 = require("@ai-matrx/design-system/controls");
1484
1473
  var import_react8 = require("react");
1485
1474
  var import_controls5 = require("@ai-matrx/design-system/controls");
1486
1475
  var import_design_system7 = require("@ai-matrx/design-system");
1476
+ var import_icons4 = require("@ai-matrx/design-system/icons");
1477
+ var import_format5 = require("@ai-matrx/kit/format");
1487
1478
 
1488
1479
  // src/authenticator/otpauth.ts
1480
+ var import_format4 = require("@ai-matrx/kit/format");
1489
1481
  var TOTP_DEFAULT_DIGITS = 6;
1490
1482
  var TOTP_DEFAULT_PERIOD = 30;
1491
1483
  var TOTP_DEFAULT_ALGORITHM = "SHA1";
@@ -1553,14 +1545,8 @@ function describeEnrollment(parsed) {
1553
1545
  const parts = [parsed.issuer, parsed.account].filter((p) => Boolean(p));
1554
1546
  return parts.length ? parts.join(" \xB7 ") : "Setup key";
1555
1547
  }
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
1548
  function maskedCode(digits = TOTP_DEFAULT_DIGITS) {
1563
- return groupCode("\u2022".repeat(Math.max(6, digits)));
1549
+ return (0, import_format4.groupCode)("\u2022".repeat(Math.max(6, digits)));
1564
1550
  }
1565
1551
  function accountOfLabel(label, issuer) {
1566
1552
  const l = label?.trim();
@@ -1636,7 +1622,7 @@ function useCopied() {
1636
1622
  }
1637
1623
  function CodeButton({ live, digits, size = "md", label }) {
1638
1624
  const { copied, copy } = useCopied();
1639
- const shown = live.code ? groupCode(live.code) : maskedCode(digits);
1625
+ const shown = live.code ? (0, import_format5.groupCode)(live.code) : maskedCode(digits);
1640
1626
  return /* @__PURE__ */ (0, import_jsx_runtime8.jsxs)(
1641
1627
  "button",
1642
1628
  {
@@ -1655,7 +1641,7 @@ function CodeButton({ live, digits, size = "md", label }) {
1655
1641
  }
1656
1642
  function CopyCodeButton({ live, label }) {
1657
1643
  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) });
1644
+ 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
1645
  }
1660
1646
 
1661
1647
  // src/authenticator/live-code.ts
@@ -1927,7 +1913,7 @@ function OtpSetupRow({ value, onChange, label = "One-time password", placeholder
1927
1913
  className: dragging ? "rounded-lg bg-accent" : void 0,
1928
1914
  children: [
1929
1915
  /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(
1930
- Row,
1916
+ VaultRow,
1931
1917
  {
1932
1918
  label,
1933
1919
  actions: /* @__PURE__ */ (0, import_jsx_runtime9.jsxs)(import_jsx_runtime9.Fragment, { children: [
@@ -2077,7 +2063,7 @@ function TotpRow({ port, item, onChanged }) {
2077
2063
  ] })
2078
2064
  ] }) : null;
2079
2065
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(
2080
- Row,
2066
+ VaultRow,
2081
2067
  {
2082
2068
  label: "One-time password",
2083
2069
  actions: /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)(import_jsx_runtime10.Fragment, { children: [
@@ -2136,7 +2122,7 @@ function TwoFactorMethodRow({ port, item, onChanged }) {
2136
2122
  const [busy, setBusy] = (0, import_react11.useState)(false);
2137
2123
  const [error, setError] = (0, import_react11.useState)(null);
2138
2124
  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)(
2125
+ 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
2126
  import_controls7.Select,
2141
2127
  {
2142
2128
  value: value ?? "none",
@@ -2251,7 +2237,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2251
2237
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(import_controls8.Button, { variant: "primary", disabled: !ready, onClick: () => void save(), children: busy ? "Adding\u2026" : "Add" })
2252
2238
  ] }),
2253
2239
  children: [
2254
- /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(Section, { children: [
2240
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsxs)(VaultSection, { children: [
2255
2241
  /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2256
2242
  OtpSetupRow,
2257
2243
  {
@@ -2273,7 +2259,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2273
2259
  status: image ? `QR image ready \xB7 ${image.name}` : null
2274
2260
  }
2275
2261
  ),
2276
- /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(Row, { label: "Add to", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2262
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Add to", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2277
2263
  import_controls8.Select,
2278
2264
  {
2279
2265
  value: target,
@@ -2287,7 +2273,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2287
2273
  }
2288
2274
  ) }),
2289
2275
  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)(
2276
+ /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime11.jsx)(
2291
2277
  import_controls8.Field,
2292
2278
  {
2293
2279
  className: "w-full",
@@ -2301,7 +2287,7 @@ function AddOtpPanel({ port, items, definitions, itemId = null, onClose, onChang
2301
2287
  "aria-label": "Name"
2302
2288
  }
2303
2289
  ) }),
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 }) })
2290
+ /* @__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
2291
  ] }) : null
2306
2292
  ] }),
2307
2293
  error ? /* @__PURE__ */ (0, import_jsx_runtime11.jsx)("p", { className: "px-1 text-sm text-destructive", role: "alert", children: error }) : null
@@ -2369,7 +2355,7 @@ function AuthenticatorView({ port, items, definitions, query, onOpen, onChanged,
2369
2355
  /* @__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
2356
  /* @__PURE__ */ (0, import_jsx_runtime12.jsx)("p", { className: "text-sm font-medium text-foreground", children: "No one-time passwords yet" }),
2371
2357
  /* @__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)(
2358
+ ] }) : 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
2359
  OtpListRow,
2374
2360
  {
2375
2361
  port,
@@ -2463,7 +2449,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2463
2449
  "Open login"
2464
2450
  ] }),
2465
2451
  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" }),
2452
+ /* @__PURE__ */ (0, import_jsx_runtime12.jsx)(import_icons5.CopyIcon, { className: "size-4" }),
2467
2453
  "Copy code"
2468
2454
  ] }) : null,
2469
2455
  canManage ? /* @__PURE__ */ (0, import_jsx_runtime12.jsxs)(import_jsx_runtime12.Fragment, { children: [
@@ -2490,6 +2476,7 @@ function OtpListRow({ port, item, family, entry, onOpen, onRename, onChanged, on
2490
2476
  var import_react14 = require("react");
2491
2477
  var import_controls10 = require("@ai-matrx/design-system/controls");
2492
2478
  var import_confirm_opener3 = require("@ai-matrx/kit/confirm-opener");
2479
+ var import_icons6 = require("@ai-matrx/design-system/icons");
2493
2480
 
2494
2481
  // src/fields/rules.ts
2495
2482
  var ENV_KEY_RE = /^[A-Za-z_][A-Za-z0-9_]*$/;
@@ -2639,7 +2626,7 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2639
2626
  const locked = !canEdit || busy !== null;
2640
2627
  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
2628
  !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)(
2629
+ /* @__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
2630
  import_controls10.SegmentedControl,
2644
2631
  {
2645
2632
  "aria-label": "Who can see it",
@@ -2648,8 +2635,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2648
2635
  data: handlingChoices(field.handling).map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint, disabled: locked }))
2649
2636
  }
2650
2637
  ) }) }),
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)(
2638
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "Automation", children: [
2639
+ /* @__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
2640
  import_controls10.Field,
2654
2641
  {
2655
2642
  ref: envRef,
@@ -2669,10 +2656,10 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2669
2656
  }
2670
2657
  }
2671
2658
  ) }),
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) }) })
2659
+ /* @__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
2660
  ] }),
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)(
2661
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "Field", children: [
2662
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(VaultRow, { label: "Description", children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2676
2663
  import_controls10.Field,
2677
2664
  {
2678
2665
  className: "w-full",
@@ -2688,8 +2675,8 @@ function FieldSettings({ item, port, field, onClose, onChanged }) {
2688
2675
  }
2689
2676
  }
2690
2677
  ) }),
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 }) }) })
2678
+ /* @__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 }) }) }),
2679
+ /* @__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
2680
  ] }),
2694
2681
  error ? /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(Problem, { children: error }) : null
2695
2682
  ] });
@@ -2720,8 +2707,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2720
2707
  const fillHint = !hasWebsite ? "Add a website first" : item.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically";
2721
2708
  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
2709
  !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)(
2710
+ /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)(VaultSection, { title: "In the browser", children: [
2711
+ /* @__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
2712
  import_controls10.Select,
2726
2713
  {
2727
2714
  "aria-label": "Website matching",
@@ -2731,13 +2718,13 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2731
2718
  onValueChange: (m) => void save("match", () => port.fields.updateItem(item, { uriMatchMode: m }))
2732
2719
  }
2733
2720
  ) }),
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 })) }) }),
2721
+ /* @__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
2722
  promotable.map((f) => /* @__PURE__ */ (0, import_jsx_runtime13.jsx)(
2736
- Row,
2723
+ VaultRow,
2737
2724
  {
2738
2725
  label: f.label,
2739
2726
  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" }),
2727
+ 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
2728
  children: /* @__PURE__ */ (0, import_jsx_runtime13.jsx)("span", { className: "text-muted-foreground", children: "Not a website yet" })
2742
2729
  },
2743
2730
  f.id
@@ -2745,8 +2732,8 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2745
2732
  ] }),
2746
2733
  /* @__PURE__ */ (0, import_jsx_runtime13.jsxs)("div", { className: "flex flex-col gap-1.5", children: [
2747
2734
  /* @__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,
2735
+ 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)(
2736
+ VaultRow,
2750
2737
  {
2751
2738
  label: f.label,
2752
2739
  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 +2758,7 @@ function ItemSettingsPanel({ item, port, onClose, onChanged, onPanel }) {
2771
2758
  var import_react15 = require("react");
2772
2759
  var import_design_system10 = require("@ai-matrx/design-system");
2773
2760
  var import_controls11 = require("@ai-matrx/design-system/controls");
2761
+ var import_icons7 = require("@ai-matrx/design-system/icons");
2774
2762
 
2775
2763
  // src/generator/generate.ts
2776
2764
  var import_credential_generator = require("@ai-matrx/kit/credential-generator");
@@ -2925,7 +2913,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
2925
2913
  /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("div", { className: "flex min-h-7 items-start gap-1", children: [
2926
2914
  /* @__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
2915
  /* @__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() }),
2916
+ /* @__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
2917
  /* @__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
2918
  ] }),
2931
2919
  strength && candidate ? /* @__PURE__ */ (0, import_jsx_runtime14.jsxs)("p", { className: "text-xs", children: [
@@ -3052,6 +3040,7 @@ function useLocked(lock) {
3052
3040
  }
3053
3041
 
3054
3042
  // src/io/BackupPanel.tsx
3043
+ var import_format6 = require("@ai-matrx/kit/format");
3055
3044
  var import_react18 = require("react");
3056
3045
  var import_controls13 = require("@ai-matrx/design-system/controls");
3057
3046
  var import_download = require("@ai-matrx/kit/download");
@@ -3193,17 +3182,17 @@ function omissionText(o) {
3193
3182
  return `${o.count ?? "Some"} ${what}: ${o.reason.replaceAll("_", " ")}`;
3194
3183
  }
3195
3184
  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" })
3185
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
3186
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Credentials", children: value.record_count }),
3187
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(VaultRow, { label: "Protected fields", children: value.field_count }),
3188
+ /* @__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
3189
  ] });
3201
3190
  }
3202
3191
  function Omissions({ omissions, accepted, onAccepted, verb }) {
3203
3192
  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` }) })
3193
+ return /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { title: "Left out", children: [
3194
+ 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}`)),
3195
+ /* @__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
3196
  ] });
3208
3197
  }
3209
3198
  function BackupPanel({ port, items, onClose, onChanged }) {
@@ -3338,7 +3327,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3338
3327
  ),
3339
3328
  mode === "backup" ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3340
3329
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3341
- Section,
3330
+ VaultSection,
3342
3331
  {
3343
3332
  title: `${selected.size} of ${plural(items.length, "credential")}`,
3344
3333
  actions: /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
@@ -3357,13 +3346,13 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3357
3346
  backup ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3358
3347
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Summary, { value: backup }),
3359
3348
  /* @__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) }) })
3349
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
3350
+ /* @__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) }) }),
3351
+ /* @__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
3352
  ] })
3364
3353
  ] }) : 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: [
3354
+ ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_jsx_runtime16.Fragment, { children: !restorePreview ? /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultSection, { children: [
3355
+ /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(VaultRow, { label: "File", ...file ? { hint: file.name } : {}, children: [
3367
3356
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(import_controls13.Button, { variant: "outline", disabled: busy, onClick: () => fileInput.current?.click(), children: "Choose a backup" }),
3368
3357
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(
3369
3358
  "input",
@@ -3379,11 +3368,11 @@ function BackupPanel({ port, items, onClose, onChanged }) {
3379
3368
  }
3380
3369
  )
3381
3370
  ] }),
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) }) })
3371
+ /* @__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
3372
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime16.jsxs)(import_jsx_runtime16.Fragment, { children: [
3384
3373
  /* @__PURE__ */ (0, import_jsx_runtime16.jsx)(Summary, { value: restorePreview }),
3385
3374
  !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: [
3375
+ !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
3376
  RECORD_STATUS[r.status],
3388
3377
  r.reason === "alias_conflict" ? " \xB7 name in use" : ""
3389
3378
  ] }) }, r.source_item_id)) })
@@ -3488,7 +3477,7 @@ function ExportPanel({ port, items, onClose }) {
3488
3477
  ] })
3489
3478
  ] }),
3490
3479
  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)(
3480
+ /* @__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
3481
  import_controls14.Select,
3493
3482
  {
3494
3483
  value: profile,
@@ -3501,7 +3490,7 @@ function ExportPanel({ port, items, onClose }) {
3501
3490
  }
3502
3491
  ) }) }),
3503
3492
  /* @__PURE__ */ (0, import_jsx_runtime17.jsx)(
3504
- Section,
3493
+ VaultSection,
3505
3494
  {
3506
3495
  title: `${selected.size} of ${plural(logins.length, "login")}`,
3507
3496
  actions: /* @__PURE__ */ (0, import_jsx_runtime17.jsxs)(import_jsx_runtime17.Fragment, { children: [
@@ -4572,13 +4561,13 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4572
4561
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(import_controls15.Button, { variant: "primary", onClick: onClose, children: "Done" })
4573
4562
  ] });
4574
4563
  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) => {
4564
+ stage === "choose" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { children: [
4565
+ /* @__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
4566
  setSource(s);
4578
4567
  setError(null);
4579
4568
  } }) }),
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: [
4569
+ 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,
4570
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultRow, { label: "File", hint: fileName ?? void 0, children: [
4582
4571
  /* @__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
4572
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4584
4573
  "input",
@@ -4595,12 +4584,12 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4595
4584
  }
4596
4585
  )
4597
4586
  ] }),
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
4587
+ 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
4588
  ] }) : null,
4600
4589
  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,
4590
+ 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
4591
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(
4603
- Section,
4592
+ VaultSection,
4604
4593
  {
4605
4594
  title: draft.kind === "env" ? plural(envKeys.length, "value") : summary(counts, lines.length),
4606
4595
  actions: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(import_jsx_runtime18.Fragment, { children: [
@@ -4628,11 +4617,11 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4628
4617
  )
4629
4618
  }
4630
4619
  ),
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,
4620
+ 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
4621
  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)(
4622
+ draft.kind === "file" ? /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(More, { children: /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { children: [
4623
+ /* @__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" }) }),
4624
+ 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
4625
  import_controls15.Select,
4637
4626
  {
4638
4627
  value: draft.mapping[index] ?? "keep",
@@ -4644,16 +4633,16 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
4644
4633
  ] }) }) : null,
4645
4634
  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
4635
  ] }) : 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: [
4636
+ stage === "done" && done ? /* @__PURE__ */ (0, import_jsx_runtime18.jsxs)(VaultSection, { title: "Result", children: [
4637
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Created", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.created.length }) }),
4638
+ /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(VaultRow, { label: "Skipped", children: /* @__PURE__ */ (0, import_jsx_runtime18.jsx)("span", { className: "text-foreground", children: done.skipped }) }),
4639
+ /* @__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 }) }),
4640
+ 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,
4641
+ 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
4642
  plural(done.withOtp, "login"),
4654
4643
  " still need the one-time password added."
4655
4644
  ] }) }) : 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))
4645
+ 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
4646
  ] }) : null,
4658
4647
  /* @__PURE__ */ (0, import_jsx_runtime18.jsx)(ErrorLine, { message: error })
4659
4648
  ] });
@@ -4713,11 +4702,13 @@ var import_controls21 = require("@ai-matrx/design-system/controls");
4713
4702
  var import_confirm_opener9 = require("@ai-matrx/kit/confirm-opener");
4714
4703
 
4715
4704
  // src/activity/FilesSection.tsx
4705
+ var import_format7 = require("@ai-matrx/kit/format");
4716
4706
  var import_react21 = require("react");
4717
4707
  var import_controls16 = require("@ai-matrx/design-system/controls");
4718
4708
  var import_design_system13 = require("@ai-matrx/design-system");
4719
4709
  var import_confirm_opener6 = require("@ai-matrx/kit/confirm-opener");
4720
4710
  var import_download3 = require("@ai-matrx/kit/download");
4711
+ var import_icons8 = require("@ai-matrx/design-system/icons");
4721
4712
  var import_jsx_runtime20 = require("react/jsx-runtime");
4722
4713
  var messageOf2 = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
4723
4714
  var TOO_BIG = "Files over 25 MB can't be stored.";
@@ -4776,7 +4767,7 @@ function FilesSection({ item, port, editing, onChanged }) {
4776
4767
  onDragLeave: canEdit ? () => setDragging(false) : void 0,
4777
4768
  onDrop: canEdit ? drop : void 0,
4778
4769
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(
4779
- Section,
4770
+ VaultSection,
4780
4771
  {
4781
4772
  title: "Files",
4782
4773
  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 +4778,11 @@ function FilesSection({ item, port, editing, onChanged }) {
4787
4778
  } }) : null,
4788
4779
  item.attachments.map(
4789
4780
  (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,
4781
+ VaultRow,
4791
4782
  {
4792
4783
  label: a.label,
4793
4784
  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,
4785
+ 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
4786
  children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(FileName, { file: a })
4796
4787
  },
4797
4788
  a.id
@@ -4817,12 +4808,12 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4817
4808
  }
4818
4809
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)(import_jsx_runtime20.Fragment, { children: [
4819
4810
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(
4820
- Row,
4811
+ VaultRow,
4821
4812
  {
4822
4813
  label: a.label,
4823
4814
  hint: a.description || void 0,
4824
4815
  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,
4816
+ 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
4817
  /* @__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
4818
  /* @__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
4819
  /* @__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 +4844,7 @@ function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, o
4853
4844
  function FileName({ file }) {
4854
4845
  return /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("span", { className: "flex min-w-0 items-center gap-2", children: [
4855
4846
  /* @__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) })
4847
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: (0, import_format7.formatFileSize)(file.sizeBytes) })
4857
4848
  ] });
4858
4849
  }
4859
4850
  function Protection({ value, locked, onChange }) {
@@ -4876,13 +4867,13 @@ function NewFile({ file, busy, onAdd, onCancel }) {
4876
4867
  await onAdd({ label: label.trim(), description: description.trim() || null, handling });
4877
4868
  }
4878
4869
  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: [
4870
+ /* @__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
4871
  /* @__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) })
4872
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)("span", { className: "shrink-0 text-xs text-muted-foreground", children: (0, import_format7.formatFileSize)(file.size) })
4882
4873
  ] }) }),
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 }) }),
4874
+ /* @__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) }) }),
4875
+ /* @__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) }) }),
4876
+ /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(VaultRow, { label: "Protection", children: /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(Protection, { value: handling, locked: false, onChange: setHandling }) }),
4886
4877
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4887
4878
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4888
4879
  /* @__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 +4891,10 @@ function FileDetailsRows({ file, busy, onSave, onCancel }) {
4900
4891
  await onSave({ label: label.trim(), description: description.trim() || null, fileName: fileName.trim(), handling });
4901
4892
  }
4902
4893
  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 }) }),
4894
+ /* @__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) }) }),
4895
+ /* @__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) }) }),
4896
+ /* @__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) }) }),
4897
+ /* @__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
4898
  /* @__PURE__ */ (0, import_jsx_runtime20.jsxs)("div", { className: "flex justify-end gap-2 px-3 py-1 sm:px-4", children: [
4908
4899
  /* @__PURE__ */ (0, import_jsx_runtime20.jsx)(import_controls16.Button, { variant: "quiet", disabled: busy, onClick: onCancel, children: "Cancel" }),
4909
4900
  /* @__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 +4913,7 @@ function confirmSeal(label) {
4922
4913
  // src/fields/RecoveryCodesRow.tsx
4923
4914
  var import_react22 = require("react");
4924
4915
  var import_controls17 = require("@ai-matrx/design-system/controls");
4916
+ var import_icons9 = require("@ai-matrx/design-system/icons");
4925
4917
  var import_jsx_runtime21 = require("react/jsx-runtime");
4926
4918
  var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
4927
4919
  var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
@@ -4962,7 +4954,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4962
4954
  };
4963
4955
  if (draft !== null) {
4964
4956
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)(
4965
- Row,
4957
+ VaultRow,
4966
4958
  {
4967
4959
  label: "Recovery codes",
4968
4960
  top: true,
@@ -4982,7 +4974,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
4982
4974
  }
4983
4975
  if (!field) {
4984
4976
  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" }) });
4977
+ 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
4978
  }
4987
4979
  const sealed = field.handling === "sealed";
4988
4980
  const canSee = !sealed && item.capabilities.canReveal;
@@ -5004,7 +4996,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
5004
4996
  });
5005
4997
  };
5006
4998
  return /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(
5007
- Row,
4999
+ VaultRow,
5008
5000
  {
5009
5001
  label: "Recovery codes",
5010
5002
  top: codes !== null,
@@ -5015,7 +5007,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
5015
5007
  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
5008
  codes.map((code, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "flex min-h-7 items-center gap-1", children: [
5017
5009
  /* @__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") }),
5010
+ /* @__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
5011
  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
5012
  ] }, `${i}-${code}`)),
5021
5013
  error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
@@ -5024,33 +5016,17 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
5024
5016
  );
5025
5017
  }
5026
5018
 
5019
+ // src/ItemPane.tsx
5020
+ var import_icons11 = require("@ai-matrx/design-system/icons");
5021
+ var import_drafts = require("@ai-matrx/kit/drafts");
5022
+
5027
5023
  // src/draft-keep.ts
5028
5024
  var PREFIX = "matrx.vault.draft:";
5029
5025
  function draftKey(itemId, definitionKey) {
5030
5026
  return `${PREFIX}${itemId ?? `new:${definitionKey ?? "custom"}`}`;
5031
5027
  }
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
- }
5028
+ function keptFieldsOf(d) {
5029
+ return { name: d.name, description: d.description, tags: d.tags, loginUrls: d.loginUrls, notes: d.notes, custom: d.custom };
5054
5030
  }
5055
5031
 
5056
5032
  // src/extension/page-logic.ts
@@ -5197,6 +5173,7 @@ var import_react26 = require("react");
5197
5173
  var import_confirm_opener8 = require("@ai-matrx/kit/confirm-opener");
5198
5174
  var import_controls20 = require("@ai-matrx/design-system/controls");
5199
5175
  var import_design_system15 = require("@ai-matrx/design-system");
5176
+ var import_icons10 = require("@ai-matrx/design-system/icons");
5200
5177
 
5201
5178
  // src/sharing/logic.ts
5202
5179
  var LEVEL_OPTIONS = [
@@ -5228,7 +5205,7 @@ function copyRefusal(message2) {
5228
5205
  return /duplicate/i.test(message2) ? "There is already a copy of this item there." : null;
5229
5206
  }
5230
5207
  var isPasskey = (item) => item.definitionKey === "native_passkey" || item.definitionKey === "passkey_private";
5231
- function moveConsequence(item, to) {
5208
+ function itemMoveConsequence(item, to) {
5232
5209
  if (item.authenticator) return "One-time password stays behind; set it up again";
5233
5210
  return to ? "Its members get access; people you shared with lose it" : "Only you; organization members lose access";
5234
5211
  }
@@ -5318,7 +5295,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5318
5295
  const to = destinationOf(moveChoice.value);
5319
5296
  const ok = await (0, import_confirm_opener7.confirm)({
5320
5297
  title: `Move to ${moveChoice.label}?`,
5321
- description: `"${item.name}" stays the same item, so everything using it keeps working. ${moveConsequence(item, to)}.`,
5298
+ description: `"${item.name}" stays the same item, so everything using it keeps working. ${itemMoveConsequence(item, to)}.`,
5322
5299
  confirmLabel: "Move"
5323
5300
  });
5324
5301
  if (!ok) return;
@@ -5354,17 +5331,17 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5354
5331
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(StatusLine, { error, notice }),
5355
5332
  /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", className: "ml-auto", onClick: onClose, children: "Close" })
5356
5333
  ] }),
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: [
5334
+ 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
5335
  canMove && moves.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(
5359
- Row,
5336
+ VaultRow,
5360
5337
  {
5361
5338
  label: "Move to",
5362
- hint: moveChoice ? moveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5339
+ hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5363
5340
  actions: /* @__PURE__ */ (0, import_jsx_runtime24.jsx)(import_controls19.Button, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
5364
5341
  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
5342
  }
5366
5343
  ) : 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)(
5344
+ 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
5345
  import_controls19.Field,
5369
5346
  {
5370
5347
  className: "w-full",
@@ -5378,7 +5355,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5378
5355
  onChange: (e) => setEmail(e.target.value)
5379
5356
  }
5380
5357
  ) }) : 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
5358
+ 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
5359
  ] })
5383
5360
  }
5384
5361
  );
@@ -5460,7 +5437,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5460
5437
  }
5461
5438
  };
5462
5439
  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." }) }) });
5440
+ 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
5441
  }
5465
5442
  return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(
5466
5443
  Panel,
@@ -5473,9 +5450,9 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5473
5450
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(import_controls20.Button, { variant: "primary", className: "ml-auto", onClick: onClose, children: "Done" })
5474
5451
  ] }),
5475
5452
  children: [
5476
- /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Section, { title: "Who has access", children: [
5453
+ /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(VaultSection, { title: "Who has access", children: [
5477
5454
  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)(
5455
+ isOrg ? /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(AccessLine, { glyph: import_icons10.UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(
5479
5456
  import_controls20.Select,
5480
5457
  {
5481
5458
  variant: "inline",
@@ -5536,7 +5513,7 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
5536
5513
  const [level, setLevel] = (0, import_react26.useState)("use");
5537
5514
  const chosen = open.find((o) => o.id === target);
5538
5515
  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: [
5516
+ 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
5517
  /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5541
5518
  /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5542
5519
  /* @__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 +5563,7 @@ function MemberAccess({ port, organizationId, organizationName }) {
5586
5563
  const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
5587
5564
  if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
5588
5565
  };
5589
- return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(Section, { title: `${organizationName} vault access`, children: [
5566
+ return /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(VaultSection, { title: `${organizationName} vault access`, children: [
5590
5567
  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
5568
  import_controls20.Select,
5592
5569
  {
@@ -5621,7 +5598,7 @@ function SharingSummary({ item, port, className }) {
5621
5598
  }
5622
5599
 
5623
5600
  // src/ItemPane.tsx
5624
- var import_format4 = require("@ai-matrx/kit/format");
5601
+ var import_format8 = require("@ai-matrx/kit/format");
5625
5602
  var import_jsx_runtime26 = require("react/jsx-runtime");
5626
5603
  var USERNAME_KEYS = /^(username|user_name|email|login|username_or_email|account_email)$/;
5627
5604
  function ItemPane(props) {
@@ -5662,7 +5639,7 @@ function ItemPane(props) {
5662
5639
  if (was && was.id === id && was.mode === mode && editing) {
5663
5640
  setDraft((d) => rebaseDraft(was.base, base, d));
5664
5641
  } else {
5665
- const kept = editing ? readKeptDraft(keepKey, item?.updatedAt ?? "new") : null;
5642
+ const kept = editing ? (0, import_drafts.readKeptDraft)(keepKey, { basedOn: item?.updatedAt ?? "new" })?.value ?? null : null;
5666
5643
  setDraft(kept ? { ...base, ...kept } : base);
5667
5644
  setTagsText((kept ?? base).tags.join(", "));
5668
5645
  setError(null);
@@ -5677,8 +5654,8 @@ function ItemPane(props) {
5677
5654
  (0, import_react27.useEffect)(() => onDirty(dirty), [dirty, onDirty]);
5678
5655
  const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
5679
5656
  (0, import_react27.useEffect)(() => {
5680
- if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new", draft);
5681
- else if (!editing) dropKeptDraft(keepKey);
5657
+ if (editing && dirty) (0, import_drafts.keepDraft)(keepKey, keptFieldsOf(draft), { basedOn: item?.updatedAt ?? "new" });
5658
+ else if (!editing) (0, import_drafts.dropKeptDraft)(keepKey);
5682
5659
  }, [editing, dirty, draft, keepKey, item?.updatedAt]);
5683
5660
  (0, import_react27.useEffect)(() => {
5684
5661
  if (!editing || !item) return;
@@ -5715,7 +5692,7 @@ function ItemPane(props) {
5715
5692
  if (item) {
5716
5693
  const r = await port.save(item, definition, out);
5717
5694
  const [next, n] = await withOtp(r.item, r.notice);
5718
- dropKeptDraft(keepKey);
5695
+ (0, import_drafts.dropKeptDraft)(keepKey);
5719
5696
  onSaved(next, false, n);
5720
5697
  } else if (definition && owner === "person") {
5721
5698
  const secretKey = declared.find((f) => f.storage === "encrypted" && f.kind === "secret")?.key ?? null;
@@ -5725,7 +5702,7 @@ function ItemPane(props) {
5725
5702
  } else if (definition) {
5726
5703
  const r = await port.create(definition, owner === "me" ? null : owner, out);
5727
5704
  const [next, n] = await withOtp(r.item, r.notice);
5728
- dropKeptDraft(keepKey);
5705
+ (0, import_drafts.dropKeptDraft)(keepKey);
5729
5706
  onSaved(next, true, n);
5730
5707
  }
5731
5708
  } catch (e) {
@@ -5764,7 +5741,7 @@ function ItemPane(props) {
5764
5741
  const viewCustom = (item?.custom ?? []).filter((c) => !declaredKeys.has(c.key) && c.key !== MFA_METHOD_KEY && !isAuthenticatorStorage(c.key));
5765
5742
  const isLogin = (item?.definitionKey ?? definition?.key) === "website_login" || (item?.definitionKey ?? definition?.key) === "username_password";
5766
5743
  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;
5744
+ 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
5745
  const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
5769
5746
  const descriptionVisible = showDescription || draft.description !== "";
5770
5747
  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 +5798,7 @@ function ItemPane(props) {
5821
5798
  "Send securely"
5822
5799
  ] }) : null,
5823
5800
  /* @__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" }),
5801
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.HistoryIcon, { className: "size-4" }),
5825
5802
  "Password history"
5826
5803
  ] }),
5827
5804
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenuItem, { onSelect: () => onPanel("activity"), children: [
@@ -5829,7 +5806,7 @@ function ItemPane(props) {
5829
5806
  "Activity"
5830
5807
  ] }),
5831
5808
  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" }),
5809
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(import_icons11.SettingsIcon, { className: "size-4" }),
5833
5810
  "Settings"
5834
5811
  ] }) : null,
5835
5812
  canManage ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
@@ -5849,8 +5826,8 @@ function ItemPane(props) {
5849
5826
  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
5827
  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
5828
  /* @__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)(
5829
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { children: [
5830
+ mode === "new" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(VaultRow, { label: "Save to", children: /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(
5854
5831
  import_controls21.OptionCombobox,
5855
5832
  {
5856
5833
  value: owner,
@@ -5871,7 +5848,7 @@ function ItemPane(props) {
5871
5848
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
5872
5849
  mode === "new" && owner === "person" ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5873
5850
  /* @__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
5851
+ 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
5852
  ] }) : null,
5876
5853
  declared.map((f) => {
5877
5854
  const existing = item?.fields.find((x) => x.key === f.key);
@@ -5891,7 +5868,7 @@ function ItemPane(props) {
5891
5868
  actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5892
5869
  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
5870
  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
5871
+ 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
5872
  ] })
5896
5873
  },
5897
5874
  f.key
@@ -5909,7 +5886,7 @@ function ItemPane(props) {
5909
5886
  removeLabel: `Delete ${f.label}`,
5910
5887
  actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5911
5888
  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}`) })
5889
+ /* @__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
5890
  ] })
5914
5891
  },
5915
5892
  f.id
@@ -5942,9 +5919,9 @@ function ItemPane(props) {
5942
5919
  /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator), item, port, onEnrolled: onChanged }),
5943
5920
  item && isLogin && !item.authenticator ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(TwoFactorMethodRow, { port, item, onChanged }) : null
5944
5921
  ] }),
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 }) }) }),
5922
+ /* @__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
5923
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(
5947
- Section,
5924
+ VaultSection,
5948
5925
  {
5949
5926
  title: "More",
5950
5927
  actions: /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_design_system16.DropdownMenu, { children: [
@@ -5978,7 +5955,7 @@ function ItemPane(props) {
5978
5955
  ),
5979
5956
  filesProps ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FilesSection, { ...filesProps, editing: true }) : null
5980
5957
  ] }) : item ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(import_jsx_runtime26.Fragment, { children: [
5981
- /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(Section, { children: [
5958
+ /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { children: [
5982
5959
  declared.map((f) => {
5983
5960
  if (f.storage === "metadata") {
5984
5961
  const v = metaValue(f.key);
@@ -5993,18 +5970,18 @@ function ItemPane(props) {
5993
5970
  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
5971
  !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
5972
  ] }),
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: [
5973
+ /* @__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" }) }),
5974
+ item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)(VaultSection, { title: "More", children: [
5998
5975
  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,
5976
+ 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
5977
  viewCustom.map((c) => /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
6001
5978
  ] }) : null,
6002
5979
  filesProps ? /* @__PURE__ */ (0, import_jsx_runtime26.jsx)(FilesSection, { ...filesProps, editing: false }) : null,
6003
5980
  /* @__PURE__ */ (0, import_jsx_runtime26.jsxs)("p", { className: (0, import_design_system17.cn)("px-1 text-xs text-muted-foreground"), children: [
6004
5981
  "Modified ",
6005
- (0, import_format4.formatAbsoluteDate)(item.updatedAt, DAY_FORMAT, ""),
5982
+ (0, import_format8.formatAbsoluteDate)(item.updatedAt, DAY_FORMAT, ""),
6006
5983
  " \xB7 Created ",
6007
- (0, import_format4.formatAbsoluteDate)(item.createdAt, DAY_FORMAT, "")
5984
+ (0, import_format8.formatAbsoluteDate)(item.createdAt, DAY_FORMAT, "")
6008
5985
  ] })
6009
5986
  ] }) : null }) })
6010
5987
  ] }) });
@@ -6120,7 +6097,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
6120
6097
  // src/lists/TrashView.tsx
6121
6098
  var import_react30 = require("react");
6122
6099
  var import_controls24 = require("@ai-matrx/design-system/controls");
6123
- var import_format5 = require("@ai-matrx/kit/format");
6100
+ var import_format9 = require("@ai-matrx/kit/format");
6124
6101
 
6125
6102
  // src/lists/logic.ts
6126
6103
  var ENTITY_TYPE = "credential_item";
@@ -6244,13 +6221,13 @@ function RestorePanel({ lists, item, restore, onClose }) {
6244
6221
  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
6222
  ] }),
6246
6223
  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." }) }),
6224
+ 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: [
6225
+ /* @__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") }) }),
6226
+ /* @__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") }) }),
6227
+ 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,
6228
+ /* @__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" }) }),
6229
+ 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
6230
+ ] }) : 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
6231
  error ? /* @__PURE__ */ (0, import_jsx_runtime28.jsx)("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
6255
6232
  ]
6256
6233
  }
@@ -6282,13 +6259,13 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6282
6259
  };
6283
6260
  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
6261
  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) => (
6262
+ /* @__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
6263
  // A list row, not a field row: the name gets the whole width (on a phone a label column
6287
6264
  // left "Vau…" for every row), the deletion date sits under it.
6288
6265
  /* @__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
6266
  /* @__PURE__ */ (0, import_jsx_runtime29.jsxs)("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6290
6267
  /* @__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 ") })
6268
+ /* @__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
6269
  ] }),
6293
6270
  /* @__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
6271
  ] }, item.id)
@@ -6302,6 +6279,7 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6302
6279
  var import_react31 = require("react");
6303
6280
  var import_design_system20 = require("@ai-matrx/design-system");
6304
6281
  var import_controls25 = require("@ai-matrx/design-system/controls");
6282
+ var import_icons12 = require("@ai-matrx/design-system/icons");
6305
6283
  var import_jsx_runtime30 = require("react/jsx-runtime");
6306
6284
  function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6307
6285
  const [search, setSearch] = (0, import_react31.useState)("");
@@ -6336,7 +6314,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6336
6314
  "aria-label": "Website address",
6337
6315
  inputMode: "url",
6338
6316
  autoFocus: true,
6339
- icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(GlobeGlyph, {})
6317
+ icon: /* @__PURE__ */ (0, import_jsx_runtime30.jsx)(import_icons12.GlobeIcon, {})
6340
6318
  }
6341
6319
  ),
6342
6320
  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 +6353,10 @@ var import_react32 = require("react");
6375
6353
  var import_confirm_opener10 = require("@ai-matrx/kit/confirm-opener");
6376
6354
  var import_design_system21 = require("@ai-matrx/design-system");
6377
6355
  var import_controls26 = require("@ai-matrx/design-system/controls");
6378
- var import_format7 = require("@ai-matrx/kit/format");
6356
+ var import_format11 = require("@ai-matrx/kit/format");
6379
6357
 
6380
6358
  // src/sharing/secure-link-logic.ts
6381
- var import_format6 = require("@ai-matrx/kit/format");
6359
+ var import_format10 = require("@ai-matrx/kit/format");
6382
6360
  var SECURE_RESOURCE_TYPE = "credential_item";
6383
6361
  var NOTE_MAX = 1e3;
6384
6362
  var CHANNEL_WORD = { email: "email", sms: "text" };
@@ -6416,7 +6394,7 @@ function carriedWords(keys, fields) {
6416
6394
  const known = new Map(fields.map((f) => [f.key, f.label]));
6417
6395
  return keys.map((k) => known.get(k) ?? fieldNames([k])).join(", ");
6418
6396
  }
6419
- var lifetimeWords = (minutes) => (0, import_format6.formatDurationMinutes)(minutes, { style: "long" });
6397
+ var lifetimeWords = (minutes) => (0, import_format10.formatDurationMinutes)(minutes, { style: "long" });
6420
6398
  function remedyOf(e) {
6421
6399
  const body = e?.serverDetail;
6422
6400
  if (!body || typeof body !== "object") return null;
@@ -6586,9 +6564,9 @@ function SecureLinkPanel({ item, port, onClose }) {
6586
6564
  ] }),
6587
6565
  children: [
6588
6566
  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)(
6567
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(VaultSection, { title: "Recipient", children: [
6568
+ /* @__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" }) }),
6569
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6592
6570
  import_controls26.Field,
6593
6571
  {
6594
6572
  type: "tel",
@@ -6604,8 +6582,8 @@ function SecureLinkPanel({ item, port, onClose }) {
6604
6582
  className: "w-full"
6605
6583
  }
6606
6584
  ) }),
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)(
6585
+ /* @__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" }) }),
6586
+ plan && !plan.same ? /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Link by", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(
6609
6587
  import_controls26.SegmentedControl,
6610
6588
  {
6611
6589
  "aria-label": "Send the link by",
@@ -6617,26 +6595,26 @@ function SecureLinkPanel({ item, port, onClose }) {
6617
6595
  ]
6618
6596
  }
6619
6597
  ) }) : 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
6598
+ 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
6599
  ] }),
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: [
6600
+ /* @__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
6601
  /* @__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
6602
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
6625
6603
  !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
6604
  ] }, 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: [
6605
+ /* @__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) }) }) }),
6606
+ options ? /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)(VaultSection, { title: "Link", children: [
6607
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Opens", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsx)("span", { className: "text-foreground", children: "Once" }) }),
6608
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Link expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
6631
6609
  "After ",
6632
6610
  lifetimeWords(options.linkMinutes)
6633
6611
  ] }) }),
6634
- /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(Row, { label: "Code expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
6612
+ /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(VaultRow, { label: "Code expires", children: /* @__PURE__ */ (0, import_jsx_runtime31.jsxs)("span", { className: "text-foreground", children: [
6635
6613
  "After ",
6636
6614
  lifetimeWords(options.codeMinutes)
6637
6615
  ] }) })
6638
6616
  ] }) : 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: [
6617
+ 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
6618
  /* @__PURE__ */ (0, import_jsx_runtime31.jsx)(import_controls26.Badge, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
6641
6619
  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
6620
  ] }, row.id)) }) : null
@@ -6645,7 +6623,7 @@ function SecureLinkPanel({ item, port, onClose }) {
6645
6623
  );
6646
6624
  }
6647
6625
  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, "");
6626
+ 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
6627
  const carried = row.fieldKeys.length ? carriedWords(row.fieldKeys, options?.fields ?? []) : "";
6650
6628
  return [when, carried].filter(Boolean).join(" \xB7 ");
6651
6629
  }
@@ -6654,7 +6632,7 @@ function sentMeta(row, options) {
6654
6632
  var import_react33 = require("react");
6655
6633
  var import_confirm_opener11 = require("@ai-matrx/kit/confirm-opener");
6656
6634
  var import_controls27 = require("@ai-matrx/design-system/controls");
6657
- var import_format8 = require("@ai-matrx/kit/format");
6635
+ var import_format12 = require("@ai-matrx/kit/format");
6658
6636
 
6659
6637
  // src/devices/logic.ts
6660
6638
  var PASSKEY_RP_ID = "aimatrx.com";
@@ -6778,19 +6756,19 @@ function DevicesPanel({ port, onClose }) {
6778
6756
  };
6779
6757
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
6780
6758
  /* @__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) => {
6759
+ /* @__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
6760
  const off = isRevoked(device);
6783
6761
  return /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6784
- Row,
6762
+ VaultRow,
6785
6763
  {
6786
6764
  label: off ? "Turned off" : "Can fill",
6787
- hint: off ? (0, import_format8.formatAbsoluteDate)(device.revokedAt, DAY_FORMAT, "") : void 0,
6765
+ hint: off ? (0, import_format12.formatAbsoluteDate)(device.revokedAt, DAY_FORMAT, "") : void 0,
6788
6766
  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
6767
  children: /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)("span", { className: "flex min-w-0 flex-col", children: [
6790
6768
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: off ? "truncate text-muted-foreground" : "truncate text-foreground", children: device.label }),
6791
6769
  /* @__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, "")}` : ""
6770
+ device.lastUsedAt ? `Last used ${(0, import_format12.formatAbsoluteDate)(device.lastUsedAt, void 0, "")}` : "Never used",
6771
+ device.addedAt ? ` \xB7 added ${(0, import_format12.formatAbsoluteDate)(device.addedAt, DAY_FORMAT, "")}` : ""
6794
6772
  ] })
6795
6773
  ] })
6796
6774
  },
@@ -6869,29 +6847,29 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6869
6847
  /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(import_controls27.Button, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
6870
6848
  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
6849
  ] });
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: [
6850
+ 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
6851
  "This link names no key. Start again from ",
6874
6852
  where,
6875
6853
  "."
6876
6854
  ] }) }) : /* @__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) }) })
6855
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(VaultSection, { title: "What is asking", children: [
6856
+ /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
6857
+ name ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(VaultRow, { label: "Name", children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "block truncate", children: name }) }) : null,
6858
+ /* @__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
6859
  ] }),
6882
6860
  /* @__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: [
6861
+ /* @__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
6862
  "Return to ",
6885
6863
  where,
6886
6864
  " by ",
6887
- (0, import_format8.formatAbsoluteDate)(approvedUntil, void 0, ""),
6865
+ (0, import_format12.formatAbsoluteDate)(approvedUntil, void 0, ""),
6888
6866
  "."
6889
6867
  ] }) }) : !passkeys ? /* @__PURE__ */ (0, import_jsx_runtime32.jsxs)(Empty, { children: [
6890
6868
  "Approve with your password in ",
6891
6869
  where,
6892
6870
  "."
6893
6871
  ] }) : !here ? /* @__PURE__ */ (0, import_jsx_runtime32.jsx)(
6894
- Row,
6872
+ VaultRow,
6895
6873
  {
6896
6874
  label: "Passkey",
6897
6875
  hint: `Passkeys work only on ${passkeys.rpId}`,
@@ -6899,14 +6877,14 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6899
6877
  children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-muted-foreground", children: "Not on this page" })
6900
6878
  }
6901
6879
  ) : 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,
6880
+ VaultRow,
6903
6881
  {
6904
6882
  label: "Passkey",
6905
6883
  hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
6906
6884
  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
6885
  children: /* @__PURE__ */ (0, import_jsx_runtime32.jsx)("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
6908
6886
  }
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" }) }) })
6887
+ ) : /* @__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
6888
  ] }) });
6911
6889
  }
6912
6890
 
@@ -7184,7 +7162,7 @@ var TONE = {
7184
7162
  };
7185
7163
  function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
7186
7164
  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." }) }) });
7165
+ 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
7166
  }
7189
7167
  return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
7190
7168
  }
@@ -7231,25 +7209,25 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7231
7209
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "primary", onClick: onClose, children: "Done" })
7232
7210
  ] }) : /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(import_controls28.Button, { variant: "quiet", onClick: onClose, children: "Close" });
7233
7211
  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" }) })
7212
+ screen.kind === "idle" ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(VaultSection, { children: [
7213
+ /* @__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 }) }),
7214
+ /* @__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" }) }),
7215
+ /* @__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
7216
  ] }) : null,
7239
- preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Section, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7217
+ preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(
7240
7218
  Windowed,
7241
7219
  {
7242
7220
  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)
7221
+ 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
7222
  }
7245
7223
  ) }) : 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
7224
+ status && !preview ? /* @__PURE__ */ (0, import_jsx_runtime33.jsxs)(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
7225
+ /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(VaultRow, { label: "Imported", children: /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("span", { className: "text-foreground", children: status.committed }) }),
7226
+ /* @__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 }) }),
7227
+ /* @__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 }) }),
7228
+ /* @__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 }) }),
7229
+ 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,
7230
+ 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
7231
  ] }) : null,
7254
7232
  screen.message ? /* @__PURE__ */ (0, import_jsx_runtime33.jsx)("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
7255
7233
  /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(ErrorLine, { message: limitError })
@@ -7260,6 +7238,7 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7260
7238
  var import_react39 = require("react");
7261
7239
  var import_design_system23 = require("@ai-matrx/design-system");
7262
7240
  var import_controls32 = require("@ai-matrx/design-system/controls");
7241
+ var import_icons14 = require("@ai-matrx/design-system/icons");
7263
7242
 
7264
7243
  // src/extension/CaptureCard.tsx
7265
7244
  var import_react36 = require("react");
@@ -7402,6 +7381,7 @@ function FillSetupCard({ fillSetup }) {
7402
7381
  var import_react38 = require("react");
7403
7382
  var import_design_system22 = require("@ai-matrx/design-system");
7404
7383
  var import_controls31 = require("@ai-matrx/design-system/controls");
7384
+ var import_icons13 = require("@ai-matrx/design-system/icons");
7405
7385
  var import_jsx_runtime36 = require("react/jsx-runtime");
7406
7386
  var HOLD_MS = 6e4;
7407
7387
  function PageGenerator({ fields }) {
@@ -7455,11 +7435,11 @@ function PageGenerator({ fields }) {
7455
7435
  const value = held.value;
7456
7436
  return /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_jsx_runtime36.Fragment, { children: [
7457
7437
  /* @__PURE__ */ (0, import_jsx_runtime36.jsx)(
7458
- Row,
7438
+ VaultRow,
7459
7439
  {
7460
7440
  label: "New password",
7461
7441
  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,
7442
+ 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
7443
  /* @__PURE__ */ (0, import_jsx_runtime36.jsxs)(import_design_system22.Popover, { open, onOpenChange: setOpen, children: [
7464
7444
  /* @__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
7445
  /* @__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 +7448,7 @@ function PageGenerator({ fields }) {
7468
7448
  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
7449
  }
7470
7450
  ),
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
7451
+ 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
7452
  ] });
7473
7453
  }
7474
7454
 
@@ -7530,7 +7510,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7530
7510
  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
7511
  header,
7532
7512
  /* @__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" }),
7513
+ /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_design_system23.SiteIcon, { site: page.url, fallback: import_icons14.GlobeIcon, className: "size-4" }),
7534
7514
  /* @__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
7515
  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
7516
  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 +7518,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7538
7518
  fillSetup ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(FillSetupCard, { fillSetup }) : null,
7539
7519
  capture ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(CaptureCard, { capture, onChanged }) : null,
7540
7520
  /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
7541
- Section,
7521
+ VaultSection,
7542
7522
  {
7543
7523
  title: "This site",
7544
7524
  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 +7526,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7546
7526
  }
7547
7527
  ),
7548
7528
  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
7529
+ newPasswordFields && canSave ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(VaultSection, { children: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(PageGenerator, { fields: newPasswordFields }) }) : null
7550
7530
  ] }) });
7551
7531
  }
7552
7532
  function Outcome({ said, onDismiss }) {
@@ -7608,6 +7588,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
7608
7588
  var import_react40 = require("react");
7609
7589
  var import_design_system24 = require("@ai-matrx/design-system");
7610
7590
  var import_controls33 = require("@ai-matrx/design-system/controls");
7591
+ var import_icons15 = require("@ai-matrx/design-system/icons");
7611
7592
  var import_jsx_runtime38 = require("react/jsx-runtime");
7612
7593
  function vaultChoices(items, organizations, current) {
7613
7594
  const n = (f) => items.filter(f).length;
@@ -7623,7 +7604,7 @@ function vaultChoices(items, organizations, current) {
7623
7604
  function VaultSelect({ value, choices, onChange }) {
7624
7605
  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
7606
  }
7626
- var CATEGORY_GLYPHS = { logins: GlobeGlyph, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
7607
+ var CATEGORY_GLYPHS = { logins: import_icons15.GlobeIcon, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
7627
7608
  var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
7628
7609
  function itemCategory(item, definitions) {
7629
7610
  return categoryOf(item.definitionKey, familyOf(item.definitionKey, definitions));
@@ -7688,7 +7669,7 @@ function Group({ title, children }) {
7688
7669
  children
7689
7670
  ] });
7690
7671
  }
7691
- function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
7672
+ function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
7692
7673
  const [tagsOpen, setTagsOpen] = (0, import_react40.useState)(view.startsWith("tag:"));
7693
7674
  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
7675
  /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
@@ -7697,7 +7678,7 @@ function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views,
7697
7678
  ] }),
7698
7679
  /* @__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
7680
  /* @__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,
7681
+ hasPage ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "page", glyph: import_icons15.GlobeIcon, label: "This page", onClick: () => onView("page") }) : null,
7701
7682
  /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
7702
7683
  hasFavorites ? /* @__PURE__ */ (0, import_jsx_runtime38.jsx)(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
7703
7684
  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 +7718,7 @@ var NO_HOST = {};
7737
7718
  var ITEM_PANELS = {
7738
7719
  share: SharePanel,
7739
7720
  move: MovePanel,
7740
- history: HistoryPanel,
7721
+ history: ItemHistoryPanel,
7741
7722
  activity: ActivityPanel,
7742
7723
  settings: ItemSettingsPanel,
7743
7724
  field: FieldSettingsPanel,
@@ -8128,7 +8109,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8128
8109
  ] }) : null,
8129
8110
  /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
8130
8111
  mode === "full" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(
8131
- Sidebar,
8112
+ VaultSidebar,
8132
8113
  {
8133
8114
  vault: loc.vault,
8134
8115
  choices,
@@ -8869,7 +8850,7 @@ function createApiVaultPort(api, options = {}) {
8869
8850
  lists.forEach((l, i) => {
8870
8851
  const sharedList = i === lists.length - 1;
8871
8852
  for (const w of l.items) {
8872
- if (seen.has(w.id) || deleted.has(w.id)) continue;
8853
+ if (seen.has(w.id) || deleted.has(w.id) || isHiddenItem(w)) continue;
8873
8854
  const owner = sharedList ? orgOf(w.organization_id, null, false) : orgOf(w.organization_id, w.user_id, i === 0);
8874
8855
  const item = itemOf(w, sharedList && !w.organization_id ? { kind: "shared", label: "Shared with me", organizationId: null } : owner, defs, auth);
8875
8856
  (isDeleted(w) ? deleted : seen).set(w.id, item);