@ai-matrx/vault 0.1.15 → 0.1.17

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -101,10 +101,10 @@ var init_keepass_xml_worker_client = __esm({
101
101
  });
102
102
 
103
103
  // src/VaultApp.tsx
104
- import { useCallback as useCallback5, useEffect as useEffect23, useMemo as useMemo6, useRef as useRef19, useState as useState40 } from "react";
105
- import { DropdownMenu as DropdownMenu6, DropdownMenuContent as DropdownMenuContent6, DropdownMenuItem as DropdownMenuItem5, DropdownMenuTrigger as DropdownMenuTrigger6, LookScope } from "@ai-matrx/design-system";
106
- import { Button as Button33, SearchField as SearchField4, Select as Select11 } from "@ai-matrx/design-system/controls";
107
- import { confirm as confirm13 } from "@ai-matrx/kit/confirm-opener";
104
+ import { useCallback as useCallback5, useEffect as useEffect23, useMemo as useMemo6, useRef as useRef19, useState as useState41 } from "react";
105
+ import { DropdownMenu as DropdownMenu6, DropdownMenuContent as DropdownMenuContent6, DropdownMenuItem as DropdownMenuItem6, DropdownMenuTrigger as DropdownMenuTrigger6, LookScope } from "@ai-matrx/design-system";
106
+ import { Button as Button34, SearchField as SearchField4, Select as Select12 } from "@ai-matrx/design-system/controls";
107
+ import { confirm as confirm14 } from "@ai-matrx/kit/confirm-opener";
108
108
 
109
109
  // src/notice.tsx
110
110
  import { createContext, useCallback, useContext, useEffect, useRef, useState } from "react";
@@ -638,12 +638,12 @@ var ROW_GRID = {
638
638
  roomy: "grid-cols-[9rem_minmax(0,1fr)_auto] gap-x-3 px-4",
639
639
  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"
640
640
  };
641
- function VaultRow({ label, hint, children, actions, top = false, className }) {
641
+ function VaultRow({ label, hint: hint2, children, actions, top = false, className }) {
642
642
  const room = useContext4(Room);
643
643
  return /* @__PURE__ */ jsxs4("div", { className: cn2("grid min-h-11 py-1", ROW_GRID[room ?? "viewport"], top ? "items-start" : "items-center", className), children: [
644
644
  /* @__PURE__ */ jsxs4("div", { className: cn2("flex min-w-0 flex-col text-xs leading-tight text-muted-foreground", top && "pt-2.5"), children: [
645
645
  /* @__PURE__ */ jsx4("span", { className: room === "roomy" ? "truncate" : room === "compact" ? "line-clamp-2 break-words" : "line-clamp-2 break-words sm:truncate", children: label }),
646
- hint ? /* @__PURE__ */ jsx4("span", { className: "line-clamp-2 break-words text-xs text-disabled-foreground", children: hint }) : null
646
+ hint2 ? /* @__PURE__ */ jsx4("span", { className: "line-clamp-2 break-words text-xs text-disabled-foreground", children: hint2 }) : null
647
647
  ] }),
648
648
  /* @__PURE__ */ jsx4("div", { className: cn2("min-w-0 text-sm", top && "py-1.5"), children }),
649
649
  /* @__PURE__ */ jsx4("div", { className: cn2("flex items-center gap-0.5", top && "pt-1"), children: actions })
@@ -753,14 +753,14 @@ function TurnOnButton({ label, onTurnOn }) {
753
753
  }
754
754
  );
755
755
  }
756
- function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
756
+ function PlainRow({ label, value, hint: hint2, openUrl, extra, multiline = false }) {
757
757
  const copyValue2 = useCopy();
758
758
  const isUrl = /^https?:\/\//i.test(value);
759
759
  return /* @__PURE__ */ jsx5(
760
760
  VaultRow,
761
761
  {
762
762
  label,
763
- hint,
763
+ hint: hint2,
764
764
  top: multiline,
765
765
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
766
766
  extra,
@@ -790,13 +790,13 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
790
790
  function AddRow({ label, onAdd, children = "Add" }) {
791
791
  return /* @__PURE__ */ jsx5(VaultRow, { label, children: onAdd ? /* @__PURE__ */ jsx5("button", { type: "button", className: "text-sm text-muted-foreground hover:text-primary", onClick: onAdd, children }) : /* @__PURE__ */ jsx5("span", { className: "text-disabled-foreground", children: "\u2014" }) });
792
792
  }
793
- function EditRow({ label, hint, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
793
+ function EditRow({ label, hint: hint2, value, onChange, placeholder, secret = false, multiline = false, onRemove, removeLabel, actions, autoFocus, onBlur, inputMode }) {
794
794
  const [shown, setShown] = useState5(false);
795
795
  return /* @__PURE__ */ jsx5(
796
796
  VaultRow,
797
797
  {
798
798
  label,
799
- hint,
799
+ hint: hint2,
800
800
  top: multiline,
801
801
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
802
802
  secret && value ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: shown ? /* @__PURE__ */ jsx5(EyeOffGlyph, {}) : /* @__PURE__ */ jsx5(EyeGlyph, {}), "aria-label": shown ? "Hide" : "Show", onClick: () => setShown((s) => !s) }) : null,
@@ -807,7 +807,7 @@ function EditRow({ label, hint, value, onChange, placeholder, secret = false, mu
807
807
  }
808
808
  );
809
809
  }
810
- function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
810
+ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove, extra, onPasteValue }) {
811
811
  const [shown, setShown] = useState5(false);
812
812
  return /* @__PURE__ */ jsx5(
813
813
  VaultRow,
@@ -815,9 +815,25 @@ function CustomEditRow({ label, value, onLabel, onValue, secret, onRemove }) {
815
815
  label: /* @__PURE__ */ jsx5(Field2, { className: "w-full", value: label, onChange: (e) => onLabel(e.target.value), placeholder: "Name", "aria-label": "Field name" }),
816
816
  actions: /* @__PURE__ */ jsxs5(Fragment2, { children: [
817
817
  secret && value ? /* @__PURE__ */ jsx5(Button2, { variant: "quiet", icon: shown ? /* @__PURE__ */ jsx5(EyeOffGlyph, {}) : /* @__PURE__ */ jsx5(EyeGlyph, {}), "aria-label": shown ? "Hide" : "Show", onClick: () => setShown((x) => !x) }) : null,
818
+ extra,
818
819
  /* @__PURE__ */ jsx5(Button2, { variant: "quiet", removes: true, icon: /* @__PURE__ */ jsx5(XGlyph, {}), "aria-label": "Remove field", onClick: onRemove })
819
820
  ] }),
820
- children: /* @__PURE__ */ jsx5(Field2, { className: "w-full", value, onChange: (e) => onValue(e.target.value), type: secret && !shown ? "password" : "text", placeholder: secret ? "Secret value" : "Value", autoComplete: "off", spellCheck: false, "aria-label": "Field value" })
821
+ children: /* @__PURE__ */ jsx5(
822
+ Field2,
823
+ {
824
+ className: "w-full",
825
+ value,
826
+ onChange: (e) => onValue(e.target.value),
827
+ onPaste: onPasteValue ? (e) => {
828
+ if (onPasteValue(e.clipboardData.getData("text"))) e.preventDefault();
829
+ } : void 0,
830
+ type: secret && !shown ? "password" : "text",
831
+ placeholder: secret ? "Secret value" : "Value",
832
+ autoComplete: "off",
833
+ spellCheck: false,
834
+ "aria-label": label ? `${label} value` : "Field value"
835
+ }
836
+ )
821
837
  }
822
838
  );
823
839
  }
@@ -831,7 +847,7 @@ import { formatRelativeTime } from "@ai-matrx/kit/format";
831
847
 
832
848
  // src/model.ts
833
849
  var DEFAULT_LOCATION = { vault: "all", view: "all", q: "", sort: "name", itemId: null, mode: "view", kind: null, url: "", panel: null };
834
- var SORTS = ["name", "website", "updated", "created"];
850
+ var SORTS = ["name", "name-desc", "website", "updated", "created", "viewed"];
835
851
  function locationFromParams(params, itemId = params.get("item")) {
836
852
  const sort = params.get("sort");
837
853
  const mode = params.get("mode");
@@ -901,10 +917,15 @@ function siteDomainOf(host) {
901
917
  const keep = TWO_PART_SUFFIX.has(sld) && tld.length <= 3 ? 3 : 2;
902
918
  return labels.slice(-keep).join(".");
903
919
  }
904
- function sortItems(items, sort) {
920
+ function sortItems(items, sort, recents) {
905
921
  const out = [...items];
906
- const byName = (a, b) => a.name.localeCompare(b.name, void 0, { sensitivity: "base" });
922
+ const byName = (a, b) => a.name.localeCompare(b.name, void 0, { sensitivity: "base", numeric: true });
907
923
  if (sort === "name") return out.sort(byName);
924
+ if (sort === "name-desc") return out.sort((a, b) => byName(b, a));
925
+ if (sort === "viewed") {
926
+ const at = new Map((recents ?? []).map((id, i) => [id, i]));
927
+ return out.sort((a, b) => (at.get(a.id) ?? Infinity) - (at.get(b.id) ?? Infinity) || byName(a, b));
928
+ }
908
929
  if (sort === "website")
909
930
  return out.sort((a, b) => {
910
931
  const x = loginSiteOf(a), y = loginSiteOf(b);
@@ -2140,7 +2161,7 @@ function TotpEditRow({ value, onChange, hasExisting, item, port, onEnrolled, onR
2140
2161
  setStatus(null);
2141
2162
  onChange(v);
2142
2163
  },
2143
- placeholder: hasExisting ? "Paste a new key to replace" : "Setup key or otpauth link",
2164
+ placeholder: hasExisting ? "Paste a new key to replace" : "Paste setup key or otpauth link",
2144
2165
  status,
2145
2166
  ...uploadImage ? { onImage: (f) => void uploadImage(f) } : {},
2146
2167
  ...onRecognized ? { onRecognized } : {}
@@ -2596,6 +2617,18 @@ function withoutCode(codes, index) {
2596
2617
  const left = codes.filter((_, i) => i !== index);
2597
2618
  return left.length ? left.join("\n") : null;
2598
2619
  }
2620
+ function parseEnvAssignment(text) {
2621
+ const m = /^\s*(?:export\s+)?([A-Za-z_][A-Za-z0-9_]*)\s*=(.*)$/s.exec(text.trim());
2622
+ if (!m || /\n/.test(m[2] ?? "")) return null;
2623
+ let value = (m[2] ?? "").trim();
2624
+ const q = value[0];
2625
+ if ((q === '"' || q === "'") && value.length >= 2 && value.endsWith(q)) value = value.slice(1, -1);
2626
+ return value ? { key: m[1] ?? "", value } : null;
2627
+ }
2628
+ function labelFromEnvKey(key) {
2629
+ const words = key.toLowerCase().split(/[_\s]+/).filter(Boolean).join(" ");
2630
+ return words ? words.charAt(0).toUpperCase() + words.slice(1) : key;
2631
+ }
2599
2632
 
2600
2633
  // src/fields/SettingsPanels.tsx
2601
2634
  import { jsx as jsx14, jsxs as jsxs13 } from "react/jsx-runtime";
@@ -2993,11 +3026,11 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
2993
3026
  /* @__PURE__ */ jsx15(Button11, { variant: "primary", disabled: !candidate, onClick: use, children: useLabel })
2994
3027
  ] });
2995
3028
  }
2996
- function OptionLine({ label, hint, children }) {
3029
+ function OptionLine({ label, hint: hint2, children }) {
2997
3030
  return /* @__PURE__ */ jsxs14("div", { className: "flex min-h-9 items-center justify-between gap-3", children: [
2998
3031
  /* @__PURE__ */ jsxs14("div", { className: "flex min-w-0 flex-col", children: [
2999
3032
  /* @__PURE__ */ jsx15("span", { className: "truncate text-sm text-foreground", children: label }),
3000
- hint ? /* @__PURE__ */ jsx15("span", { className: "truncate text-xs text-muted-foreground", children: hint }) : null
3033
+ hint2 ? /* @__PURE__ */ jsx15("span", { className: "truncate text-xs text-muted-foreground", children: hint2 }) : null
3001
3034
  ] }),
3002
3035
  /* @__PURE__ */ jsx15("div", { className: "flex shrink-0 items-center", children })
3003
3036
  ] });
@@ -4720,17 +4753,18 @@ function Notices({ draft }) {
4720
4753
  }
4721
4754
 
4722
4755
  // src/ItemList.tsx
4723
- import { useEffect as useEffect17, useRef as useRef15, useState as useState27 } from "react";
4724
- import { DropdownMenu as DropdownMenu4, DropdownMenuContent as DropdownMenuContent4, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuTrigger as DropdownMenuTrigger4 } from "@ai-matrx/design-system";
4756
+ import { useEffect as useEffect17, useRef as useRef15, useState as useState28 } from "react";
4757
+ import { DropdownMenu as DropdownMenu4, DropdownMenuContent as DropdownMenuContent4, DropdownMenuItem as DropdownMenuItem4, DropdownMenuRadioGroup, DropdownMenuRadioItem, DropdownMenuSeparator as DropdownMenuSeparator4, DropdownMenuTrigger as DropdownMenuTrigger4 } from "@ai-matrx/design-system";
4725
4758
  import { cn as cn13 } from "@ai-matrx/design-system";
4726
- import { Button as Button22, SearchField } from "@ai-matrx/design-system/controls";
4759
+ import { Button as Button23, SearchField } from "@ai-matrx/design-system/controls";
4760
+ import { CopyIcon as CopyIcon7 } from "@ai-matrx/design-system/icons";
4727
4761
 
4728
4762
  // src/ItemPane.tsx
4729
- import { useEffect as useEffect16, useMemo as useMemo3, useRef as useRef14, useState as useState26 } from "react";
4763
+ import { useEffect as useEffect16, useMemo as useMemo3, useRef as useRef14, useState as useState27 } from "react";
4730
4764
  import { DropdownMenu as DropdownMenu3, DropdownMenuContent as DropdownMenuContent3, DropdownMenuItem as DropdownMenuItem3, DropdownMenuSeparator as DropdownMenuSeparator3, DropdownMenuTrigger as DropdownMenuTrigger3 } from "@ai-matrx/design-system";
4731
4765
  import { cn as cn12 } from "@ai-matrx/design-system";
4732
- import { Badge as Badge7, Button as Button21, CONTROLS_CONTAINER_CLASS, OptionCombobox, Switch as Switch5 } from "@ai-matrx/design-system/controls";
4733
- import { confirm as confirm9 } from "@ai-matrx/kit/confirm-opener";
4766
+ import { Badge as Badge7, Button as Button22, CONTROLS_CONTAINER_CLASS, OptionCombobox, Switch as Switch6 } from "@ai-matrx/design-system/controls";
4767
+ import { confirm as confirm10 } from "@ai-matrx/kit/confirm-opener";
4734
4768
 
4735
4769
  // src/activity/FilesSection.tsx
4736
4770
  import { formatFileSize as formatFileSize2 } from "@ai-matrx/kit/format";
@@ -4751,12 +4785,13 @@ var PROTECTION = [
4751
4785
  function FilesSection({ item, port, editing, onChanged }) {
4752
4786
  const confirmed = useConfirmed();
4753
4787
  const canEdit = editing && item.capabilities.canEdit;
4788
+ const canAdd = item.capabilities.canEdit;
4754
4789
  const [busy, setBusy] = useState20(null);
4755
4790
  const [error, setError] = useState20(null);
4756
4791
  const [pending, setPending] = useState20(null);
4757
4792
  const [dragging, setDragging] = useState20(false);
4758
4793
  const picker = useRef13(null);
4759
- if (!canEdit && item.attachments.length === 0) return null;
4794
+ if (!canAdd && item.attachments.length === 0) return null;
4760
4795
  async function run(key, work, fallback) {
4761
4796
  setBusy(key);
4762
4797
  setError(null);
@@ -4778,7 +4813,7 @@ function FilesSection({ item, port, editing, onChanged }) {
4778
4813
  setPending(file);
4779
4814
  }
4780
4815
  function drop(e) {
4781
- if (!canEdit) return;
4816
+ if (!canAdd) return;
4782
4817
  e.preventDefault();
4783
4818
  setDragging(false);
4784
4819
  choose(e.dataTransfer.files[0]);
@@ -4791,22 +4826,23 @@ function FilesSection({ item, port, editing, onChanged }) {
4791
4826
  "div",
4792
4827
  {
4793
4828
  className: cn9("rounded-xl", dragging && "outline outline-2 outline-primary"),
4794
- onDragOver: canEdit ? (e) => {
4829
+ onDragOver: canAdd ? (e) => {
4795
4830
  e.preventDefault();
4796
4831
  setDragging(true);
4797
4832
  } : void 0,
4798
- onDragLeave: canEdit ? () => setDragging(false) : void 0,
4799
- onDrop: canEdit ? drop : void 0,
4833
+ onDragLeave: canAdd ? () => setDragging(false) : void 0,
4834
+ onDrop: canAdd ? drop : void 0,
4800
4835
  children: /* @__PURE__ */ jsxs19(
4801
4836
  VaultSection,
4802
4837
  {
4803
- title: "Files",
4804
- actions: canEdit ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
4838
+ title: editing || item.attachments.length > 0 || pending ? "Files" : void 0,
4839
+ actions: canAdd && (editing || item.attachments.length > 0) ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PlusGlyph, {}), disabled: busy !== null, onClick: () => picker.current?.click(), children: "Add file" }) : void 0,
4805
4840
  children: [
4806
- canEdit ? /* @__PURE__ */ jsx20("input", { ref: picker, type: "file", hidden: true, onChange: (e) => {
4841
+ canAdd ? /* @__PURE__ */ jsx20("input", { ref: picker, type: "file", hidden: true, "aria-label": "Choose a file", onChange: (e) => {
4807
4842
  choose(e.target.files?.[0]);
4808
4843
  e.target.value = "";
4809
4844
  } }) : null,
4845
+ !editing && canAdd && item.attachments.length === 0 && !pending ? /* @__PURE__ */ jsx20(AddRow, { label: "Files", onAdd: () => picker.current?.click(), children: "Add file" }) : null,
4810
4846
  item.attachments.map(
4811
4847
  (a) => canEdit ? /* @__PURE__ */ jsx20(EditableFile, { port, item, file: a, busy, run, onDownload: () => void download(a), onTooBig: () => setError(TOO_BIG) }, a.id) : /* @__PURE__ */ jsx20(
4812
4848
  VaultRow,
@@ -4819,7 +4855,7 @@ function FilesSection({ item, port, editing, onChanged }) {
4819
4855
  a.id
4820
4856
  )
4821
4857
  ),
4822
- canEdit && pending ? /* @__PURE__ */ jsx20(NewFile, { file: pending, busy: busy === "add", onCancel: () => setPending(null), onAdd: async (details) => {
4858
+ canAdd && pending ? /* @__PURE__ */ jsx20(NewFile, { file: pending, busy: busy === "add", onCancel: () => setPending(null), onAdd: async (details) => {
4823
4859
  if (await run("add", () => port.activity.addFile(item, pending, details), "The file could not be added.")) setPending(null);
4824
4860
  } }) : null,
4825
4861
  canEdit && item.attachments.length === 0 && !pending ? /* @__PURE__ */ jsx20("div", { className: "px-4 py-3 text-sm text-muted-foreground", children: "Drop a file here or choose Add file" }) : null,
@@ -4940,6 +4976,57 @@ function confirmSeal(label) {
4940
4976
  variant: "destructive"
4941
4977
  });
4942
4978
  }
4979
+ function DraftFilesSection({ files, onFiles }) {
4980
+ const [pending, setPending] = useState20(null);
4981
+ const [error, setError] = useState20(null);
4982
+ const [dragging, setDragging] = useState20(false);
4983
+ const picker = useRef13(null);
4984
+ const choose = (file) => {
4985
+ if (!file) return;
4986
+ if (fileTooBig(file.size)) return setError(TOO_BIG);
4987
+ setError(null);
4988
+ setPending(file);
4989
+ };
4990
+ return /* @__PURE__ */ jsx20(
4991
+ "div",
4992
+ {
4993
+ className: cn9("rounded-xl", dragging && "outline outline-2 outline-primary"),
4994
+ onDragOver: (e) => {
4995
+ e.preventDefault();
4996
+ setDragging(true);
4997
+ },
4998
+ onDragLeave: () => setDragging(false),
4999
+ onDrop: (e) => {
5000
+ e.preventDefault();
5001
+ setDragging(false);
5002
+ choose(e.dataTransfer.files[0]);
5003
+ },
5004
+ children: /* @__PURE__ */ jsxs19(VaultSection, { title: files.length > 0 || pending ? "Files" : void 0, actions: files.length > 0 ? /* @__PURE__ */ jsx20(Button16, { variant: "quiet", icon: /* @__PURE__ */ jsx20(PlusGlyph, {}), onClick: () => picker.current?.click(), children: "Add file" }) : void 0, children: [
5005
+ /* @__PURE__ */ jsx20("input", { ref: picker, type: "file", hidden: true, "aria-label": "Choose a file", onChange: (e) => {
5006
+ choose(e.target.files?.[0]);
5007
+ e.target.value = "";
5008
+ } }),
5009
+ files.map((f, i) => /* @__PURE__ */ jsx20(VaultRow, { label: f.label, hint: f.description ?? void 0, actions: /* @__PURE__ */ jsx20(Button16, { variant: "quiet", removes: true, icon: /* @__PURE__ */ jsx20(XGlyph, {}), "aria-label": `Remove ${f.label}`, onClick: () => onFiles(files.filter((_, j) => j !== i)) }), children: /* @__PURE__ */ jsxs19("span", { className: "flex min-w-0 items-center gap-2", children: [
5010
+ /* @__PURE__ */ jsx20("span", { className: "truncate", children: f.file.name }),
5011
+ /* @__PURE__ */ jsx20("span", { className: "shrink-0 text-xs text-muted-foreground", children: formatFileSize2(f.file.size) })
5012
+ ] }) }, `${f.file.name}-${i}`)),
5013
+ pending ? /* @__PURE__ */ jsx20(
5014
+ NewFile,
5015
+ {
5016
+ file: pending,
5017
+ busy: false,
5018
+ onCancel: () => setPending(null),
5019
+ onAdd: async (d) => {
5020
+ onFiles([...files, { file: pending, ...d }]);
5021
+ setPending(null);
5022
+ }
5023
+ }
5024
+ ) : files.length === 0 ? /* @__PURE__ */ jsx20(AddRow, { label: "Files", onAdd: () => picker.current?.click(), children: "Add file" }) : null,
5025
+ error ? /* @__PURE__ */ jsx20("p", { role: "alert", className: "px-4 py-2 text-sm text-destructive", children: error }) : null
5026
+ ] })
5027
+ }
5028
+ );
5029
+ }
4943
5030
 
4944
5031
  // src/fields/RecoveryCodesRow.tsx
4945
5032
  import { useState as useState21 } from "react";
@@ -5047,6 +5134,134 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
5047
5134
  );
5048
5135
  }
5049
5136
 
5137
+ // src/fields/DraftRows.tsx
5138
+ import { useState as useState22 } from "react";
5139
+ import { Button as Button18, Field as Field8, SegmentedControl as SegmentedControl5, Select as Select7, Switch as Switch5 } from "@ai-matrx/design-system/controls";
5140
+ import { RecordId } from "@ai-matrx/design-system";
5141
+ import { confirm as confirm7 } from "@ai-matrx/kit/confirm-opener";
5142
+ import { Fragment as Fragment15, jsx as jsx22, jsxs as jsxs21 } from "react/jsx-runtime";
5143
+ var HANDLINGS = ["visible", "revealable", "sealed"];
5144
+ var hint = (text, tone = "muted") => /* @__PURE__ */ jsx22("span", { className: tone === "destructive" ? "text-destructive" : void 0, title: text, children: text });
5145
+ var hasSecretSettings = (s) => Boolean(s.envKey?.trim() || s.injectIntoSandbox || s.handling && s.handling !== "revealable");
5146
+ function SecretBuilderRow({ field, onChange, onRemove }) {
5147
+ const [open, setOpen] = useState22(hasSecretSettings(field));
5148
+ const env = field.envKey ?? "";
5149
+ const envProblem = envKeyProblem(env);
5150
+ const envOk = env.trim() !== "" && !envProblem;
5151
+ const handling = field.handling ?? "revealable";
5152
+ const name = field.label.trim() || "Secret";
5153
+ const chooseHandling = async (next) => {
5154
+ if (next === handling) return;
5155
+ if (next === "sealed") {
5156
+ const ok = await confirm7({
5157
+ title: `Seal ${name} permanently?`,
5158
+ description: "Once saved, no person can see or copy it again; only automation can use it.",
5159
+ confirmLabel: "Seal",
5160
+ variant: "destructive"
5161
+ });
5162
+ if (!ok) return;
5163
+ }
5164
+ onChange({ handling: next });
5165
+ };
5166
+ return /* @__PURE__ */ jsxs21(Fragment15, { children: [
5167
+ /* @__PURE__ */ jsx22(
5168
+ CustomEditRow,
5169
+ {
5170
+ label: field.label,
5171
+ value: field.value,
5172
+ secret: true,
5173
+ onLabel: (v) => onChange({ label: v }),
5174
+ onValue: (v) => onChange({ value: v }),
5175
+ onRemove,
5176
+ onPasteValue: (text) => {
5177
+ const a = parseEnvAssignment(text);
5178
+ if (!a) return false;
5179
+ onChange({ envKey: a.key, value: a.value, ...field.label.trim() ? {} : { label: labelFromEnvKey(a.key) } });
5180
+ setOpen(true);
5181
+ return true;
5182
+ },
5183
+ extra: /* @__PURE__ */ jsxs21(Fragment15, { children: [
5184
+ handling !== "sealed" ? /* @__PURE__ */ jsx22(GenerateButton, { onUse: (v) => onChange({ value: v }) }) : null,
5185
+ /* @__PURE__ */ jsx22(Button18, { variant: "quiet", icon: /* @__PURE__ */ jsx22(SlidersGlyph, {}), "aria-label": `${name} settings`, pressed: open, onClick: () => setOpen((o) => !o) })
5186
+ ] })
5187
+ }
5188
+ ),
5189
+ open ? /* @__PURE__ */ jsxs21(Fragment15, { children: [
5190
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Env key", hint: envProblem ? hint(envProblem, "destructive") : hint("The name sandboxes and workflows use"), children: /* @__PURE__ */ jsx22(
5191
+ Field8,
5192
+ {
5193
+ className: "w-full font-mono",
5194
+ "aria-label": `${name} env key`,
5195
+ "aria-invalid": Boolean(envProblem),
5196
+ placeholder: "e.g. GITHUB_TOKEN",
5197
+ autoComplete: "off",
5198
+ spellCheck: false,
5199
+ value: env,
5200
+ onChange: (e) => onChange({ envKey: e.target.value, ...e.target.value.trim() ? {} : { injectIntoSandbox: false } })
5201
+ }
5202
+ ) }),
5203
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Who can see it", hint: hint(HANDLING_WORDS[handling].hint), children: /* @__PURE__ */ jsx22(
5204
+ SegmentedControl5,
5205
+ {
5206
+ "aria-label": `Who can see ${name}`,
5207
+ value: handling,
5208
+ onValueChange: (v) => void chooseHandling(v),
5209
+ data: HANDLINGS.map((h) => ({ value: h, label: HANDLING_WORDS[h].label, title: HANDLING_WORDS[h].hint }))
5210
+ }
5211
+ ) }),
5212
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Use in sandbox", hint: envOk ? hint("Sandboxes get it as an env variable") : hint("Needs an env key"), children: /* @__PURE__ */ jsx22(Switch5, { "aria-label": `Use ${name} in sandbox`, checked: envOk && field.injectIntoSandbox === true, disabled: !envOk, onCheckedChange: (v) => onChange({ injectIntoSandbox: v }) }) })
5213
+ ] }) : null
5214
+ ] });
5215
+ }
5216
+ function withMfaMethod(custom, v) {
5217
+ const rest = custom.filter((c) => c.key !== MFA_METHOD_KEY);
5218
+ return v === "sms" || v === "push_or_other" ? [...rest, { key: MFA_METHOD_KEY, label: "Two-factor method", value: v }] : rest;
5219
+ }
5220
+ function DraftTwoFactorRow({ custom, onCustom }) {
5221
+ const value = custom.find((c) => c.key === MFA_METHOD_KEY)?.value || "none";
5222
+ return /* @__PURE__ */ jsx22(VaultRow, { label: "Two-factor", children: /* @__PURE__ */ jsx22(
5223
+ Select7,
5224
+ {
5225
+ value: value === "sms" || value === "push_or_other" ? value : "none",
5226
+ "aria-label": "Two-factor method",
5227
+ options: MFA_OPTIONS.map((o) => ({ value: o.value, label: o.label })),
5228
+ onValueChange: (v) => onCustom(withMfaMethod(custom, v))
5229
+ }
5230
+ ) });
5231
+ }
5232
+ var defaultBrowserSettings = (hasWebsite) => ({ uriMatchMode: "host", browserFillEnabled: hasWebsite });
5233
+ function DraftBrowserRows({ value, hasWebsite, onChange }) {
5234
+ return /* @__PURE__ */ jsxs21(Fragment15, { children: [
5235
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Website matching", hint: hint(MATCH_WORDS[value.uriMatchMode].hint), children: /* @__PURE__ */ jsx22(
5236
+ Select7,
5237
+ {
5238
+ "aria-label": "Website matching",
5239
+ value: value.uriMatchMode,
5240
+ options: MATCH_MODES.map((m) => ({ value: m, label: MATCH_WORDS[m].label })),
5241
+ onValueChange: (m) => onChange({ ...value, uriMatchMode: m })
5242
+ }
5243
+ ) }),
5244
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Fill in browser", hint: hint(hasWebsite ? value.browserFillEnabled ? "Offered on matching pages" : "Never filled automatically" : "Add a website first"), children: /* @__PURE__ */ jsx22(Switch5, { "aria-label": "Fill in browser", checked: hasWebsite && value.browserFillEnabled, disabled: !hasWebsite, onCheckedChange: (v) => onChange({ ...value, browserFillEnabled: v }) }) })
5245
+ ] });
5246
+ }
5247
+ function AssignResult({ sent, onAnother, onDone }) {
5248
+ return /* @__PURE__ */ jsxs21("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5 px-3 py-4 sm:px-6 sm:py-6", role: "status", children: [
5249
+ /* @__PURE__ */ jsxs21(VaultSection, { title: /* @__PURE__ */ jsxs21("span", { className: "flex items-center gap-1.5", children: [
5250
+ /* @__PURE__ */ jsx22(CheckGlyph, { className: "size-4 text-success" }),
5251
+ "Sent to ",
5252
+ sent.recipientEmail
5253
+ ] }), children: [
5254
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx22("span", { className: "block truncate", children: sent.name }) }),
5255
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Item ID", children: /* @__PURE__ */ jsx22(RecordId, { value: sent.id, label: "Item" }) }),
5256
+ /* @__PURE__ */ jsx22(VaultRow, { label: "Password", children: /* @__PURE__ */ jsx22("span", { className: "block truncate text-muted-foreground", children: sent.generated ? "Generated privately, never shown to you" : "Theirs now; you keep no access" }) })
5257
+ ] }),
5258
+ /* @__PURE__ */ jsxs21("div", { className: "flex justify-end gap-2", children: [
5259
+ /* @__PURE__ */ jsx22(Button18, { variant: "outline", icon: /* @__PURE__ */ jsx22(PlusGlyph, {}), onClick: onAnother, children: "Create another" }),
5260
+ /* @__PURE__ */ jsx22(Button18, { variant: "primary", onClick: onDone, children: "Done" })
5261
+ ] })
5262
+ ] });
5263
+ }
5264
+
5050
5265
  // src/ItemPane.tsx
5051
5266
  import { HistoryIcon, SettingsIcon, UsersIcon as UsersIcon2 } from "@ai-matrx/design-system/icons";
5052
5267
  import { dropKeptDraft, keepDraft, readKeptDraft } from "@ai-matrx/kit/drafts";
@@ -5173,15 +5388,15 @@ function targetLabel(t) {
5173
5388
  }
5174
5389
 
5175
5390
  // src/extension/UseOnSiteButton.tsx
5176
- import { useState as useState22 } from "react";
5177
- import { Button as Button18 } from "@ai-matrx/design-system/controls";
5178
- import { jsx as jsx22 } from "react/jsx-runtime";
5391
+ import { useState as useState23 } from "react";
5392
+ import { Button as Button19 } from "@ai-matrx/design-system/controls";
5393
+ import { jsx as jsx23 } from "react/jsx-runtime";
5179
5394
  function canUseOnSite(item, pageUrl) {
5180
5395
  return item.capabilities.canEdit && isFillablePage(pageUrl) && !coversPage(item.loginUrls, item.uriMatchMode, pageUrl);
5181
5396
  }
5182
5397
  function UseOnSiteButton({ port, item, pageUrl, onChanged }) {
5183
5398
  const notify = useNotify();
5184
- const [busy, setBusy] = useState22(false);
5399
+ const [busy, setBusy] = useState23(false);
5185
5400
  if (!canUseOnSite(item, pageUrl)) return null;
5186
5401
  const site = pageSite(pageUrl);
5187
5402
  const run = async () => {
@@ -5196,13 +5411,13 @@ function UseOnSiteButton({ port, item, pageUrl, onChanged }) {
5196
5411
  setBusy(false);
5197
5412
  }
5198
5413
  };
5199
- return /* @__PURE__ */ jsx22(Button18, { variant: "outline", icon: /* @__PURE__ */ jsx22(PlusGlyph, {}), disabled: busy, onClick: () => void run(), title: `Fill this login on ${site}`, children: "Use here" });
5414
+ return /* @__PURE__ */ jsx23(Button19, { variant: "outline", icon: /* @__PURE__ */ jsx23(PlusGlyph, {}), disabled: busy, onClick: () => void run(), title: `Fill this login on ${site}`, children: "Use here" });
5200
5415
  }
5201
5416
 
5202
5417
  // src/sharing/SharePanel.tsx
5203
- import { useEffect as useEffect15, useState as useState25 } from "react";
5204
- import { confirm as confirm8 } from "@ai-matrx/kit/confirm-opener";
5205
- import { Button as Button20, DisclosureHeader as DisclosureHeader3, Field as Field9, RegionSkeleton, Select as Select8 } from "@ai-matrx/design-system/controls";
5418
+ import { useEffect as useEffect15, useState as useState26 } from "react";
5419
+ import { confirm as confirm9 } from "@ai-matrx/kit/confirm-opener";
5420
+ import { Button as Button21, DisclosureHeader as DisclosureHeader3, Field as Field10, RegionSkeleton, Select as Select9 } from "@ai-matrx/design-system/controls";
5206
5421
  import { cn as cn11 } from "@ai-matrx/design-system";
5207
5422
  import { UsersIcon } from "@ai-matrx/design-system/icons";
5208
5423
 
@@ -5258,18 +5473,18 @@ function shareSummary(grants) {
5258
5473
  var MEMBER_CHOICE_DEFAULT = "default";
5259
5474
 
5260
5475
  // src/sharing/parts.tsx
5261
- import { useState as useState23 } from "react";
5476
+ import { useState as useState24 } from "react";
5262
5477
  import { cn as cn10 } from "@ai-matrx/design-system";
5263
- import { jsx as jsx23, jsxs as jsxs21 } from "react/jsx-runtime";
5478
+ import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
5264
5479
  var message = (e, fallback) => {
5265
5480
  const m = e instanceof Error && e.message ? e.message : fallback;
5266
5481
  return copyRefusal(m) ?? m;
5267
5482
  };
5268
5483
  function useConfirmedChange() {
5269
5484
  const confirmed = useConfirmed();
5270
- const [busy, setBusy] = useState23(null);
5271
- const [error, setError] = useState23(null);
5272
- const [notice, setNotice] = useState23(null);
5485
+ const [busy, setBusy] = useState24(null);
5486
+ const [error, setError] = useState24(null);
5487
+ const [notice, setNotice] = useState24(null);
5273
5488
  async function run(key, fn, done) {
5274
5489
  setBusy(key);
5275
5490
  setError(null);
@@ -5288,33 +5503,33 @@ function useConfirmedChange() {
5288
5503
  return { busy, error, notice, run, setNotice };
5289
5504
  }
5290
5505
  function AccessLine({ glyph: G, who, meta, children }) {
5291
- return /* @__PURE__ */ jsxs21("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5292
- /* @__PURE__ */ jsx23(G, { className: "size-4 shrink-0 text-muted-foreground" }),
5293
- /* @__PURE__ */ jsxs21("div", { className: "flex min-w-0 flex-1 items-baseline gap-2", children: [
5294
- /* @__PURE__ */ jsx23("span", { className: "truncate text-sm text-foreground", children: who }),
5295
- meta ? /* @__PURE__ */ jsx23("span", { className: "shrink-0 text-xs text-muted-foreground", children: meta }) : null
5506
+ return /* @__PURE__ */ jsxs22("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5507
+ /* @__PURE__ */ jsx24(G, { className: "size-4 shrink-0 text-muted-foreground" }),
5508
+ /* @__PURE__ */ jsxs22("div", { className: "flex min-w-0 flex-1 items-baseline gap-2", children: [
5509
+ /* @__PURE__ */ jsx24("span", { className: "truncate text-sm text-foreground", children: who }),
5510
+ meta ? /* @__PURE__ */ jsx24("span", { className: "shrink-0 text-xs text-muted-foreground", children: meta }) : null
5296
5511
  ] }),
5297
- /* @__PURE__ */ jsx23("div", { className: "flex shrink-0 items-center gap-0.5", children })
5512
+ /* @__PURE__ */ jsx24("div", { className: "flex shrink-0 items-center gap-0.5", children })
5298
5513
  ] });
5299
5514
  }
5300
5515
  function StatusLine({ error, notice }) {
5301
5516
  if (!error && !notice) return null;
5302
- return /* @__PURE__ */ jsx23("p", { className: cn10("min-w-0 flex-1 line-clamp-2 text-sm", error ? "text-destructive" : "text-success"), title: error ?? notice ?? void 0, children: error ?? notice });
5517
+ return /* @__PURE__ */ jsx24("p", { className: cn10("min-w-0 flex-1 line-clamp-2 text-sm", error ? "text-destructive" : "text-success"), title: error ?? notice ?? void 0, children: error ?? notice });
5303
5518
  }
5304
5519
 
5305
5520
  // src/sharing/MovePanel.tsx
5306
- import { useState as useState24 } from "react";
5307
- import { confirm as confirm7 } from "@ai-matrx/kit/confirm-opener";
5308
- import { Button as Button19, Field as Field8, Select as Select7 } from "@ai-matrx/design-system/controls";
5309
- import { jsx as jsx24, jsxs as jsxs22 } from "react/jsx-runtime";
5521
+ import { useState as useState25 } from "react";
5522
+ import { confirm as confirm8 } from "@ai-matrx/kit/confirm-opener";
5523
+ import { Button as Button20, Field as Field9, Select as Select8 } from "@ai-matrx/design-system/controls";
5524
+ import { jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
5310
5525
  var NONE = "__none__";
5311
5526
  function MovePanel({ item, port, organizations, onClose, onChanged }) {
5312
5527
  const { busy, error, notice, run, setNotice } = useConfirmedChange();
5313
5528
  const moves = moveDestinations(item, organizations);
5314
5529
  const copies = copyDestinations(organizations, item);
5315
- const [moveTo, setMoveTo] = useState24("");
5316
- const [copyTo, setCopyTo] = useState24("");
5317
- const [email, setEmail] = useState24("");
5530
+ const [moveTo, setMoveTo] = useState25("");
5531
+ const [copyTo, setCopyTo] = useState25("");
5532
+ const [email, setEmail] = useState25("");
5318
5533
  const passkey = isPasskey(item);
5319
5534
  const canMove = item.capabilities.canManage && !passkey && moves.length > 0;
5320
5535
  const canGive = item.capabilities.canManage && item.owner.kind === "me" && !passkey;
@@ -5324,7 +5539,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5324
5539
  const move = async () => {
5325
5540
  if (!moveChoice) return;
5326
5541
  const to = destinationOf(moveChoice.value);
5327
- const ok = await confirm7({
5542
+ const ok = await confirm8({
5328
5543
  title: `Move to ${moveChoice.label}?`,
5329
5544
  description: `"${item.name}" stays the same item, so everything using it keeps working. ${itemMoveConsequence(item, to)}.`,
5330
5545
  confirmLabel: "Move"
@@ -5339,7 +5554,7 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5339
5554
  const give = async () => {
5340
5555
  const to = email.trim();
5341
5556
  if (!isEmail(to)) return;
5342
- const ok = await confirm7({ title: "Give ownership away?", description: giveDescription(item, to), confirmLabel: "Give ownership", variant: "destructive" });
5557
+ const ok = await confirm8({ title: "Give ownership away?", description: giveDescription(item, to), confirmLabel: "Give ownership", variant: "destructive" });
5343
5558
  if (!ok) return;
5344
5559
  const out = await run("give", () => port.sharing.giveOwnership(item, to));
5345
5560
  if (!out) return;
@@ -5352,25 +5567,25 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5352
5567
  if (made) onChanged();
5353
5568
  };
5354
5569
  const nothing = !canMove && !canGive && !canCopy;
5355
- return /* @__PURE__ */ jsx24(
5570
+ return /* @__PURE__ */ jsx25(
5356
5571
  Panel,
5357
5572
  {
5358
5573
  title: "Move or copy",
5359
5574
  size: "md",
5360
5575
  onClose,
5361
- footer: /* @__PURE__ */ jsx24(PanelFooter, { status: error || notice ? /* @__PURE__ */ jsx24(StatusLine, { error, notice }) : null, children: /* @__PURE__ */ jsx24(Button19, { variant: "primary", onClick: onClose, children: "Done" }) }),
5362
- children: nothing ? /* @__PURE__ */ jsx24(VaultSection, { children: /* @__PURE__ */ jsx24(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ jsxs22(VaultSection, { children: [
5363
- canMove && moves.length > 0 ? /* @__PURE__ */ jsx24(
5576
+ footer: /* @__PURE__ */ jsx25(PanelFooter, { status: error || notice ? /* @__PURE__ */ jsx25(StatusLine, { error, notice }) : null, children: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }) }),
5577
+ children: nothing ? /* @__PURE__ */ jsx25(VaultSection, { children: /* @__PURE__ */ jsx25(Empty, { children: passkey ? "A passkey stays where it was created." : "Only the owner can move or give this item." }) }) : /* @__PURE__ */ jsxs23(VaultSection, { children: [
5578
+ canMove && moves.length > 0 ? /* @__PURE__ */ jsx25(
5364
5579
  VaultRow,
5365
5580
  {
5366
5581
  label: "Move to",
5367
5582
  hint: moveChoice ? itemMoveConsequence(item, destinationOf(moveChoice.value)) : void 0,
5368
- actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
5369
- children: /* @__PURE__ */ jsx24(Select7, { className: "w-full", "aria-label": "Move to", value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
5583
+ actions: /* @__PURE__ */ jsx25(Button20, { variant: "outline", disabled: busy !== null || !moveChoice, onClick: () => void move(), children: "Move" }),
5584
+ children: /* @__PURE__ */ jsx25(Select8, { className: "w-full", "aria-label": "Move to", value: moveTo || NONE, onValueChange: (v) => setMoveTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...moves] })
5370
5585
  }
5371
5586
  ) : null,
5372
- canGive ? /* @__PURE__ */ jsx24(VaultRow, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ jsx24(Button19, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ jsx24(
5373
- Field8,
5587
+ canGive ? /* @__PURE__ */ jsx25(VaultRow, { label: "Give to", hint: "You lose all access; your shares end", actions: /* @__PURE__ */ jsx25(Button20, { variant: "danger", disabled: busy !== null || !isEmail(email), onClick: () => void give(), children: "Give" }), children: /* @__PURE__ */ jsx25(
5588
+ Field9,
5374
5589
  {
5375
5590
  className: "w-full",
5376
5591
  type: "email",
@@ -5383,18 +5598,18 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
5383
5598
  onChange: (e) => setEmail(e.target.value)
5384
5599
  }
5385
5600
  ) }) : null,
5386
- canCopy && copies.length > 0 ? /* @__PURE__ */ jsx24(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ jsx24(Button19, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ jsx24(Select7, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
5601
+ canCopy && copies.length > 0 ? /* @__PURE__ */ jsx25(VaultRow, { label: "Copy to", hint: "A separate item; edits no longer sync", actions: /* @__PURE__ */ jsx25(Button20, { variant: "outline", disabled: busy !== null || !copyChoice, onClick: () => void copy(), children: "Copy" }), children: /* @__PURE__ */ jsx25(Select8, { className: "w-full", "aria-label": "Copy to", value: copyTo || NONE, onValueChange: (v) => setCopyTo(v === NONE ? "" : v), options: [{ value: NONE, label: "Choose where" }, ...copies] }) }) : null
5387
5602
  ] })
5388
5603
  }
5389
5604
  );
5390
5605
  }
5391
5606
 
5392
5607
  // src/sharing/SharePanel.tsx
5393
- import { Fragment as Fragment15, jsx as jsx25, jsxs as jsxs23 } from "react/jsx-runtime";
5608
+ import { Fragment as Fragment16, jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
5394
5609
  function useGrants(port, item) {
5395
- const [grants, setGrants] = useState25(null);
5396
- const [loadError, setLoadError] = useState25(null);
5397
- const [nonce, setNonce] = useState25(0);
5610
+ const [grants, setGrants] = useState26(null);
5611
+ const [loadError, setLoadError] = useState26(null);
5612
+ const [nonce, setNonce] = useState26(0);
5398
5613
  const allowed = item.capabilities.canManage;
5399
5614
  useEffect15(() => {
5400
5615
  if (!allowed) return;
@@ -5413,9 +5628,9 @@ function useGrants(port, item) {
5413
5628
  function SharePanel({ item, port, organizations, onClose, onChanged }) {
5414
5629
  const { grants, setGrants, loadError, reload } = useGrants(port, item);
5415
5630
  const { busy, error, notice, run } = useConfirmedChange();
5416
- const [email, setEmail] = useState25("");
5417
- const [level, setLevel] = useState25("use");
5418
- const [more, setMore] = useState25(false);
5631
+ const [email, setEmail] = useState26("");
5632
+ const [level, setLevel] = useState26("use");
5633
+ const [more, setMore] = useState26(false);
5419
5634
  const isOrg = item.owner.kind === "organization" && item.owner.organizationId !== null;
5420
5635
  const orgName = item.owner.label;
5421
5636
  const people = (grants ?? []).filter((g) => g.kind === "person");
@@ -5434,7 +5649,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5434
5649
  if (updated) setGrants((all) => (all ?? []).map((x) => x.id === g.id ? { ...updated, label: updated.label || g.label } : x));
5435
5650
  };
5436
5651
  const revoke = async (g) => {
5437
- const ok = await confirm8({
5652
+ const ok = await confirm9({
5438
5653
  title: g.kind === "organization" ? `Remove from ${g.label}?` : "Remove access?",
5439
5654
  description: g.kind === "organization" ? `${g.label} members can no longer use "${item.name}". It stays in your vault.` : `${g.label} can no longer use "${item.name}". This takes effect at once.`,
5440
5655
  confirmLabel: "Remove",
@@ -5450,7 +5665,7 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5450
5665
  const setMode = async (mode) => {
5451
5666
  if (mode === (item.accessMode === "restricted" ? "restricted" : "all_members")) return;
5452
5667
  if (mode === "all_members" && people.length > 0) {
5453
- const ok = await confirm8({
5668
+ const ok = await confirm9({
5454
5669
  title: "Open to every member?",
5455
5670
  description: `Every member of ${orgName} gets it at their own vault access. The ${people.length === 1 ? "person" : `${people.length} people`} listed here lose their own access.`,
5456
5671
  confirmLabel: "Open to members",
@@ -5465,20 +5680,20 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5465
5680
  }
5466
5681
  };
5467
5682
  if (!item.capabilities.canManage) {
5468
- return /* @__PURE__ */ jsx25(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ jsx25(VaultSection, { children: /* @__PURE__ */ jsx25(Empty, { children: "Only the owner can change who has access." }) }) });
5683
+ return /* @__PURE__ */ jsx26(Panel, { title: "Share", size: "md", onClose, footer: /* @__PURE__ */ jsx26(Button21, { variant: "primary", onClick: onClose, children: "Done" }), children: /* @__PURE__ */ jsx26(VaultSection, { children: /* @__PURE__ */ jsx26(Empty, { children: "Only the owner can change who has access." }) }) });
5469
5684
  }
5470
- return /* @__PURE__ */ jsxs23(
5685
+ return /* @__PURE__ */ jsxs24(
5471
5686
  Panel,
5472
5687
  {
5473
5688
  title: "Share",
5474
5689
  size: "md",
5475
5690
  onClose,
5476
- footer: /* @__PURE__ */ jsx25(PanelFooter, { status: error || notice ? /* @__PURE__ */ jsx25(StatusLine, { error, notice }) : null, children: /* @__PURE__ */ jsx25(Button20, { variant: "primary", onClick: onClose, children: "Done" }) }),
5691
+ footer: /* @__PURE__ */ jsx26(PanelFooter, { status: error || notice ? /* @__PURE__ */ jsx26(StatusLine, { error, notice }) : null, children: /* @__PURE__ */ jsx26(Button21, { variant: "primary", onClick: onClose, children: "Done" }) }),
5477
5692
  children: [
5478
- /* @__PURE__ */ jsxs23(VaultSection, { title: "Who has access", children: [
5479
- isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: BuildingGlyph, who: `${orgName} admins`, children: /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }) : /* @__PURE__ */ jsx25(AccessLine, { glyph: PersonGlyph, who: "You", meta: "Owner", children: /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }),
5480
- isOrg ? /* @__PURE__ */ jsx25(AccessLine, { glyph: UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ jsx25(
5481
- Select8,
5693
+ /* @__PURE__ */ jsxs24(VaultSection, { title: "Who has access", children: [
5694
+ isOrg ? /* @__PURE__ */ jsx26(AccessLine, { glyph: BuildingGlyph, who: `${orgName} admins`, children: /* @__PURE__ */ jsx26("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }) : /* @__PURE__ */ jsx26(AccessLine, { glyph: PersonGlyph, who: "You", meta: "Owner", children: /* @__PURE__ */ jsx26("span", { className: "px-2 text-sm text-muted-foreground", children: "Full access" }) }),
5695
+ isOrg ? /* @__PURE__ */ jsx26(AccessLine, { glyph: UsersIcon, who: `${orgName} members`, children: /* @__PURE__ */ jsx26(
5696
+ Select9,
5482
5697
  {
5483
5698
  variant: "inline",
5484
5699
  align: "end",
@@ -5492,14 +5707,14 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5492
5707
  ]
5493
5708
  }
5494
5709
  ) }) : null,
5495
- loadError ? /* @__PURE__ */ jsx25(AccessLine, { glyph: XGlyph, who: /* @__PURE__ */ jsx25("span", { className: "text-destructive", children: loadError }), children: /* @__PURE__ */ jsx25(Button20, { variant: "quiet", onClick: reload, children: "Retry" }) }) : grants === null ? /* @__PURE__ */ jsx25(RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading who has access", className: "px-3 sm:px-4" }) : grants.map((g) => /* @__PURE__ */ jsxs23(AccessLine, { glyph: g.kind === "organization" ? BuildingGlyph : PersonGlyph, who: g.label, ...g.kind === "organization" ? { meta: "Organization vault" } : {}, children: [
5496
- /* @__PURE__ */ jsx25(Select8, { variant: "inline", align: "end", "aria-label": `What ${g.label} can do`, disabled: busy !== null, value: g.level, onValueChange: (v) => void change(g, v), options: LEVEL_OPTIONS }),
5497
- /* @__PURE__ */ jsx25(Button20, { variant: "quiet", removes: true, icon: /* @__PURE__ */ jsx25(XGlyph, {}), "aria-label": `Remove ${g.label}`, disabled: busy !== null, onClick: () => void revoke(g) })
5710
+ loadError ? /* @__PURE__ */ jsx26(AccessLine, { glyph: XGlyph, who: /* @__PURE__ */ jsx26("span", { className: "text-destructive", children: loadError }), children: /* @__PURE__ */ jsx26(Button21, { variant: "quiet", onClick: reload, children: "Retry" }) }) : grants === null ? /* @__PURE__ */ jsx26(RegionSkeleton, { shape: "rows", count: 2, "aria-label": "Loading who has access", className: "px-3 sm:px-4" }) : grants.map((g) => /* @__PURE__ */ jsxs24(AccessLine, { glyph: g.kind === "organization" ? BuildingGlyph : PersonGlyph, who: g.label, ...g.kind === "organization" ? { meta: "Organization vault" } : {}, children: [
5711
+ /* @__PURE__ */ jsx26(Select9, { variant: "inline", align: "end", "aria-label": `What ${g.label} can do`, disabled: busy !== null, value: g.level, onValueChange: (v) => void change(g, v), options: LEVEL_OPTIONS }),
5712
+ /* @__PURE__ */ jsx26(Button21, { variant: "quiet", removes: true, icon: /* @__PURE__ */ jsx26(XGlyph, {}), "aria-label": `Remove ${g.label}`, disabled: busy !== null, onClick: () => void revoke(g) })
5498
5713
  ] }, g.id)),
5499
- /* @__PURE__ */ jsxs23("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5500
- /* @__PURE__ */ jsx25(PersonGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5501
- /* @__PURE__ */ jsx25(
5502
- Field9,
5714
+ /* @__PURE__ */ jsxs24("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5715
+ /* @__PURE__ */ jsx26(PersonGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5716
+ /* @__PURE__ */ jsx26(
5717
+ Field10,
5503
5718
  {
5504
5719
  className: "min-w-0 flex-1",
5505
5720
  type: "email",
@@ -5519,13 +5734,13 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5519
5734
  }
5520
5735
  }
5521
5736
  ),
5522
- /* @__PURE__ */ jsx25(Select8, { variant: "inline", align: "end", "aria-label": "What they can do", value: level, onValueChange: setLevel, options: LEVEL_OPTIONS }),
5523
- /* @__PURE__ */ jsx25(Button20, { variant: "primary", disabled: busy !== null || !isEmail(email), onClick: () => void add(), children: "Share" })
5737
+ /* @__PURE__ */ jsx26(Select9, { variant: "inline", align: "end", "aria-label": "What they can do", value: level, onValueChange: setLevel, options: LEVEL_OPTIONS }),
5738
+ /* @__PURE__ */ jsx26(Button21, { variant: "primary", disabled: busy !== null || !isEmail(email), onClick: () => void add(), children: "Share" })
5524
5739
  ] })
5525
5740
  ] }),
5526
- /* @__PURE__ */ jsxs23("div", { className: "flex flex-col gap-3", children: [
5527
- /* @__PURE__ */ jsx25(DisclosureHeader3, { open: more, title: "More options", onClick: () => setMore((o) => !o) }),
5528
- more ? isOrg && item.owner.organizationId ? /* @__PURE__ */ jsx25(MemberAccess, { port, organizationId: item.owner.organizationId, organizationName: orgName }) : /* @__PURE__ */ jsx25(IntoOrganization, { item, port, organizations, grants: grants ?? [], onShared: (g) => setGrants((all) => [...(all ?? []).filter((x) => x.id !== g.id), g]) }) : null
5741
+ /* @__PURE__ */ jsxs24("div", { className: "flex flex-col gap-3", children: [
5742
+ /* @__PURE__ */ jsx26(DisclosureHeader3, { open: more, title: "More options", onClick: () => setMore((o) => !o) }),
5743
+ more ? isOrg && item.owner.organizationId ? /* @__PURE__ */ jsx26(MemberAccess, { port, organizationId: item.owner.organizationId, organizationName: orgName }) : /* @__PURE__ */ jsx26(IntoOrganization, { item, port, organizations, grants: grants ?? [], onShared: (g) => setGrants((all) => [...(all ?? []).filter((x) => x.id !== g.id), g]) }) : null
5529
5744
  ] })
5530
5745
  ]
5531
5746
  }
@@ -5534,17 +5749,17 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
5534
5749
  function IntoOrganization({ item, port, organizations, grants, onShared }) {
5535
5750
  const { busy, error, notice, run } = useConfirmedChange();
5536
5751
  const open = organizations.filter((o) => !grants.some((g) => g.organizationId === o.id));
5537
- const [target, setTarget] = useState25("");
5538
- const [level, setLevel] = useState25("use");
5752
+ const [target, setTarget] = useState26("");
5753
+ const [level, setLevel] = useState26("use");
5539
5754
  const chosen = open.find((o) => o.id === target);
5540
5755
  if (item.owner.kind !== "me") return null;
5541
- return /* @__PURE__ */ jsx25(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ jsxs23(Fragment15, { children: [
5542
- /* @__PURE__ */ jsxs23("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5543
- /* @__PURE__ */ jsx25(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5544
- /* @__PURE__ */ jsx25(Select8, { className: "min-w-0 flex-1", "aria-label": "Organization", value: target || "__none__", onValueChange: (v) => setTarget(v === "__none__" ? "" : v), options: [{ value: "__none__", label: "Choose an organization" }, ...open.map((o) => ({ value: o.id, label: o.name }))] }),
5545
- /* @__PURE__ */ jsx25(Select8, { variant: "inline", align: "end", "aria-label": "What its members can do", value: level, onValueChange: setLevel, options: LEVEL_OPTIONS }),
5546
- /* @__PURE__ */ jsx25(
5547
- Button20,
5756
+ return /* @__PURE__ */ jsx26(VaultSection, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ jsxs24(Fragment16, { children: [
5757
+ /* @__PURE__ */ jsxs24("div", { className: "flex min-h-11 items-center gap-2 px-3 sm:px-4", children: [
5758
+ /* @__PURE__ */ jsx26(BuildingGlyph, { className: "size-4 shrink-0 text-muted-foreground" }),
5759
+ /* @__PURE__ */ jsx26(Select9, { 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 }))] }),
5760
+ /* @__PURE__ */ jsx26(Select9, { variant: "inline", align: "end", "aria-label": "What its members can do", value: level, onValueChange: setLevel, options: LEVEL_OPTIONS }),
5761
+ /* @__PURE__ */ jsx26(
5762
+ Button21,
5548
5763
  {
5549
5764
  variant: "outline",
5550
5765
  disabled: busy !== null || !chosen,
@@ -5560,8 +5775,8 @@ function IntoOrganization({ item, port, organizations, grants, onShared }) {
5560
5775
  }
5561
5776
  )
5562
5777
  ] }),
5563
- /* @__PURE__ */ jsx25("p", { className: "truncate px-3 pb-1 text-xs text-muted-foreground sm:px-4", children: error ? /* @__PURE__ */ jsx25("span", { className: "text-destructive", children: error }) : notice ? /* @__PURE__ */ jsx25("span", { className: "text-success", children: notice }) : "It stays yours; its members can use it too" })
5564
- ] }) : /* @__PURE__ */ jsx25(Empty, { children: organizations.length ? "Already in every organization you belong to." : "You are not in any organization." }) });
5778
+ /* @__PURE__ */ jsx26("p", { className: "truncate px-3 pb-1 text-xs text-muted-foreground sm:px-4", children: error ? /* @__PURE__ */ jsx26("span", { className: "text-destructive", children: error }) : notice ? /* @__PURE__ */ jsx26("span", { className: "text-success", children: notice }) : "It stays yours; its members can use it too" })
5779
+ ] }) : /* @__PURE__ */ jsx26(Empty, { children: organizations.length ? "Already in every organization you belong to." : "You are not in any organization." }) });
5565
5780
  }
5566
5781
  var CHOICES = [
5567
5782
  { value: MEMBER_CHOICE_DEFAULT, label: "Default" },
@@ -5570,8 +5785,8 @@ var CHOICES = [
5570
5785
  { value: "editor", label: "Can edit", meta: "See and change" }
5571
5786
  ];
5572
5787
  function MemberAccess({ port, organizationId, organizationName }) {
5573
- const [list, setList] = useState25(null);
5574
- const [loadError, setLoadError] = useState25(null);
5788
+ const [list, setList] = useState26(null);
5789
+ const [loadError, setLoadError] = useState26(null);
5575
5790
  const { busy, error, run } = useConfirmedChange();
5576
5791
  useEffect15(() => {
5577
5792
  let live = true;
@@ -5588,9 +5803,9 @@ function MemberAccess({ port, organizationId, organizationName }) {
5588
5803
  const effective = await run(userId, () => port.sharing.setMemberAccess(organizationId, userId, access));
5589
5804
  if (effective) setList((l) => l ? { ...l, members: l.members.map((m) => m.userId === userId ? { ...m, access, effective } : m) } : l);
5590
5805
  };
5591
- return /* @__PURE__ */ jsxs23(VaultSection, { title: `${organizationName} vault access`, children: [
5592
- loadError ? /* @__PURE__ */ jsx25(Empty, { children: loadError }) : list === null ? /* @__PURE__ */ jsx25(RegionSkeleton, { shape: "rows", count: 3, "aria-label": "Loading member access", className: "px-3 sm:px-4" }) : list.members.length === 0 ? /* @__PURE__ */ jsx25(Empty, { children: "No members yet." }) : list.members.map((m) => /* @__PURE__ */ jsx25(AccessLine, { glyph: PersonGlyph, who: m.email || m.userId, meta: m.role, children: m.effective === "admin" ? /* @__PURE__ */ jsx25("span", { className: "px-2 text-sm text-muted-foreground", children: MEMBER_ACCESS_LABEL.admin }) : /* @__PURE__ */ jsx25(
5593
- Select8,
5806
+ return /* @__PURE__ */ jsxs24(VaultSection, { title: `${organizationName} vault access`, children: [
5807
+ loadError ? /* @__PURE__ */ jsx26(Empty, { children: loadError }) : list === null ? /* @__PURE__ */ jsx26(RegionSkeleton, { shape: "rows", count: 3, "aria-label": "Loading member access", className: "px-3 sm:px-4" }) : list.members.length === 0 ? /* @__PURE__ */ jsx26(Empty, { children: "No members yet." }) : list.members.map((m) => /* @__PURE__ */ jsx26(AccessLine, { glyph: PersonGlyph, who: m.email || m.userId, meta: m.role, children: m.effective === "admin" ? /* @__PURE__ */ jsx26("span", { className: "px-2 text-sm text-muted-foreground", children: MEMBER_ACCESS_LABEL.admin }) : /* @__PURE__ */ jsx26(
5808
+ Select9,
5594
5809
  {
5595
5810
  variant: "inline",
5596
5811
  align: "end",
@@ -5601,11 +5816,11 @@ function MemberAccess({ port, organizationId, organizationName }) {
5601
5816
  options: CHOICES.map((c) => c.value === MEMBER_CHOICE_DEFAULT ? { value: c.value, label: `Default (${MEMBER_ACCESS_LABEL[list.defaultAccess]})` } : c.meta ? { value: c.value, label: c.label, meta: c.meta } : { value: c.value, label: c.label })
5602
5817
  }
5603
5818
  ) }, m.userId)),
5604
- /* @__PURE__ */ jsx25("p", { className: "truncate px-3 pb-1 text-xs text-muted-foreground sm:px-4", children: error ? /* @__PURE__ */ jsx25("span", { className: "text-destructive", children: error }) : "Applies to every item in this organization" })
5819
+ /* @__PURE__ */ jsx26("p", { className: "truncate px-3 pb-1 text-xs text-muted-foreground sm:px-4", children: error ? /* @__PURE__ */ jsx26("span", { className: "text-destructive", children: error }) : "Applies to every item in this organization" })
5605
5820
  ] });
5606
5821
  }
5607
5822
  function SharingSummary({ item, port, className }) {
5608
- const [text, setText] = useState25("");
5823
+ const [text, setText] = useState26("");
5609
5824
  const allowed = item.capabilities.canManage;
5610
5825
  useEffect15(() => {
5611
5826
  if (!allowed) return;
@@ -5619,12 +5834,12 @@ function SharingSummary({ item, port, className }) {
5619
5834
  };
5620
5835
  }, [port, item, allowed]);
5621
5836
  if (!allowed || !text) return null;
5622
- return /* @__PURE__ */ jsx25("span", { className: cn11("truncate text-xs text-muted-foreground", className), children: text });
5837
+ return /* @__PURE__ */ jsx26("span", { className: cn11("truncate text-xs text-muted-foreground", className), children: text });
5623
5838
  }
5624
5839
 
5625
5840
  // src/ItemPane.tsx
5626
5841
  import { formatAbsoluteDate as formatAbsoluteDate3 } from "@ai-matrx/kit/format";
5627
- import { Fragment as Fragment16, jsx as jsx26, jsxs as jsxs24 } from "react/jsx-runtime";
5842
+ import { Fragment as Fragment17, jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
5628
5843
  var USERNAME_KEYS = /^(username|user_name|email|login|username_or_email|account_email)$/;
5629
5844
  function ItemPane(props) {
5630
5845
  const { port, item, definition, mode, host, organizations, defaultOwner, seed, onBack, onMode, onSaved, onDeleted, onDirty, onCancelNew, onPanel, onChanged, favorite, notice, refreshKey } = props;
@@ -5633,7 +5848,7 @@ function ItemPane(props) {
5633
5848
  const editing = mode !== "view";
5634
5849
  const seedName = seed?.name ?? "";
5635
5850
  const seedUrl = seed?.url ?? "";
5636
- const [loaded, setLoaded] = useState26({});
5851
+ const [loaded, setLoaded] = useState27({});
5637
5852
  const base = useMemo3(() => {
5638
5853
  const b = draftOf(item);
5639
5854
  if (!item) {
@@ -5643,18 +5858,21 @@ function ItemPane(props) {
5643
5858
  b.values = { ...loaded };
5644
5859
  return b;
5645
5860
  }, [item, seedName, seedUrl, loaded]);
5646
- const [draft, setDraft] = useState26(base);
5647
- const [tagsText, setTagsText] = useState26(base.tags.join(", "));
5648
- const [showTags, setShowTags] = useState26(false);
5649
- const [showDescription, setShowDescription] = useState26(false);
5650
- const [showRecovery, setShowRecovery] = useState26(false);
5651
- const [settingUpOtp, setSettingUpOtp] = useState26(false);
5652
- const [owner, setOwner] = useState26(defaultOwner ?? "me");
5653
- const [recipient, setRecipient] = useState26("");
5654
- const [generatePrivately, setGeneratePrivately] = useState26(false);
5655
- const [busy, setBusy] = useState26(false);
5656
- const [error, setError] = useState26(null);
5657
- const [destinations, setDestinations] = useState26({});
5861
+ const [draft, setDraft] = useState27(base);
5862
+ const [tagsText, setTagsText] = useState27(base.tags.join(", "));
5863
+ const [showTags, setShowTags] = useState27(false);
5864
+ const [showDescription, setShowDescription] = useState27(false);
5865
+ const [showRecovery, setShowRecovery] = useState27(false);
5866
+ const [settingUpOtp, setSettingUpOtp] = useState27(false);
5867
+ const [owner, setOwner] = useState27(defaultOwner ?? "me");
5868
+ const [recipient, setRecipient] = useState27("");
5869
+ const [generatePrivately, setGeneratePrivately] = useState27(false);
5870
+ const [busy, setBusy] = useState27(false);
5871
+ const [sent, setSent] = useState27(null);
5872
+ const [queuedFiles, setQueuedFiles] = useState27([]);
5873
+ const [showBrowser, setShowBrowser] = useState27(false);
5874
+ const [error, setError] = useState27(null);
5875
+ const [destinations, setDestinations] = useState27({});
5658
5876
  const dirty = editing && isDirty(base, draft);
5659
5877
  const declared = definition?.fields ?? [];
5660
5878
  const prev = useRef14(null);
@@ -5727,10 +5945,13 @@ function ItemPane(props) {
5727
5945
  const secretKey = declared.find((f) => f.storage === "encrypted" && f.kind === "secret")?.key ?? null;
5728
5946
  const r = await port.sharing.assign({ recipientEmail: recipient.trim(), definition, draft: out, generateFieldKey: generatePrivately ? secretKey : null });
5729
5947
  notify(`Sent to ${r.recipientEmail}`);
5730
- onCancelNew();
5948
+ dropKeptDraft(keepKey);
5949
+ onDirty(false);
5950
+ setSent(r);
5731
5951
  } else if (definition) {
5732
5952
  const r = await port.create(definition, owner === "me" ? null : owner, out);
5733
- const [next, n, enrolled] = await withOtp(r.item, r.notice);
5953
+ const [withCode, n0, enrolled] = await withOtp(r.item, r.notice);
5954
+ const [next, n] = await storeQueuedFiles(withCode, n0);
5734
5955
  dropKeptDraft(keepKey);
5735
5956
  onSaved(next, true, n, enrolled);
5736
5957
  }
@@ -5740,9 +5961,32 @@ function ItemPane(props) {
5740
5961
  setBusy(false);
5741
5962
  }
5742
5963
  }
5964
+ async function storeQueuedFiles(saved, notice2) {
5965
+ let next = saved;
5966
+ const failed = [];
5967
+ for (const q of queuedFiles) {
5968
+ try {
5969
+ next = await confirmed(() => port.activity.addFile(next, q.file, { label: q.label, description: q.description, handling: q.handling }));
5970
+ } catch {
5971
+ failed.push(q.label);
5972
+ }
5973
+ }
5974
+ setQueuedFiles([]);
5975
+ if (failed.length === 0) return [next, notice2];
5976
+ const said = `Saved, but ${failed.length === 1 ? `the file ${failed[0]} was` : `${failed.length} files were`} not stored. Add ${failed.length === 1 ? "it" : "them"} with Add file.`;
5977
+ return [next, notice2 ? `${notice2} ${said}` : said];
5978
+ }
5979
+ function createAnother() {
5980
+ setSent(null);
5981
+ setDraft(base);
5982
+ setTagsText(base.tags.join(", "));
5983
+ setQueuedFiles([]);
5984
+ setShowBrowser(false);
5985
+ setError(null);
5986
+ }
5743
5987
  async function remove() {
5744
5988
  if (!item) return;
5745
- const ok = await confirm9({ title: `Delete \u201C${item.name}\u201D?`, description: "It moves to Trash. You can restore it from there.", confirmLabel: "Delete", variant: "destructive" });
5989
+ const ok = await confirm10({ title: `Delete \u201C${item.name}\u201D?`, description: "It moves to Trash. You can restore it from there.", confirmLabel: "Delete", variant: "destructive" });
5746
5990
  if (!ok) return;
5747
5991
  setBusy(true);
5748
5992
  try {
@@ -5783,6 +6027,7 @@ function ItemPane(props) {
5783
6027
  onChanged();
5784
6028
  }
5785
6029
  }
6030
+ const fieldSettings = (f) => canEdit ? /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(SlidersGlyph, {}), "aria-label": `${f.label} settings`, title: `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) }) : null;
5786
6031
  const turnOnOne = canTurnOn ? (f) => () => turnOn([f]) : () => void 0;
5787
6032
  const declaredKeys = new Set(declared.map((f) => f.key));
5788
6033
  const extraFields = (item?.fields ?? []).filter((f) => !declaredKeys.has(f.key) && !draft.removed.includes(f.id) && !isAuthenticatorStorage(f.key));
@@ -5795,35 +6040,35 @@ function ItemPane(props) {
5795
6040
  const recoveryExtra = extraFields.some(isRecoveryCodesField);
5796
6041
  const offerRecovery = isLogin || Boolean(item?.authenticator) || draft.authenticator.trim() !== "";
5797
6042
  const recoveryEditing = !recoveryDeclared && !recoveryExtra && (showRecovery || (draft.values[RECOVERY_CODES_KEY] ?? "") !== "");
5798
- const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ jsx26(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ jsx26(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ jsx26(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ jsx26(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ jsx26(BuildingGlyph, {}) : /* @__PURE__ */ jsx26(UsersIcon2, {}) } : null;
6043
+ const shownOwner = mode === "new" ? owner === "me" ? { label: "Personal", glyph: /* @__PURE__ */ jsx27(PersonGlyph, {}) } : owner === "person" ? { label: "Someone else", glyph: /* @__PURE__ */ jsx27(SendGlyph, {}) } : { label: organizations.find((o) => o.id === owner)?.name ?? "Organization", glyph: /* @__PURE__ */ jsx27(BuildingGlyph, {}) } : item ? { label: item.owner.label, glyph: item.owner.kind === "me" ? /* @__PURE__ */ jsx27(PersonGlyph, {}) : item.owner.kind === "organization" ? /* @__PURE__ */ jsx27(BuildingGlyph, {}) : /* @__PURE__ */ jsx27(UsersIcon2, {}) } : null;
5799
6044
  const sameNamed = (id) => {
5800
6045
  const name = organizations.find((o) => o.id === id)?.name.trim().toLowerCase();
5801
6046
  return Boolean(name) && organizations.filter((o) => o.name.trim().toLowerCase() === name).length > 1;
5802
6047
  };
5803
6048
  const tagsVisible = showTags || draft.tags.length > 0 || tagsText !== "";
5804
6049
  const descriptionVisible = showDescription || draft.description !== "";
5805
- const header = /* @__PURE__ */ jsxs24("header", { className: "flex min-h-14 items-center gap-2 border-b border-border px-3 py-2 sm:gap-3 sm:px-5", children: [
5806
- onBack ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(ChevronLeftGlyph, {}), "aria-label": "Back", onClick: mode === "new" ? onCancelNew : onBack }) : null,
5807
- /* @__PURE__ */ jsx26(ItemIcon, { definitionKey: definition?.key ?? item?.definitionKey ?? "custom", family: definition?.family ?? "generic", site: item ? loginSiteOf(item) : loginSiteOf({ loginUrls: draft.loginUrls }), size: "lg" }),
5808
- /* @__PURE__ */ jsxs24("div", { className: "flex min-w-0 flex-1 flex-col", children: [
5809
- /* @__PURE__ */ jsx26("h2", { className: "truncate text-base font-semibold leading-tight", children: editing ? draft.name || (mode === "new" ? `New ${typeLabel.toLowerCase()}` : item?.name) : item?.name }),
5810
- /* @__PURE__ */ jsxs24("span", { className: "flex min-w-0 items-center gap-1 text-xs text-muted-foreground", children: [
5811
- typeLabel ? /* @__PURE__ */ jsx26("span", { className: "truncate", children: typeLabel }) : null,
5812
- shownOwner ? /* @__PURE__ */ jsx26(Badge7, { className: "shrink-0", icon: shownOwner.glyph, "aria-label": `Saved in ${shownOwner.label}`, children: shownOwner.label }) : null,
5813
- item && !editing ? /* @__PURE__ */ jsx26(SharingSummary, { item, port, className: "hidden truncate before:mr-1 before:content-['\xB7'] sm:inline" }, `${item.updatedAt}-${refreshKey ?? ""}`) : null
6050
+ const header = /* @__PURE__ */ jsxs25("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: [
6051
+ onBack ? /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(ChevronLeftGlyph, {}), "aria-label": "Back", onClick: mode === "new" ? onCancelNew : onBack }) : null,
6052
+ /* @__PURE__ */ jsx27(ItemIcon, { definitionKey: definition?.key ?? item?.definitionKey ?? "custom", family: definition?.family ?? "generic", site: item ? loginSiteOf(item) : loginSiteOf({ loginUrls: draft.loginUrls }), size: "lg" }),
6053
+ /* @__PURE__ */ jsxs25("div", { className: "flex min-w-0 flex-1 flex-col", children: [
6054
+ /* @__PURE__ */ jsx27("h2", { className: "truncate text-base font-semibold leading-tight", children: editing ? draft.name || (mode === "new" ? `New ${typeLabel.toLowerCase()}` : item?.name) : item?.name }),
6055
+ /* @__PURE__ */ jsxs25("span", { className: "flex min-w-0 items-center gap-1 text-xs text-muted-foreground", children: [
6056
+ typeLabel ? /* @__PURE__ */ jsx27("span", { className: "truncate", children: typeLabel }) : null,
6057
+ shownOwner ? /* @__PURE__ */ jsx27(Badge7, { className: "shrink-0", icon: shownOwner.glyph, "aria-label": `Saved in ${shownOwner.label}`, children: shownOwner.label }) : null,
6058
+ item && !editing ? /* @__PURE__ */ jsx27(SharingSummary, { item, port, className: "hidden truncate before:mr-1 before:content-['\xB7'] sm:inline" }, `${item.updatedAt}-${refreshKey ?? ""}`) : null
5814
6059
  ] })
5815
6060
  ] }),
5816
- editing ? /* @__PURE__ */ jsxs24("div", { className: "flex shrink-0 items-center gap-2", children: [
5817
- dirty ? /* @__PURE__ */ jsxs24("span", { className: "hidden items-center gap-1.5 text-xs text-muted-foreground sm:flex", role: "status", children: [
5818
- /* @__PURE__ */ jsx26("span", { className: "size-1.5 rounded-full bg-warning", "aria-hidden": true }),
6061
+ editing ? /* @__PURE__ */ jsxs25("div", { className: "flex shrink-0 items-center gap-2", children: [
6062
+ dirty ? /* @__PURE__ */ jsxs25("span", { className: "hidden items-center gap-1.5 text-xs text-muted-foreground sm:flex", role: "status", children: [
6063
+ /* @__PURE__ */ jsx27("span", { className: "size-1.5 rounded-full bg-warning", "aria-hidden": true }),
5819
6064
  "Unsaved"
5820
6065
  ] }) : null,
5821
- /* @__PURE__ */ jsx26(Button21, { variant: "quiet", disabled: busy, onClick: () => mode === "new" ? onCancelNew() : onMode("view"), children: dirty ? "Discard" : "Cancel" }),
5822
- /* @__PURE__ */ jsx26(Button21, { variant: "primary", disabled: busy || draft.name.trim() === "" || mode === "edit" && !dirty || mode === "new" && owner === "person" && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(recipient.trim()), onClick: () => void save(), children: mode === "new" && owner === "person" ? "Send" : "Save" })
5823
- ] }) : item ? /* @__PURE__ */ jsxs24("div", { className: "flex shrink-0 items-center gap-1", children: [
5824
- host.page && canUseOnSite(item, host.page.url) ? /* @__PURE__ */ jsx26(UseOnSiteButton, { port, item, pageUrl: host.page.url, onChanged: (next) => onChanged(next) }) : null,
5825
- host.fill && item.capabilities.canUse ? /* @__PURE__ */ jsx26(
5826
- Button21,
6066
+ /* @__PURE__ */ jsx27(Button22, { variant: "quiet", disabled: busy, onClick: () => mode === "new" ? onCancelNew() : onMode("view"), children: dirty ? "Discard" : "Cancel" }),
6067
+ /* @__PURE__ */ jsx27(Button22, { variant: "primary", disabled: busy || sent !== null || draft.name.trim() === "" || mode === "edit" && !dirty || mode === "new" && owner === "person" && !/^[^@\s]+@[^@\s]+\.[^@\s]+$/.test(recipient.trim()), onClick: () => void save(), children: mode === "new" && owner === "person" ? "Send" : "Save" })
6068
+ ] }) : item ? /* @__PURE__ */ jsxs25("div", { className: "flex shrink-0 items-center gap-1", children: [
6069
+ host.page && canUseOnSite(item, host.page.url) ? /* @__PURE__ */ jsx27(UseOnSiteButton, { port, item, pageUrl: host.page.url, onChanged: (next) => onChanged(next) }) : null,
6070
+ host.fill && item.capabilities.canUse ? /* @__PURE__ */ jsx27(
6071
+ Button22,
5827
6072
  {
5828
6073
  variant: "primary",
5829
6074
  onClick: () => void host.fill?.(item.id).then((outcome) => {
@@ -5833,44 +6078,44 @@ function ItemPane(props) {
5833
6078
  children: "Fill"
5834
6079
  }
5835
6080
  ) : null,
5836
- favorite ? /* @__PURE__ */ jsx26("span", { className: "hidden sm:contents", children: /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(StarGlyph, { className: favorite.on ? "fill-current text-warning" : "size-4" }), "aria-label": favorite.on ? "Remove from favorites" : "Add to favorites", pressed: favorite.on, onClick: favorite.toggle }) }) : null,
5837
- canManage ? /* @__PURE__ */ jsx26("span", { className: "hidden sm:contents", children: /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(ShareGlyph, {}), "aria-label": "Share", onClick: () => onPanel("share") }) }) : null,
5838
- canEdit ? /* @__PURE__ */ jsx26(Button21, { variant: "outline", icon: /* @__PURE__ */ jsx26(PencilGlyph, {}), collapse: "container", "aria-label": "Edit", onClick: () => onMode("edit"), children: "Edit" }) : null,
5839
- /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
5840
- /* @__PURE__ */ jsx26(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(MoreGlyph, {}), "aria-label": "More actions" }) }),
5841
- /* @__PURE__ */ jsxs24(DropdownMenuContent3, { align: "end", children: [
5842
- favorite ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: favorite.toggle, children: [
5843
- /* @__PURE__ */ jsx26(StarGlyph, { className: "size-4" }),
6081
+ favorite ? /* @__PURE__ */ jsx27("span", { className: "hidden sm:contents", children: /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(StarGlyph, { className: favorite.on ? "fill-current text-warning" : "size-4" }), "aria-label": favorite.on ? "Remove from favorites" : "Add to favorites", pressed: favorite.on, onClick: favorite.toggle }) }) : null,
6082
+ canManage ? /* @__PURE__ */ jsx27("span", { className: "hidden sm:contents", children: /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(ShareGlyph, {}), "aria-label": "Share", onClick: () => onPanel("share") }) }) : null,
6083
+ canEdit ? /* @__PURE__ */ jsx27(Button22, { variant: "outline", icon: /* @__PURE__ */ jsx27(PencilGlyph, {}), collapse: "container", "aria-label": "Edit", onClick: () => onMode("edit"), children: "Edit" }) : null,
6084
+ /* @__PURE__ */ jsxs25(DropdownMenu3, { children: [
6085
+ /* @__PURE__ */ jsx27(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(MoreGlyph, {}), "aria-label": "More actions" }) }),
6086
+ /* @__PURE__ */ jsxs25(DropdownMenuContent3, { align: "end", children: [
6087
+ favorite ? /* @__PURE__ */ jsxs25(DropdownMenuItem3, { onSelect: favorite.toggle, children: [
6088
+ /* @__PURE__ */ jsx27(StarGlyph, { className: "size-4" }),
5844
6089
  favorite.on ? "Remove from favorites" : "Add to favorites"
5845
6090
  ] }) : null,
5846
- canManage ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("share"), children: [
5847
- /* @__PURE__ */ jsx26(ShareGlyph, { className: "size-4" }),
6091
+ canManage ? /* @__PURE__ */ jsxs25(DropdownMenuItem3, { onSelect: () => onPanel("share"), children: [
6092
+ /* @__PURE__ */ jsx27(ShareGlyph, { className: "size-4" }),
5848
6093
  "Share"
5849
6094
  ] }) : null,
5850
- canManage ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("move"), children: [
5851
- /* @__PURE__ */ jsx26(MoveGlyph, { className: "size-4" }),
6095
+ canManage ? /* @__PURE__ */ jsxs25(DropdownMenuItem3, { onSelect: () => onPanel("move"), children: [
6096
+ /* @__PURE__ */ jsx27(MoveGlyph, { className: "size-4" }),
5852
6097
  "Move or copy"
5853
6098
  ] }) : null,
5854
- item.capabilities.canReveal ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("send"), children: [
5855
- /* @__PURE__ */ jsx26(SendGlyph, { className: "size-4" }),
6099
+ item.capabilities.canReveal ? /* @__PURE__ */ jsxs25(DropdownMenuItem3, { onSelect: () => onPanel("send"), children: [
6100
+ /* @__PURE__ */ jsx27(SendGlyph, { className: "size-4" }),
5856
6101
  "Send securely"
5857
6102
  ] }) : null,
5858
- /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("history"), children: [
5859
- /* @__PURE__ */ jsx26(HistoryIcon, { className: "size-4" }),
6103
+ /* @__PURE__ */ jsxs25(DropdownMenuItem3, { onSelect: () => onPanel("history"), children: [
6104
+ /* @__PURE__ */ jsx27(HistoryIcon, { className: "size-4" }),
5860
6105
  "Password history"
5861
6106
  ] }),
5862
- /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("activity"), children: [
5863
- /* @__PURE__ */ jsx26(ListGlyph, { className: "size-4" }),
6107
+ /* @__PURE__ */ jsxs25(DropdownMenuItem3, { onSelect: () => onPanel("activity"), children: [
6108
+ /* @__PURE__ */ jsx27(ListGlyph, { className: "size-4" }),
5864
6109
  "Activity"
5865
6110
  ] }),
5866
- canEdit ? /* @__PURE__ */ jsxs24(DropdownMenuItem3, { onSelect: () => onPanel("settings"), children: [
5867
- /* @__PURE__ */ jsx26(SettingsIcon, { className: "size-4" }),
6111
+ canEdit ? /* @__PURE__ */ jsxs25(DropdownMenuItem3, { onSelect: () => onPanel("settings"), children: [
6112
+ /* @__PURE__ */ jsx27(SettingsIcon, { className: "size-4" }),
5868
6113
  "Settings"
5869
6114
  ] }) : null,
5870
- canManage ? /* @__PURE__ */ jsxs24(Fragment16, { children: [
5871
- /* @__PURE__ */ jsx26(DropdownMenuSeparator3, {}),
5872
- /* @__PURE__ */ jsxs24(DropdownMenuItem3, { className: "text-destructive", disabled: busy, onSelect: () => void remove(), children: [
5873
- /* @__PURE__ */ jsx26(TrashGlyph, { className: "size-4" }),
6115
+ canManage ? /* @__PURE__ */ jsxs25(Fragment17, { children: [
6116
+ /* @__PURE__ */ jsx27(DropdownMenuSeparator3, {}),
6117
+ /* @__PURE__ */ jsxs25(DropdownMenuItem3, { className: "text-destructive", disabled: busy, onSelect: () => void remove(), children: [
6118
+ /* @__PURE__ */ jsx27(TrashGlyph, { className: "size-4" }),
5874
6119
  "Delete"
5875
6120
  ] })
5876
6121
  ] }) : null
@@ -5879,17 +6124,17 @@ function ItemPane(props) {
5879
6124
  ] }) : null
5880
6125
  ] });
5881
6126
  const filesProps = item ? { item, port, host, definition, organizations, arg: null, onClose: () => void 0, onChanged, onPanel } : null;
5882
- return /* @__PURE__ */ jsx26(RoomProvider, { value: room, children: /* @__PURE__ */ jsxs24("article", { ref: paneRef, "aria-label": item?.name ?? "New item", className: cn12(CONTROLS_CONTAINER_CLASS, "flex h-full min-h-0 flex-col bg-background"), children: [
6127
+ return /* @__PURE__ */ jsx27(RoomProvider, { value: room, children: /* @__PURE__ */ jsxs25("article", { ref: paneRef, "aria-label": item?.name ?? "New item", className: cn12(CONTROLS_CONTAINER_CLASS, "flex h-full min-h-0 flex-col bg-background"), children: [
5883
6128
  header,
5884
- error ? /* @__PURE__ */ jsx26("div", { role: "alert", className: "border-b border-border bg-muted px-5 py-2 text-sm text-destructive", children: error }) : null,
5885
- notice && !editing ? /* @__PURE__ */ jsx26("div", { role: "status", className: "border-b border-border bg-muted px-5 py-2 text-sm text-warning", children: notice }) : null,
5886
- item && !editing && (itemOff || offFields.length > 0) ? /* @__PURE__ */ jsxs24("div", { role: "status", className: "flex items-center gap-3 border-b border-border bg-muted px-5 py-2 text-sm", children: [
5887
- /* @__PURE__ */ jsx26("span", { className: "min-w-0 flex-1 truncate text-warning", children: offFields.length === 0 ? "This item is turned off" : offFields.length === 1 ? "1 field is turned off" : `${offFields.length} fields are turned off` }),
5888
- canTurnOn ? /* @__PURE__ */ jsx26(TurnOnButton, { label: "all fields", onTurnOn: () => turnOn(offFields) }) : null
6129
+ error ? /* @__PURE__ */ jsx27("div", { role: "alert", className: "border-b border-border bg-muted px-5 py-2 text-sm text-destructive", children: error }) : null,
6130
+ notice && !editing ? /* @__PURE__ */ jsx27("div", { role: "status", className: "border-b border-border bg-muted px-5 py-2 text-sm text-warning", children: notice }) : null,
6131
+ item && !editing && (itemOff || offFields.length > 0) ? /* @__PURE__ */ jsxs25("div", { role: "status", className: "flex items-center gap-3 border-b border-border bg-muted px-5 py-2 text-sm", children: [
6132
+ /* @__PURE__ */ jsx27("span", { className: "min-w-0 flex-1 truncate text-warning", children: offFields.length === 0 ? "This item is turned off" : offFields.length === 1 ? "1 field is turned off" : `${offFields.length} fields are turned off` }),
6133
+ canTurnOn ? /* @__PURE__ */ jsx27(TurnOnButton, { label: "all fields", onTurnOn: () => turnOn(offFields) }) : null
5889
6134
  ] }) : null,
5890
- /* @__PURE__ */ jsx26("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsx26("div", { className: "mx-auto flex w-full max-w-3xl flex-col gap-5 px-3 py-4 sm:px-6 sm:py-6", children: editing ? /* @__PURE__ */ jsxs24(Fragment16, { children: [
5891
- /* @__PURE__ */ jsxs24(VaultSection, { children: [
5892
- mode === "new" ? /* @__PURE__ */ jsx26(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx26(
6135
+ /* @__PURE__ */ jsx27("div", { className: "min-h-0 flex-1 overflow-y-auto", children: sent ? /* @__PURE__ */ jsx27(AssignResult, { sent, onAnother: createAnother, onDone: onCancelNew }) : /* @__PURE__ */ jsx27("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__ */ jsxs25(Fragment17, { children: [
6136
+ /* @__PURE__ */ jsxs25(VaultSection, { children: [
6137
+ mode === "new" ? /* @__PURE__ */ jsx27(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx27(
5893
6138
  OptionCombobox,
5894
6139
  {
5895
6140
  value: owner,
@@ -5904,39 +6149,39 @@ function ItemPane(props) {
5904
6149
  ],
5905
6150
  getLabel: (v) => v === "me" ? "Personal" : v === "person" ? "Someone else" : organizations.find((o) => o.id === v)?.name ?? v,
5906
6151
  getHint: (v) => v === "me" ? "Only you" : v === "person" ? "Sent by email" : sameNamed(v) ? `ID ${v.slice(0, 8)}` : null,
5907
- renderIcon: (v) => v === "me" ? /* @__PURE__ */ jsx26(PersonGlyph, { className: "size-4" }) : v === "person" ? /* @__PURE__ */ jsx26(SendGlyph, { className: "size-4" }) : /* @__PURE__ */ jsx26(BuildingGlyph, { className: "size-4" })
6152
+ renderIcon: (v) => v === "me" ? /* @__PURE__ */ jsx27(PersonGlyph, { className: "size-4" }) : v === "person" ? /* @__PURE__ */ jsx27(SendGlyph, { className: "size-4" }) : /* @__PURE__ */ jsx27(BuildingGlyph, { className: "size-4" })
5908
6153
  }
5909
6154
  ) }) : null,
5910
- /* @__PURE__ */ jsx26(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
5911
- mode === "new" && owner === "person" ? /* @__PURE__ */ jsxs24(Fragment16, { children: [
5912
- /* @__PURE__ */ jsx26(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
5913
- declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ jsx26(VaultRow, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ jsx26(Switch5, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
6155
+ /* @__PURE__ */ jsx27(EditRow, { label: "Name", value: draft.name, onChange: (v) => patch({ name: v }), placeholder: "Name", autoFocus: mode === "new" }),
6156
+ mode === "new" && owner === "person" ? /* @__PURE__ */ jsxs25(Fragment17, { children: [
6157
+ /* @__PURE__ */ jsx27(EditRow, { label: "Their email", value: recipient, placeholder: "name@company.com", inputMode: "email", onChange: setRecipient }),
6158
+ declared.some((f) => f.storage === "encrypted" && f.kind === "secret") ? /* @__PURE__ */ jsx27(VaultRow, { label: "Password", hint: "You never see it", children: /* @__PURE__ */ jsx27(Switch6, { checked: generatePrivately, onCheckedChange: setGeneratePrivately, "aria-label": "Generate the password privately" }) }) : null
5914
6159
  ] }) : null,
5915
6160
  declared.map((f) => {
5916
6161
  const existing = item?.fields.find((x) => x.key === f.key);
5917
6162
  const secretKind = f.storage === "encrypted" && f.kind === "secret";
5918
6163
  const value = f.storage === "metadata" ? metaValue(f.key) : draft.values[f.key] ?? "";
5919
6164
  const hidden = existing && existing.handling !== "visible" && !(f.key in loaded);
5920
- return /* @__PURE__ */ jsx26(
6165
+ return /* @__PURE__ */ jsx27(
5921
6166
  EditRow,
5922
6167
  {
5923
6168
  label: f.label,
5924
6169
  value,
5925
- placeholder: hidden ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : f.required ? "Required" : "",
6170
+ placeholder: hidden ? "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022" : f.required ? "Required" : isRecoveryCodesField(f) ? "Backup codes, one per line" : "",
5926
6171
  secret: secretKind,
5927
6172
  multiline: f.kind === "multiline",
5928
6173
  inputMode: f.kind === "url" ? "url" : USERNAME_KEYS.test(f.key) ? "email" : "text",
5929
6174
  onChange: (v) => setValue(f.key, v),
5930
- actions: /* @__PURE__ */ jsxs24(Fragment16, { children: [
5931
- hidden && existing?.handling === "revealable" && item?.capabilities.canReveal ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
5932
- secretKind ? /* @__PURE__ */ jsx26(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
5933
- existing ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
6175
+ actions: /* @__PURE__ */ jsxs25(Fragment17, { children: [
6176
+ hidden && existing?.handling === "revealable" && item?.capabilities.canReveal ? /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
6177
+ secretKind ? /* @__PURE__ */ jsx27(GenerateButton, { onUse: (v) => setValue(f.key, v) }) : null,
6178
+ existing ? /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${existing.id}`) }) : null
5934
6179
  ] })
5935
6180
  },
5936
6181
  f.key
5937
6182
  );
5938
6183
  }),
5939
- extraFields.map((f) => /* @__PURE__ */ jsx26(
6184
+ extraFields.map((f) => /* @__PURE__ */ jsx27(
5940
6185
  EditRow,
5941
6186
  {
5942
6187
  label: f.label,
@@ -5947,18 +6192,18 @@ function ItemPane(props) {
5947
6192
  onChange: (v) => setValue(f.key, v),
5948
6193
  onRemove: () => patch({ removed: [...draft.removed, f.id] }),
5949
6194
  removeLabel: `Delete ${f.label}`,
5950
- actions: /* @__PURE__ */ jsxs24(Fragment16, { children: [
5951
- f.handling === "revealable" && !(f.key in loaded) && item?.capabilities.canReveal ? /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
5952
- /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
6195
+ actions: /* @__PURE__ */ jsxs25(Fragment17, { children: [
6196
+ f.handling === "revealable" && !(f.key in loaded) && item?.capabilities.canReveal ? /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(EyeGlyph, {}), "aria-label": `Show current ${f.label}`, onClick: () => void loadForEdit(f.key) }) : null,
6197
+ /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(SettingsIcon, {}), "aria-label": `${f.label} settings`, onClick: () => onPanel(`field:${f.id}`) })
5953
6198
  ] })
5954
6199
  },
5955
6200
  f.id
5956
6201
  )),
5957
- draft.loginUrls.map((u, i) => /* @__PURE__ */ jsx26(
6202
+ draft.loginUrls.map((u, i) => /* @__PURE__ */ jsx27(
5958
6203
  EditRow,
5959
6204
  {
5960
6205
  label: i === 0 ? "Website" : `Website ${i + 1}`,
5961
- hint: destinations[i] && destinations[i].tone !== "success" ? /* @__PURE__ */ jsx26("span", { className: destinations[i].tone === "destructive" ? "text-destructive" : "text-warning", children: destinations[i].message }) : void 0,
6206
+ hint: destinations[i] && destinations[i].tone !== "success" ? /* @__PURE__ */ jsx27("span", { className: destinations[i].tone === "destructive" ? "text-destructive" : "text-warning", children: destinations[i].message }) : void 0,
5962
6207
  value: u,
5963
6208
  autoFocus: i > 0 && u === "" && i === draft.loginUrls.length - 1,
5964
6209
  placeholder: "https://",
@@ -5978,10 +6223,11 @@ function ItemPane(props) {
5978
6223
  },
5979
6224
  i
5980
6225
  )),
5981
- /* @__PURE__ */ jsx26(AddRow, { label: draft.loginUrls.length === 0 ? "Website" : "", onAdd: () => patch({ loginUrls: [...draft.loginUrls, ""] }), children: draft.loginUrls.length === 0 ? "Add website" : "Add another website" }),
5982
- /* @__PURE__ */ jsx26(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator || seedField), item, port, onEnrolled: onChanged }),
5983
- item && isLogin && !item.authenticator ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null,
5984
- recoveryEditing ? /* @__PURE__ */ jsx26(
6226
+ /* @__PURE__ */ jsx27(AddRow, { label: draft.loginUrls.length === 0 ? "Website" : "", onAdd: () => patch({ loginUrls: [...draft.loginUrls, ""] }), children: draft.loginUrls.length === 0 ? "Add website" : "Add another website" }),
6227
+ /* @__PURE__ */ jsx27(TotpEditRow, { value: draft.authenticator, onChange: (v) => patch({ authenticator: v }), hasExisting: Boolean(item?.authenticator || seedField), item, port, onEnrolled: onChanged }),
6228
+ item && isLogin && !item.authenticator ? /* @__PURE__ */ jsx27(TwoFactorMethodRow, { port, item, onChanged }) : null,
6229
+ !item && isLogin && draft.authenticator.trim() === "" ? /* @__PURE__ */ jsx27(DraftTwoFactorRow, { custom: draft.custom, onCustom: (custom) => patch({ custom }) }) : null,
6230
+ recoveryEditing ? /* @__PURE__ */ jsx27(
5985
6231
  EditRow,
5986
6232
  {
5987
6233
  label: "Recovery codes",
@@ -6000,26 +6246,30 @@ function ItemPane(props) {
6000
6246
  },
6001
6247
  removeLabel: "Remove recovery codes"
6002
6248
  }
6003
- ) : !recoveryDeclared && !recoveryExtra && offerRecovery ? /* @__PURE__ */ jsx26(AddRow, { label: "Recovery codes", onAdd: () => setShowRecovery(true), children: "Add backup codes" }) : null
6249
+ ) : !recoveryDeclared && !recoveryExtra && offerRecovery ? /* @__PURE__ */ jsx27(AddRow, { label: "Recovery codes", onAdd: () => setShowRecovery(true), children: "Add backup codes" }) : null
6004
6250
  ] }),
6005
- /* @__PURE__ */ jsx26(VaultSection, { children: /* @__PURE__ */ jsx26(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
6006
- /* @__PURE__ */ jsxs24(
6251
+ /* @__PURE__ */ jsx27(VaultSection, { children: /* @__PURE__ */ jsx27(EditRow, { label: "Notes", value: draft.notes, multiline: true, placeholder: "Anything worth remembering", onChange: (v) => patch({ notes: v }) }) }),
6252
+ /* @__PURE__ */ jsxs25(
6007
6253
  VaultSection,
6008
6254
  {
6009
6255
  title: "More",
6010
- actions: /* @__PURE__ */ jsxs24(DropdownMenu3, { children: [
6011
- /* @__PURE__ */ jsx26(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx26(Button21, { variant: "quiet", icon: /* @__PURE__ */ jsx26(PlusGlyph, {}), children: "Add" }) }),
6012
- /* @__PURE__ */ jsxs24(DropdownMenuContent3, { align: "end", children: [
6013
- /* @__PURE__ */ jsx26(DropdownMenuItem3, { onSelect: () => patch({ secrets: [...draft.secrets, { key: "", label: "", value: "" }] }), children: "Secret field" }),
6014
- /* @__PURE__ */ jsx26(DropdownMenuItem3, { onSelect: () => patch({ custom: [...draft.custom, { key: `custom_${draft.custom.length + 1}_${Date.now() % 1e5}`, label: "", value: "" }] }), children: "Text field" }),
6015
- !tagsVisible ? /* @__PURE__ */ jsx26(DropdownMenuItem3, { onSelect: () => setShowTags(true), children: "Tags" }) : null,
6016
- !descriptionVisible ? /* @__PURE__ */ jsx26(DropdownMenuItem3, { onSelect: () => setShowDescription(true), children: "Description" }) : null,
6017
- !recoveryDeclared && !recoveryExtra && !recoveryEditing ? /* @__PURE__ */ jsx26(DropdownMenuItem3, { onSelect: () => setShowRecovery(true), children: "Recovery codes" }) : null
6256
+ actions: /* @__PURE__ */ jsxs25(DropdownMenu3, { children: [
6257
+ /* @__PURE__ */ jsx27(DropdownMenuTrigger3, { asChild: true, children: /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(PlusGlyph, {}), children: "Add" }) }),
6258
+ /* @__PURE__ */ jsxs25(DropdownMenuContent3, { align: "end", children: [
6259
+ /* @__PURE__ */ jsx27(DropdownMenuItem3, { onSelect: () => patch({ secrets: [...draft.secrets, { key: "", label: "", value: "" }] }), children: "Secret field" }),
6260
+ /* @__PURE__ */ jsx27(DropdownMenuItem3, { onSelect: () => patch({ custom: [...draft.custom, { key: `custom_${draft.custom.length + 1}_${Date.now() % 1e5}`, label: "", value: "" }] }), children: "Text field" }),
6261
+ !tagsVisible ? /* @__PURE__ */ jsx27(DropdownMenuItem3, { onSelect: () => setShowTags(true), children: "Tags" }) : null,
6262
+ !descriptionVisible ? /* @__PURE__ */ jsx27(DropdownMenuItem3, { onSelect: () => setShowDescription(true), children: "Description" }) : null,
6263
+ mode === "new" && !showBrowser ? /* @__PURE__ */ jsx27(DropdownMenuItem3, { onSelect: () => {
6264
+ setShowBrowser(true);
6265
+ if (!draft.browser) patch({ browser: defaultBrowserSettings(draft.loginUrls.some((u) => u.trim() !== "")) });
6266
+ }, children: "Browser settings" }) : null,
6267
+ !recoveryDeclared && !recoveryExtra && !recoveryEditing ? /* @__PURE__ */ jsx27(DropdownMenuItem3, { onSelect: () => setShowRecovery(true), children: "Recovery codes" }) : null
6018
6268
  ] })
6019
6269
  ] }),
6020
6270
  children: [
6021
- descriptionVisible ? /* @__PURE__ */ jsx26(EditRow, { label: "Description", value: draft.description, placeholder: "What this is for", onChange: (v) => patch({ description: v }) }) : null,
6022
- tagsVisible ? /* @__PURE__ */ jsx26(
6271
+ descriptionVisible ? /* @__PURE__ */ jsx27(EditRow, { label: "Description", value: draft.description, placeholder: "What this is for", onChange: (v) => patch({ description: v }) }) : null,
6272
+ tagsVisible ? /* @__PURE__ */ jsx27(
6023
6273
  EditRow,
6024
6274
  {
6025
6275
  label: "Tags",
@@ -6031,49 +6281,50 @@ function ItemPane(props) {
6031
6281
  }
6032
6282
  }
6033
6283
  ) : null,
6034
- draft.secrets.map((s, i) => /* @__PURE__ */ jsx26(CustomEditRow, { label: s.label, value: s.value, secret: true, onLabel: (v) => patch({ secrets: draft.secrets.map((x, j) => j === i ? { ...x, label: v } : x) }), onValue: (v) => patch({ secrets: draft.secrets.map((x, j) => j === i ? { ...x, value: v } : x) }), onRemove: () => patch({ secrets: draft.secrets.filter((_, j) => j !== i) }) }, `s${i}`)),
6035
- extraCustom.map((c) => /* @__PURE__ */ jsx26(CustomEditRow, { label: c.label, value: c.value, secret: false, onLabel: (v) => patch({ custom: draft.custom.map((x) => x.key === c.key ? { ...x, label: v } : x) }), onValue: (v) => patch({ custom: draft.custom.map((x) => x.key === c.key ? { ...x, value: v } : x) }), onRemove: () => patch({ custom: draft.custom.filter((x) => x.key !== c.key) }) }, c.key)),
6036
- !descriptionVisible && !tagsVisible && draft.secrets.length === 0 && extraCustom.length === 0 ? /* @__PURE__ */ jsx26(AddRow, { label: "Tags", onAdd: () => setShowTags(true), children: "Add tags" }) : null
6284
+ mode === "new" && showBrowser && draft.browser ? /* @__PURE__ */ jsx27(DraftBrowserRows, { value: draft.browser, hasWebsite: draft.loginUrls.some((u) => u.trim() !== ""), onChange: (browser) => patch({ browser }) }) : null,
6285
+ draft.secrets.map((s, i) => /* @__PURE__ */ jsx27(SecretBuilderRow, { field: s, onChange: (p) => setDraft((d) => ({ ...d, secrets: d.secrets.map((x, j) => j === i ? { ...x, ...p } : x) })), onRemove: () => patch({ secrets: draft.secrets.filter((_, j) => j !== i) }) }, `s${i}`)),
6286
+ extraCustom.map((c) => /* @__PURE__ */ jsx27(CustomEditRow, { label: c.label, value: c.value, secret: false, onLabel: (v) => patch({ custom: draft.custom.map((x) => x.key === c.key ? { ...x, label: v } : x) }), onValue: (v) => patch({ custom: draft.custom.map((x) => x.key === c.key ? { ...x, value: v } : x) }), onRemove: () => patch({ custom: draft.custom.filter((x) => x.key !== c.key) }) }, c.key)),
6287
+ !descriptionVisible && !tagsVisible && draft.secrets.length === 0 && extraCustom.length === 0 ? /* @__PURE__ */ jsx27(AddRow, { label: "Tags", onAdd: () => setShowTags(true), children: "Add tags" }) : null
6037
6288
  ]
6038
6289
  }
6039
6290
  ),
6040
- filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: true }) : null
6041
- ] }) : item ? /* @__PURE__ */ jsxs24(Fragment16, { children: [
6042
- /* @__PURE__ */ jsxs24(VaultSection, { children: [
6291
+ filesProps ? /* @__PURE__ */ jsx27(FilesSection, { ...filesProps, editing: true }) : mode === "new" && owner !== "person" ? /* @__PURE__ */ jsx27(DraftFilesSection, { files: queuedFiles, onFiles: setQueuedFiles }) : null
6292
+ ] }) : item ? /* @__PURE__ */ jsxs25(Fragment17, { children: [
6293
+ /* @__PURE__ */ jsxs25(VaultSection, { children: [
6043
6294
  declared.map((f) => {
6044
6295
  if (f.storage === "metadata") {
6045
6296
  const v = metaValue(f.key);
6046
- return v ? /* @__PURE__ */ jsx26(PlainRow, { label: f.label, value: v, openUrl: host.openUrl }, f.key) : null;
6297
+ return v ? /* @__PURE__ */ jsx27(PlainRow, { label: f.label, value: v, openUrl: host.openUrl }, f.key) : null;
6047
6298
  }
6048
6299
  const field = item.fields.find((x) => x.key === f.key);
6049
- if (isRecoveryCodesField(f)) return /* @__PURE__ */ jsx26(RecoveryCodesRow, { item, field, port, onChanged }, f.key);
6050
- return field ? /* @__PURE__ */ jsx26(SecretRow, { port, item, field, onTurnOn: turnOnOne(field) }, field.id) : null;
6300
+ if (isRecoveryCodesField(f)) return /* @__PURE__ */ jsx27(RecoveryCodesRow, { item, field, port, onChanged }, f.key);
6301
+ return field ? /* @__PURE__ */ jsx27(SecretRow, { port, item, field, onTurnOn: turnOnOne(field), extra: fieldSettings(field) }, field.id) : null;
6051
6302
  }),
6052
- extraFields.map((f) => isRecoveryCodesField(f) ? /* @__PURE__ */ jsx26(RecoveryCodesRow, { item, field: f, port, onChanged }, f.id) : /* @__PURE__ */ jsx26(SecretRow, { port, item, field: f, onTurnOn: turnOnOne(f) }, f.id)),
6053
- item.loginUrls.length > 0 ? item.loginUrls.map((u, i) => /* @__PURE__ */ jsx26(PlainRow, { label: i === 0 ? "Website" : `Website ${i + 1}`, value: u, openUrl: host.openUrl }, `${u}-${i}`)) : /* @__PURE__ */ jsx26(AddRow, { label: "Website", onAdd: canEdit ? () => onMode("edit") : null, children: "Add website" }),
6054
- item.authenticator ? /* @__PURE__ */ jsx26(TotpRow, { port, item, onChanged }) : seedField && !seedField.active ? (
6303
+ extraFields.map((f) => isRecoveryCodesField(f) ? /* @__PURE__ */ jsx27(RecoveryCodesRow, { item, field: f, port, onChanged }, f.id) : /* @__PURE__ */ jsx27(SecretRow, { port, item, field: f, onTurnOn: turnOnOne(f), extra: fieldSettings(f) }, f.id)),
6304
+ item.loginUrls.length > 0 ? item.loginUrls.map((u, i) => /* @__PURE__ */ jsx27(PlainRow, { label: i === 0 ? "Website" : `Website ${i + 1}`, value: u, openUrl: host.openUrl }, `${u}-${i}`)) : /* @__PURE__ */ jsx27(AddRow, { label: "Website", onAdd: canEdit ? () => onMode("edit") : null, children: "Add website" }),
6305
+ item.authenticator ? /* @__PURE__ */ jsx27(TotpRow, { port, item, onChanged }) : seedField && !seedField.active ? (
6055
6306
  // The secret is still there, only off: turning it on brings the codes back. Never "Set up",
6056
6307
  // which would invite replacing a working two-factor secret.
6057
- /* @__PURE__ */ jsx26(VaultRow, { label: "Authenticator", actions: canTurnOn ? /* @__PURE__ */ jsx26(TurnOnButton, { label: "Authenticator", onTurnOn: () => turnOn([seedField]) }) : null, children: /* @__PURE__ */ jsx26("span", { className: "text-muted-foreground", children: "Turned off" }) })
6058
- ) : /* @__PURE__ */ jsx26(AddRow, { label: "Authenticator", onAdd: canEdit ? () => setSettingUpOtp(true) : null, children: "Set up" }),
6059
- !recoveryDeclared && !recoveryExtra && offerRecovery ? /* @__PURE__ */ jsx26(RecoveryCodesRow, { item, field: null, port, onChanged }) : null,
6060
- !item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ jsx26(TwoFactorMethodRow, { port, item, onChanged }) : null
6308
+ /* @__PURE__ */ jsx27(VaultRow, { label: "Authenticator", actions: canTurnOn ? /* @__PURE__ */ jsx27(TurnOnButton, { label: "Authenticator", onTurnOn: () => turnOn([seedField]) }) : null, children: /* @__PURE__ */ jsx27("span", { className: "text-muted-foreground", children: "Turned off" }) })
6309
+ ) : /* @__PURE__ */ jsx27(AddRow, { label: "Authenticator", onAdd: canEdit ? () => setSettingUpOtp(true) : null, children: "Set up" }),
6310
+ !recoveryDeclared && !recoveryExtra && offerRecovery ? /* @__PURE__ */ jsx27(RecoveryCodesRow, { item, field: null, port, onChanged }) : null,
6311
+ !item.authenticator && item.custom.some((c) => c.key === MFA_METHOD_KEY && c.value) ? /* @__PURE__ */ jsx27(TwoFactorMethodRow, { port, item, onChanged }) : null
6061
6312
  ] }),
6062
- /* @__PURE__ */ jsx26(VaultSection, { children: item.notes ? /* @__PURE__ */ jsx26(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ jsx26(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
6063
- item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs24(VaultSection, { title: "More", children: [
6064
- item.description ? /* @__PURE__ */ jsx26(PlainRow, { label: "Description", value: item.description }) : null,
6065
- item.tags.length > 0 ? /* @__PURE__ */ jsx26(VaultRow, { label: "Tags", children: /* @__PURE__ */ jsx26("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ jsx26("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
6066
- viewCustom.map((c) => /* @__PURE__ */ jsx26(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
6313
+ /* @__PURE__ */ jsx27(VaultSection, { children: item.notes ? /* @__PURE__ */ jsx27(PlainRow, { label: "Notes", value: item.notes, multiline: true }) : /* @__PURE__ */ jsx27(AddRow, { label: "Notes", onAdd: canEdit ? () => onMode("edit") : null, children: "Add notes" }) }),
6314
+ item.description || item.tags.length > 0 || viewCustom.length > 0 ? /* @__PURE__ */ jsxs25(VaultSection, { title: "More", children: [
6315
+ item.description ? /* @__PURE__ */ jsx27(PlainRow, { label: "Description", value: item.description }) : null,
6316
+ item.tags.length > 0 ? /* @__PURE__ */ jsx27(VaultRow, { label: "Tags", children: /* @__PURE__ */ jsx27("div", { className: "flex flex-wrap gap-1", children: item.tags.map((t) => /* @__PURE__ */ jsx27("span", { className: "rounded-md bg-muted px-1.5 py-0.5 text-xs", children: t }, t)) }) }) : null,
6317
+ viewCustom.map((c) => /* @__PURE__ */ jsx27(PlainRow, { label: c.label, value: c.value, openUrl: host.openUrl }, c.key))
6067
6318
  ] }) : null,
6068
- filesProps ? /* @__PURE__ */ jsx26(FilesSection, { ...filesProps, editing: false }) : null,
6069
- /* @__PURE__ */ jsxs24("p", { className: cn12("px-1 text-xs text-muted-foreground"), children: [
6319
+ filesProps ? /* @__PURE__ */ jsx27(FilesSection, { ...filesProps, editing: false }) : null,
6320
+ /* @__PURE__ */ jsxs25("p", { className: cn12("px-1 text-xs text-muted-foreground"), children: [
6070
6321
  "Modified ",
6071
6322
  formatAbsoluteDate3(item.updatedAt, DAY_FORMAT, ""),
6072
6323
  " \xB7 Created ",
6073
6324
  formatAbsoluteDate3(item.createdAt, DAY_FORMAT, "")
6074
6325
  ] })
6075
6326
  ] }) : null }) }),
6076
- settingUpOtp && item ? /* @__PURE__ */ jsx26(
6327
+ settingUpOtp && item ? /* @__PURE__ */ jsx27(
6077
6328
  AddOtpPanel,
6078
6329
  {
6079
6330
  port,
@@ -6092,18 +6343,21 @@ function ItemPane(props) {
6092
6343
  }
6093
6344
 
6094
6345
  // src/ItemList.tsx
6095
- import { jsx as jsx27, jsxs as jsxs25 } from "react/jsx-runtime";
6346
+ import { jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
6096
6347
  var SORTS2 = [
6097
- { value: "name", label: "Name" },
6348
+ { value: "name", label: "Name A\u2013Z" },
6349
+ { value: "name-desc", label: "Name Z\u2013A" },
6098
6350
  { value: "website", label: "Website" },
6099
6351
  { value: "updated", label: "Recently changed" },
6100
- { value: "created", label: "Recently added" }
6352
+ { value: "created", label: "Recently added" },
6353
+ { value: "viewed", label: "Recently viewed" }
6101
6354
  ];
6102
6355
  function subtitleOf(item, withOwner) {
6103
6356
  const what = loginSiteOf(item) || item.definitionLabel;
6104
6357
  return withOwner ? `${what} \xB7 ${item.owner.label}` : what;
6105
6358
  }
6106
- function ItemList({ title, items, definitions, port, selectedId, onSelect, query, onQuery, sort, onSort, onNew, matchingIds, header, showOwner }) {
6359
+ function ItemList({ title, items, definitions, port, selectedId, onSelect, query, onQuery, sort, onSort, onNew, matchingIds, header, showOwner, canSortViewed = false }) {
6360
+ const sorts = SORTS2.filter((s) => canSortViewed || s.value !== "viewed");
6107
6361
  const pinned = matchingIds ? items.filter((i) => matchingIds.has(i.id)) : [];
6108
6362
  const rest = matchingIds ? items.filter((i) => !matchingIds.has(i.id)) : items;
6109
6363
  const ordered = [...pinned, ...rest];
@@ -6123,34 +6377,34 @@ function ItemList({ title, items, definitions, port, selectedId, onSelect, query
6123
6377
  }
6124
6378
  };
6125
6379
  const mixedOwners = showOwner ?? new Set(items.map((i) => i.owner.organizationId ?? i.owner.kind)).size > 1;
6126
- const row = (i) => /* @__PURE__ */ jsx27(ListRow, { item: i, family: familyOf2(i.definitionKey), port, on: i.id === selectedId, onSelect, withOwner: mixedOwners }, i.id);
6127
- const sortLabel = SORTS2.find((s) => s.value === sort)?.label ?? "Name";
6128
- return /* @__PURE__ */ jsxs25("section", { "aria-label": title, className: "flex h-full min-h-0 flex-col border-r border-border bg-background", children: [
6129
- /* @__PURE__ */ jsxs25("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children: [
6380
+ const row = (i) => /* @__PURE__ */ jsx28(ListRow, { item: i, family: familyOf2(i.definitionKey), port, on: i.id === selectedId, onSelect, withOwner: mixedOwners }, i.id);
6381
+ const sortLabel = sorts.find((s) => s.value === sort)?.label ?? "Name A\u2013Z";
6382
+ return /* @__PURE__ */ jsxs26("section", { "aria-label": title, className: "flex h-full min-h-0 flex-col border-r border-border bg-background", children: [
6383
+ /* @__PURE__ */ jsxs26("div", { className: "flex flex-col gap-2 px-3 pb-2 pt-3", children: [
6130
6384
  header,
6131
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center gap-2", children: [
6132
- /* @__PURE__ */ jsx27(SearchField, { value: query, onChange: (e) => onQuery(e.target.value), onKeyDown, placeholder: `Search ${title}`, className: "min-w-0 flex-1", "aria-label": "Search the vault" }),
6133
- /* @__PURE__ */ jsx27(Button22, { variant: "primary", icon: /* @__PURE__ */ jsx27(PlusGlyph, {}), "aria-label": "New item", onClick: onNew })
6385
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center gap-2", children: [
6386
+ /* @__PURE__ */ jsx28(SearchField, { value: query, onChange: (e) => onQuery(e.target.value), onKeyDown, placeholder: `Search ${title}`, className: "min-w-0 flex-1", "aria-label": "Search the vault" }),
6387
+ /* @__PURE__ */ jsx28(Button23, { variant: "primary", icon: /* @__PURE__ */ jsx28(PlusGlyph, {}), "aria-label": "New item", onClick: onNew })
6134
6388
  ] }),
6135
- /* @__PURE__ */ jsxs25("div", { className: "flex items-center justify-between gap-2 px-1", children: [
6136
- /* @__PURE__ */ jsxs25("span", { className: "truncate text-xs text-muted-foreground", children: [
6389
+ /* @__PURE__ */ jsxs26("div", { className: "flex items-center justify-between gap-2 px-1", children: [
6390
+ /* @__PURE__ */ jsxs26("span", { className: "truncate text-xs text-muted-foreground", children: [
6137
6391
  items.length,
6138
6392
  " ",
6139
6393
  items.length === 1 ? "item" : "items"
6140
6394
  ] }),
6141
- /* @__PURE__ */ jsxs25(DropdownMenu4, { children: [
6142
- /* @__PURE__ */ jsx27(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(SortGlyph, {}), "aria-label": `Sort: ${sortLabel}`, children: sortLabel }) }),
6143
- /* @__PURE__ */ jsx27(DropdownMenuContent4, { align: "end", children: /* @__PURE__ */ jsx27(DropdownMenuRadioGroup, { value: sort, onValueChange: (v) => onSort(SORTS2.find((s) => s.value === v)?.value ?? "name"), children: SORTS2.map((s) => /* @__PURE__ */ jsx27(DropdownMenuRadioItem, { value: s.value, children: s.label }, s.value)) }) })
6395
+ /* @__PURE__ */ jsxs26(DropdownMenu4, { children: [
6396
+ /* @__PURE__ */ jsx28(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx28(Button23, { variant: "quiet", icon: /* @__PURE__ */ jsx28(SortGlyph, {}), "aria-label": `Sort: ${sortLabel}`, children: sortLabel }) }),
6397
+ /* @__PURE__ */ jsx28(DropdownMenuContent4, { align: "end", children: /* @__PURE__ */ jsx28(DropdownMenuRadioGroup, { value: sort, onValueChange: (v) => onSort(sorts.find((s) => s.value === v)?.value ?? "name"), children: sorts.map((s) => /* @__PURE__ */ jsx28(DropdownMenuRadioItem, { value: s.value, children: s.label }, s.value)) }) })
6144
6398
  ] })
6145
6399
  ] })
6146
6400
  ] }),
6147
- /* @__PURE__ */ jsx27("div", { className: "min-h-0 flex-1 overflow-y-auto px-2 pb-3", onKeyDown, children: items.length === 0 ? /* @__PURE__ */ jsxs25("div", { className: "flex flex-col items-center gap-3 px-4 py-12 text-center", children: [
6148
- /* @__PURE__ */ jsx27("span", { className: "text-sm text-muted-foreground", children: query ? `Nothing matches \u201C${query}\u201D.` : "Nothing here yet." }),
6149
- query ? /* @__PURE__ */ jsx27(Button22, { variant: "outline", onClick: () => onQuery(""), children: "Clear search" }) : /* @__PURE__ */ jsx27(Button22, { variant: "outline", icon: /* @__PURE__ */ jsx27(PlusGlyph, {}), onClick: onNew, children: "New item" })
6150
- ] }) : /* @__PURE__ */ jsxs25("ul", { ref: listRef, className: "flex flex-col gap-px", children: [
6151
- pinned.length > 0 ? /* @__PURE__ */ jsx27("li", { className: "px-2 pb-1 pt-1 text-xs font-medium text-muted-foreground", children: "This page" }) : null,
6401
+ /* @__PURE__ */ jsx28("div", { className: "min-h-0 flex-1 overflow-y-auto px-2 pb-3", onKeyDown, children: items.length === 0 ? /* @__PURE__ */ jsxs26("div", { className: "flex flex-col items-center gap-3 px-4 py-12 text-center", children: [
6402
+ /* @__PURE__ */ jsx28("span", { className: "text-sm text-muted-foreground", children: query ? `Nothing matches \u201C${query}\u201D.` : "Nothing here yet." }),
6403
+ query ? /* @__PURE__ */ jsx28(Button23, { variant: "outline", onClick: () => onQuery(""), children: "Clear search" }) : /* @__PURE__ */ jsx28(Button23, { variant: "outline", icon: /* @__PURE__ */ jsx28(PlusGlyph, {}), onClick: onNew, children: "New item" })
6404
+ ] }) : /* @__PURE__ */ jsxs26("ul", { ref: listRef, className: "flex flex-col gap-px", children: [
6405
+ pinned.length > 0 ? /* @__PURE__ */ jsx28("li", { className: "px-2 pb-1 pt-1 text-xs font-medium text-muted-foreground", children: "This page" }) : null,
6152
6406
  pinned.map(row),
6153
- pinned.length > 0 && rest.length > 0 ? /* @__PURE__ */ jsx27("li", { className: "px-2 pb-1 pt-3 text-xs font-medium text-muted-foreground", children: "Everything else" }) : null,
6407
+ pinned.length > 0 && rest.length > 0 ? /* @__PURE__ */ jsx28("li", { className: "px-2 pb-1 pt-3 text-xs font-medium text-muted-foreground", children: "Everything else" }) : null,
6154
6408
  rest.map(row)
6155
6409
  ] }) })
6156
6410
  ] });
@@ -6159,48 +6413,93 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
6159
6413
  const confirmed = useConfirmed();
6160
6414
  const copy = useCopy();
6161
6415
  const notify = useNotify();
6162
- const [busy, setBusy] = useState27(false);
6163
- const user = item.fields.find((f) => USERNAME_KEYS.test(f.key) && f.handling !== "sealed");
6164
- const secret = item.fields.find((f) => f.key === "password" && f.handling === "revealable");
6165
- const quick = async (key, label) => {
6416
+ const [busy, setBusy] = useState28(false);
6417
+ const [menuOpen, setMenuOpen] = useState28(false);
6418
+ const canUse = item.capabilities.canUse;
6419
+ const user = canUse ? item.fields.find((f) => USERNAME_KEYS.test(f.key) && f.handling !== "sealed" && f.active !== false) : void 0;
6420
+ const secret = canUse && item.capabilities.canReveal ? item.fields.find((f) => f.key === "password" && f.handling === "revealable" && f.active !== false) : void 0;
6421
+ const code = canUse && item.authenticator?.enabled ? item.authenticator : null;
6422
+ const run = async (label, read, isSecret) => {
6166
6423
  setBusy(true);
6167
6424
  try {
6168
- const v = await confirmed(() => port.reveal(item, key));
6169
- await copy(v, label, { secret: key !== user?.key || user.handling !== "visible" });
6425
+ const v = await confirmed(read);
6426
+ await copy(v, label, { secret: isSecret });
6170
6427
  } catch (e) {
6171
6428
  if (!wasCancelled(e)) notify(e instanceof Error ? e.message : `${label} could not be read`, "error");
6172
6429
  } finally {
6173
6430
  setBusy(false);
6174
6431
  }
6175
6432
  };
6176
- return /* @__PURE__ */ jsxs25("li", { className: "group relative", "data-item": item.id, children: [
6177
- /* @__PURE__ */ jsxs25(
6433
+ const copyUser = () => user && void run(user.label, () => port.reveal(item, user.key), user.handling !== "visible");
6434
+ const copyPassword = () => secret && void run("Password", () => port.reveal(item, secret.key), true);
6435
+ const copyCode = () => code && void run("One-time code", async () => (await port.authenticator.code(item)).code, true);
6436
+ const copyName = () => void copy(item.name, "Name", { secret: false });
6437
+ return /* @__PURE__ */ jsxs26("li", { className: "group relative", "data-item": item.id, children: [
6438
+ /* @__PURE__ */ jsxs26(
6178
6439
  "button",
6179
6440
  {
6180
6441
  type: "button",
6181
6442
  "aria-current": on ? "true" : void 0,
6182
6443
  "data-surface": on ? "primary" : void 0,
6183
6444
  onClick: () => onSelect(item.id),
6184
- className: cn13("flex h-12 w-full items-center gap-3 rounded-lg px-2 text-left", on ? "bg-primary text-primary-foreground" : "hover:bg-accent"),
6445
+ className: cn13("flex h-12 w-full items-center gap-3 rounded-lg px-2 pr-10 text-left", on ? "bg-primary text-primary-foreground" : "hover:bg-accent"),
6185
6446
  children: [
6186
- /* @__PURE__ */ jsx27(ItemIcon, { definitionKey: item.definitionKey, family, site: loginSiteOf(item), inverted: on }),
6187
- /* @__PURE__ */ jsxs25("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6188
- /* @__PURE__ */ jsx27("span", { className: "truncate text-sm font-medium", children: item.name }),
6189
- /* @__PURE__ */ jsx27("span", { className: "truncate text-xs text-muted-foreground", children: subtitleOf(item, withOwner) })
6447
+ /* @__PURE__ */ jsx28(ItemIcon, { definitionKey: item.definitionKey, family, site: loginSiteOf(item), inverted: on }),
6448
+ /* @__PURE__ */ jsxs26("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6449
+ /* @__PURE__ */ jsx28("span", { className: "truncate text-sm font-medium", children: item.name }),
6450
+ /* @__PURE__ */ jsx28("span", { className: "truncate text-xs text-muted-foreground", children: subtitleOf(item, withOwner) })
6190
6451
  ] })
6191
6452
  ]
6192
6453
  }
6193
6454
  ),
6194
- item.capabilities.canUse && (user || secret && item.capabilities.canReveal) ? /* @__PURE__ */ jsxs25("div", { className: cn13("absolute right-1.5 top-1/2 hidden -translate-y-1/2 items-center gap-0.5 rounded-md pl-2 group-hover:flex", on ? "bg-primary" : "bg-accent"), "data-surface": on ? "primary" : void 0, children: [
6195
- user ? /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(UserGlyph, {}), "aria-label": `Copy ${user.label}`, disabled: busy, onClick: () => void quick(user.key, user.label) }) : null,
6196
- secret && item.capabilities.canReveal ? /* @__PURE__ */ jsx27(Button22, { variant: "quiet", icon: /* @__PURE__ */ jsx27(KeyGlyph, {}), "aria-label": "Copy password", disabled: busy, onClick: () => void quick(secret.key, "Password") }) : null
6197
- ] }) : null
6455
+ /* @__PURE__ */ jsxs26("div", { className: "absolute right-1.5 top-1/2 flex -translate-y-1/2 items-center gap-0.5", "data-surface": on ? "primary" : void 0, children: [
6456
+ user || secret ? /* @__PURE__ */ jsxs26("div", { className: cn13("hidden items-center gap-0.5 rounded-md pl-2 [@media(hover:hover)]:group-hover:flex [@media(hover:hover)]:group-focus-within:flex", on ? "bg-primary" : "bg-accent"), "data-row-quick": "", children: [
6457
+ user ? /* @__PURE__ */ jsx28(Button23, { variant: "quiet", icon: /* @__PURE__ */ jsx28(UserGlyph, {}), "aria-label": `Copy ${user.label}`, disabled: busy, onClick: copyUser }) : null,
6458
+ secret ? /* @__PURE__ */ jsx28(Button23, { variant: "quiet", icon: /* @__PURE__ */ jsx28(KeyGlyph, {}), "aria-label": "Copy password", disabled: busy, onClick: copyPassword }) : null
6459
+ ] }) : null,
6460
+ /* @__PURE__ */ jsxs26(DropdownMenu4, { open: menuOpen, onOpenChange: setMenuOpen, children: [
6461
+ /* @__PURE__ */ jsx28(DropdownMenuTrigger4, { asChild: true, children: /* @__PURE__ */ jsx28(
6462
+ Button23,
6463
+ {
6464
+ variant: "quiet",
6465
+ icon: /* @__PURE__ */ jsx28(MoreGlyph, {}),
6466
+ "aria-label": `Actions for ${item.name}`,
6467
+ disabled: busy,
6468
+ className: cn13("[@media(hover:hover)]:invisible [@media(hover:hover)]:group-hover:visible [@media(hover:hover)]:group-focus-within:visible", menuOpen && "[@media(hover:hover)]:visible")
6469
+ }
6470
+ ) }),
6471
+ /* @__PURE__ */ jsxs26(DropdownMenuContent4, { align: "end", children: [
6472
+ user ? /* @__PURE__ */ jsxs26(DropdownMenuItem4, { onSelect: copyUser, children: [
6473
+ /* @__PURE__ */ jsx28(UserGlyph, { className: "size-4" }),
6474
+ "Copy ",
6475
+ user.label.toLowerCase()
6476
+ ] }) : null,
6477
+ secret ? /* @__PURE__ */ jsxs26(DropdownMenuItem4, { onSelect: copyPassword, children: [
6478
+ /* @__PURE__ */ jsx28(KeyGlyph, { className: "size-4" }),
6479
+ "Copy password"
6480
+ ] }) : null,
6481
+ code ? /* @__PURE__ */ jsxs26(DropdownMenuItem4, { onSelect: copyCode, children: [
6482
+ /* @__PURE__ */ jsx28(ClockGlyph, { className: "size-4" }),
6483
+ "Copy one-time code"
6484
+ ] }) : null,
6485
+ user || secret || code ? /* @__PURE__ */ jsx28(DropdownMenuSeparator4, {}) : null,
6486
+ /* @__PURE__ */ jsxs26(DropdownMenuItem4, { onSelect: () => onSelect(item.id), children: [
6487
+ /* @__PURE__ */ jsx28(ChevronRightGlyph, { className: "size-4" }),
6488
+ "Open"
6489
+ ] }),
6490
+ /* @__PURE__ */ jsxs26(DropdownMenuItem4, { onSelect: copyName, children: [
6491
+ /* @__PURE__ */ jsx28(CopyIcon7, { className: "size-4" }),
6492
+ "Copy name"
6493
+ ] })
6494
+ ] })
6495
+ ] })
6496
+ ] })
6198
6497
  ] });
6199
6498
  }
6200
6499
 
6201
6500
  // src/lists/TrashView.tsx
6202
- import { useState as useState29 } from "react";
6203
- import { Button as Button24 } from "@ai-matrx/design-system/controls";
6501
+ import { useState as useState30 } from "react";
6502
+ import { Button as Button25 } from "@ai-matrx/design-system/controls";
6204
6503
  import { formatAbsoluteDate as formatAbsoluteDate4 } from "@ai-matrx/kit/format";
6205
6504
 
6206
6505
  // src/lists/logic.ts
@@ -6273,15 +6572,15 @@ function refusalText(reason) {
6273
6572
  }
6274
6573
 
6275
6574
  // src/lists/RestorePanel.tsx
6276
- import { useEffect as useEffect18, useState as useState28 } from "react";
6277
- import { Button as Button23 } from "@ai-matrx/design-system/controls";
6278
- import { Fragment as Fragment17, jsx as jsx28, jsxs as jsxs26 } from "react/jsx-runtime";
6575
+ import { useEffect as useEffect18, useState as useState29 } from "react";
6576
+ import { Button as Button24 } from "@ai-matrx/design-system/controls";
6577
+ import { Fragment as Fragment18, jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
6279
6578
  var count = (n, one) => `${n} ${one}${n === 1 ? "" : "s"}`;
6280
6579
  function RestorePanel({ lists, item, restore, onClose }) {
6281
- const [preview, setPreview] = useState28(null);
6282
- const [error, setError] = useState28(null);
6283
- const [busy, setBusy] = useState28(false);
6284
- const [loading, setLoading] = useState28(Boolean(lists.preview));
6580
+ const [preview, setPreview] = useState29(null);
6581
+ const [error, setError] = useState29(null);
6582
+ const [busy, setBusy] = useState29(false);
6583
+ const [loading, setLoading] = useState29(Boolean(lists.preview));
6285
6584
  useEffect18(() => {
6286
6585
  if (!lists.preview) return;
6287
6586
  let live = true;
@@ -6314,41 +6613,41 @@ function RestorePanel({ lists, item, restore, onClose }) {
6314
6613
  setBusy(false);
6315
6614
  }
6316
6615
  };
6317
- return /* @__PURE__ */ jsxs26(
6616
+ return /* @__PURE__ */ jsxs27(
6318
6617
  Panel,
6319
6618
  {
6320
6619
  title: `Restore "${item.name}"`,
6321
6620
  size: "md",
6322
6621
  onClose,
6323
- footer: /* @__PURE__ */ jsxs26(Fragment17, { children: [
6324
- /* @__PURE__ */ jsx28(Button23, { variant: "quiet", onClick: onClose, children: refused ? "Close" : "Cancel" }),
6325
- refused ? null : /* @__PURE__ */ jsx28(Button23, { variant: "primary", icon: /* @__PURE__ */ jsx28(RestoreGlyph, {}), disabled: busy || loading || lists.preview !== void 0 && preview === null, onClick: () => void run(), children: busy ? "Restoring\u2026" : "Restore" })
6622
+ footer: /* @__PURE__ */ jsxs27(Fragment18, { children: [
6623
+ /* @__PURE__ */ jsx29(Button24, { variant: "quiet", onClick: onClose, children: refused ? "Close" : "Cancel" }),
6624
+ refused ? null : /* @__PURE__ */ jsx29(Button24, { variant: "primary", icon: /* @__PURE__ */ jsx29(RestoreGlyph, {}), disabled: busy || loading || lists.preview !== void 0 && preview === null, onClick: () => void run(), children: busy ? "Restoring\u2026" : "Restore" })
6326
6625
  ] }),
6327
6626
  children: [
6328
- loading ? /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ jsxs26(VaultSection, { title: "Comes back", children: [
6329
- /* @__PURE__ */ jsx28(VaultRow, { label: "Fields", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
6330
- /* @__PURE__ */ jsx28(VaultRow, { label: "Files", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
6331
- preview.passkeys === 1 ? /* @__PURE__ */ jsx28(VaultRow, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ jsx28("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
6332
- /* @__PURE__ */ jsx28(VaultRow, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
6333
- preview.priorWasDisabled ? /* @__PURE__ */ jsx28(VaultRow, { label: "Before", children: /* @__PURE__ */ jsx28("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
6334
- ] }) : preview ? /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ jsx28(VaultSection, { children: /* @__PURE__ */ jsx28(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
6335
- error ? /* @__PURE__ */ jsx28("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
6627
+ loading ? /* @__PURE__ */ jsx29(VaultSection, { children: /* @__PURE__ */ jsx29(Empty, { children: "Checking what comes back\u2026" }) }) : preview?.supported ? /* @__PURE__ */ jsxs27(VaultSection, { title: "Comes back", children: [
6628
+ /* @__PURE__ */ jsx29(VaultRow, { label: "Fields", children: /* @__PURE__ */ jsx29("span", { className: "text-foreground", children: count(preview.fields, "field") }) }),
6629
+ /* @__PURE__ */ jsx29(VaultRow, { label: "Files", children: /* @__PURE__ */ jsx29("span", { className: "text-foreground", children: count(preview.attachments, "file") }) }),
6630
+ preview.passkeys === 1 ? /* @__PURE__ */ jsx29(VaultRow, { label: "Passkey", hint: "Not turned on; the site may not accept it", children: /* @__PURE__ */ jsx29("span", { className: "text-foreground", children: "1 passkey" }) }) : null,
6631
+ /* @__PURE__ */ jsx29(VaultRow, { label: "Stays off", hint: "Turn each back on yourself", children: /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "Sharing, browser fill, codes, sandboxes, agents" }) }),
6632
+ preview.priorWasDisabled ? /* @__PURE__ */ jsx29(VaultRow, { label: "Before", children: /* @__PURE__ */ jsx29("span", { className: "text-muted-foreground", children: "It was already off before it was deleted." }) }) : null
6633
+ ] }) : preview ? /* @__PURE__ */ jsx29(VaultSection, { children: /* @__PURE__ */ jsx29(Empty, { children: refusalText(preview.reason) }) }) : /* @__PURE__ */ jsx29(VaultSection, { children: /* @__PURE__ */ jsx29(Empty, { children: "It comes back turned off: sharing, browser fill, codes and sandbox use stay off." }) }),
6634
+ error ? /* @__PURE__ */ jsx29("p", { role: "alert", className: "px-1 text-sm text-destructive", children: error }) : null
6336
6635
  ]
6337
6636
  }
6338
6637
  );
6339
6638
  }
6340
6639
 
6341
6640
  // src/lists/TrashView.tsx
6342
- import { jsx as jsx29, jsxs as jsxs27 } from "react/jsx-runtime";
6641
+ import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
6343
6642
  function trashLineOf(item) {
6344
6643
  return [item.definitionLabel || null, item.owner.label, item.deletion?.deletedAt ? `Deleted ${formatAbsoluteDate4(item.deletion.deletedAt, DAY_FORMAT, "")}` : null].filter(Boolean).join(" \xB7 ");
6345
6644
  }
6346
6645
  function TrashView({ port, deleted, query, header, onChanged }) {
6347
6646
  const confirmed = useConfirmed();
6348
- const [busyId, setBusyId] = useState29(null);
6349
- const [message2, setMessage] = useState29(null);
6647
+ const [busyId, setBusyId] = useState30(null);
6648
+ const [message2, setMessage] = useState30(null);
6350
6649
  const shown = deleted.filter((i) => trashItemMatchesQuery(i, query));
6351
- const [restoring, setRestoring] = useState29(null);
6650
+ const [restoring, setRestoring] = useState30(null);
6352
6651
  const restore = async (item, deletionId) => {
6353
6652
  setBusyId(item.id);
6354
6653
  setMessage(null);
@@ -6364,32 +6663,32 @@ function TrashView({ port, deleted, query, header, onChanged }) {
6364
6663
  setBusyId(null);
6365
6664
  }
6366
6665
  };
6367
- return /* @__PURE__ */ jsxs27("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
6666
+ return /* @__PURE__ */ jsxs28("div", { className: "flex min-h-0 flex-1 flex-col gap-3 overflow-y-auto p-3", children: [
6368
6667
  header,
6369
- /* @__PURE__ */ jsx29(VaultSection, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ jsx29(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
6668
+ /* @__PURE__ */ jsx30(VaultSection, { title: "Trash", children: shown.length === 0 ? /* @__PURE__ */ jsx30(Empty, { children: deleted.length === 0 ? "The trash is empty." : "Nothing matches." }) : shown.map((item) => (
6370
6669
  // A list row, not a field row: the name gets the whole width (on a phone a label column
6371
6670
  // left "Vau…" for every row), the deletion date sits under it.
6372
- /* @__PURE__ */ jsxs27("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
6373
- /* @__PURE__ */ jsxs27("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6374
- /* @__PURE__ */ jsx29("span", { className: "truncate text-sm text-foreground", children: item.name }),
6375
- /* @__PURE__ */ jsx29("span", { className: "truncate text-xs text-muted-foreground", children: trashLineOf(item) })
6671
+ /* @__PURE__ */ jsxs28("div", { className: "flex min-h-12 items-center gap-3 px-3 py-1.5 sm:px-4", children: [
6672
+ /* @__PURE__ */ jsxs28("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
6673
+ /* @__PURE__ */ jsx30("span", { className: "truncate text-sm text-foreground", children: item.name }),
6674
+ /* @__PURE__ */ jsx30("span", { className: "truncate text-xs text-muted-foreground", children: trashLineOf(item) })
6376
6675
  ] }),
6377
- /* @__PURE__ */ jsx29(Button24, { variant: "outline", icon: /* @__PURE__ */ jsx29(RestoreGlyph, {}), disabled: busyId !== null || !item.deletion, onClick: () => setRestoring(item), children: "Restore" })
6676
+ /* @__PURE__ */ jsx30(Button25, { variant: "outline", icon: /* @__PURE__ */ jsx30(RestoreGlyph, {}), disabled: busyId !== null || !item.deletion, onClick: () => setRestoring(item), children: "Restore" })
6378
6677
  ] }, item.id)
6379
6678
  )) }),
6380
- restoring ? /* @__PURE__ */ jsx29(RestorePanel, { lists: port.lists, item: restoring, restore: (deletionId) => restore(restoring, deletionId), onClose: () => setRestoring(null) }) : null,
6381
- message2 ? /* @__PURE__ */ jsx29("p", { role: "status", className: message2.tone === "error" ? "px-1 text-sm text-destructive" : "px-1 text-sm text-muted-foreground", children: message2.text }) : null
6679
+ restoring ? /* @__PURE__ */ jsx30(RestorePanel, { lists: port.lists, item: restoring, restore: (deletionId) => restore(restoring, deletionId), onClose: () => setRestoring(null) }) : null,
6680
+ message2 ? /* @__PURE__ */ jsx30("p", { role: "status", className: message2.tone === "error" ? "px-1 text-sm text-destructive" : "px-1 text-sm text-muted-foreground", children: message2.text }) : null
6382
6681
  ] });
6383
6682
  }
6384
6683
 
6385
6684
  // src/NewItemFlow.tsx
6386
- import { useMemo as useMemo4, useState as useState30 } from "react";
6685
+ import { useMemo as useMemo4, useState as useState31 } from "react";
6387
6686
  import { cn as cn14 } from "@ai-matrx/design-system";
6388
- import { Button as Button25, Field as Field10, SearchField as SearchField2 } from "@ai-matrx/design-system/controls";
6687
+ import { Button as Button26, Field as Field11, SearchField as SearchField2 } from "@ai-matrx/design-system/controls";
6389
6688
  import { GlobeIcon as GlobeIcon3 } from "@ai-matrx/design-system/icons";
6390
- import { jsx as jsx30, jsxs as jsxs28 } from "react/jsx-runtime";
6689
+ import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
6391
6690
  function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6392
- const [search, setSearch] = useState30("");
6691
+ const [search, setSearch] = useState31("");
6393
6692
  const guess = useMemo4(() => inferFromUrl(url, definitions), [url, definitions]);
6394
6693
  const common = COMMON_DEFINITION_KEYS.map((k) => definitions.find((d) => d.key === k)).filter((d) => d !== void 0);
6395
6694
  const matches = useMemo4(() => {
@@ -6401,15 +6700,15 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6401
6700
  const alternatives = (guess?.alternatives ?? []).map((k) => definitions.find((d) => d.key === k)).filter((d) => d !== void 0).slice(0, 4);
6402
6701
  const use = (d) => onChoose(d.key, guess?.name ?? "", guess?.url ?? url.trim());
6403
6702
  const shown = search.trim() ? matches : common;
6404
- return /* @__PURE__ */ jsxs28("div", { className: "flex h-full min-h-0 flex-col bg-background", children: [
6405
- /* @__PURE__ */ jsxs28("header", { className: "flex min-h-14 items-center gap-2 border-b border-border px-3 sm:px-5", children: [
6406
- /* @__PURE__ */ jsx30(Button25, { variant: "quiet", icon: /* @__PURE__ */ jsx30(ChevronLeftGlyph, {}), "aria-label": "Cancel", onClick: onCancel }),
6407
- /* @__PURE__ */ jsx30("h2", { className: "text-base font-semibold", children: "New item" })
6703
+ return /* @__PURE__ */ jsxs29("div", { className: "flex h-full min-h-0 flex-col bg-background", children: [
6704
+ /* @__PURE__ */ jsxs29("header", { className: "flex min-h-14 items-center gap-2 border-b border-border px-3 sm:px-5", children: [
6705
+ /* @__PURE__ */ jsx31(Button26, { variant: "quiet", icon: /* @__PURE__ */ jsx31(ChevronLeftGlyph, {}), "aria-label": "Cancel", onClick: onCancel }),
6706
+ /* @__PURE__ */ jsx31("h2", { className: "text-base font-semibold", children: "New item" })
6408
6707
  ] }),
6409
- /* @__PURE__ */ jsx30("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxs28("div", { className: "mx-auto flex w-full max-w-2xl flex-col gap-8 px-4 py-8 sm:px-6 sm:py-12", children: [
6410
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-3", children: [
6411
- /* @__PURE__ */ jsx30(
6412
- Field10,
6708
+ /* @__PURE__ */ jsx31("div", { className: "min-h-0 flex-1 overflow-y-auto", children: /* @__PURE__ */ jsxs29("div", { className: "mx-auto flex w-full max-w-2xl flex-col gap-8 px-4 py-8 sm:px-6 sm:py-12", children: [
6709
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-3", children: [
6710
+ /* @__PURE__ */ jsx31(
6711
+ Field11,
6413
6712
  {
6414
6713
  hero: true,
6415
6714
  value: url,
@@ -6421,45 +6720,45 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
6421
6720
  "aria-label": "Website address",
6422
6721
  inputMode: "url",
6423
6722
  autoFocus: true,
6424
- icon: /* @__PURE__ */ jsx30(GlobeIcon3, {})
6723
+ icon: /* @__PURE__ */ jsx31(GlobeIcon3, {})
6425
6724
  }
6426
6725
  ),
6427
- guess && login ? /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
6428
- /* @__PURE__ */ jsxs28("div", { className: "flex items-center gap-3", children: [
6429
- /* @__PURE__ */ jsx30("span", { "aria-hidden": true, className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-muted text-sm font-semibold", children: guess.name.charAt(0).toUpperCase() }),
6430
- /* @__PURE__ */ jsxs28("div", { className: "flex min-w-0 flex-1 flex-col", children: [
6431
- /* @__PURE__ */ jsx30("span", { className: "truncate text-sm font-medium", children: guess.name }),
6432
- /* @__PURE__ */ jsx30("span", { className: "truncate text-xs text-muted-foreground", children: guess.url.replace(/^https?:\/\//, "") })
6726
+ guess && login ? /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-2 rounded-xl border border-border bg-card p-3", children: [
6727
+ /* @__PURE__ */ jsxs29("div", { className: "flex items-center gap-3", children: [
6728
+ /* @__PURE__ */ jsx31("span", { "aria-hidden": true, className: "flex size-9 shrink-0 items-center justify-center rounded-lg bg-muted text-sm font-semibold", children: guess.name.charAt(0).toUpperCase() }),
6729
+ /* @__PURE__ */ jsxs29("div", { className: "flex min-w-0 flex-1 flex-col", children: [
6730
+ /* @__PURE__ */ jsx31("span", { className: "truncate text-sm font-medium", children: guess.name }),
6731
+ /* @__PURE__ */ jsx31("span", { className: "truncate text-xs text-muted-foreground", children: guess.url.replace(/^https?:\/\//, "") })
6433
6732
  ] }),
6434
- /* @__PURE__ */ jsx30(Button25, { variant: "primary", onClick: () => use(login), children: "Save login" })
6733
+ /* @__PURE__ */ jsx31(Button26, { variant: "primary", onClick: () => use(login), children: "Save login" })
6435
6734
  ] }),
6436
- alternatives.length > 0 ? /* @__PURE__ */ jsxs28("div", { className: "flex flex-wrap items-center gap-1.5 pl-12", children: [
6437
- /* @__PURE__ */ jsx30("span", { className: "text-xs text-muted-foreground", children: "Or" }),
6438
- alternatives.map((d) => /* @__PURE__ */ jsx30(Button25, { variant: "outline", onClick: () => use(d), children: d.label }, d.key))
6735
+ alternatives.length > 0 ? /* @__PURE__ */ jsxs29("div", { className: "flex flex-wrap items-center gap-1.5 pl-12", children: [
6736
+ /* @__PURE__ */ jsx31("span", { className: "text-xs text-muted-foreground", children: "Or" }),
6737
+ alternatives.map((d) => /* @__PURE__ */ jsx31(Button26, { variant: "outline", onClick: () => use(d), children: d.label }, d.key))
6439
6738
  ] }) : null
6440
- ] }) : url.trim() ? /* @__PURE__ */ jsx30("p", { className: "px-1 text-sm text-muted-foreground", children: "Not a website address. Pick a type below; it is kept." }) : null
6739
+ ] }) : url.trim() ? /* @__PURE__ */ jsx31("p", { className: "px-1 text-sm text-muted-foreground", children: "Not a website address. Pick a type below; it is kept." }) : null
6441
6740
  ] }),
6442
- /* @__PURE__ */ jsxs28("div", { className: "flex flex-col gap-3", children: [
6443
- /* @__PURE__ */ jsx30("div", { className: "flex items-center justify-between gap-3", children: /* @__PURE__ */ jsx30("h3", { className: "text-xs font-medium text-muted-foreground", children: search.trim() ? "Matching types" : "Or choose a type" }) }),
6444
- /* @__PURE__ */ jsx30("ul", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: shown.map((d) => {
6741
+ /* @__PURE__ */ jsxs29("div", { className: "flex flex-col gap-3", children: [
6742
+ /* @__PURE__ */ jsx31("div", { className: "flex items-center justify-between gap-3", children: /* @__PURE__ */ jsx31("h3", { className: "text-xs font-medium text-muted-foreground", children: search.trim() ? "Matching types" : "Or choose a type" }) }),
6743
+ /* @__PURE__ */ jsx31("ul", { className: "grid grid-cols-1 gap-2 sm:grid-cols-2", children: shown.map((d) => {
6445
6744
  const Icon = definitionGlyph(d.key, d.family);
6446
- return /* @__PURE__ */ jsx30("li", { children: /* @__PURE__ */ jsxs28("button", { type: "button", onClick: () => use(d), className: cn14("flex h-12 w-full items-center gap-3 rounded-xl border border-border bg-card px-3 text-left hover:bg-accent"), children: [
6447
- /* @__PURE__ */ jsx30("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted", children: /* @__PURE__ */ jsx30(Icon, { className: "size-4" }) }),
6448
- /* @__PURE__ */ jsx30("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: d.label })
6745
+ return /* @__PURE__ */ jsx31("li", { children: /* @__PURE__ */ jsxs29("button", { type: "button", onClick: () => use(d), className: cn14("flex h-12 w-full items-center gap-3 rounded-xl border border-border bg-card px-3 text-left hover:bg-accent"), children: [
6746
+ /* @__PURE__ */ jsx31("span", { className: "flex size-8 shrink-0 items-center justify-center rounded-lg bg-muted", children: /* @__PURE__ */ jsx31(Icon, { className: "size-4" }) }),
6747
+ /* @__PURE__ */ jsx31("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", children: d.label })
6449
6748
  ] }) }, d.key);
6450
6749
  }) }),
6451
- search.trim() && matches.length === 0 ? /* @__PURE__ */ jsx30("p", { className: "px-1 text-sm text-muted-foreground", children: "No type matches." }) : null,
6452
- /* @__PURE__ */ jsx30(SearchField2, { value: search, onChange: (e) => setSearch(e.target.value), placeholder: `Search all ${definitions.length} types`, "aria-label": "Search types" })
6750
+ search.trim() && matches.length === 0 ? /* @__PURE__ */ jsx31("p", { className: "px-1 text-sm text-muted-foreground", children: "No type matches." }) : null,
6751
+ /* @__PURE__ */ jsx31(SearchField2, { value: search, onChange: (e) => setSearch(e.target.value), placeholder: `Search all ${definitions.length} types`, "aria-label": "Search types" })
6453
6752
  ] })
6454
6753
  ] }) })
6455
6754
  ] });
6456
6755
  }
6457
6756
 
6458
6757
  // src/sharing/SecureLinkPanel.tsx
6459
- import { useEffect as useEffect19, useRef as useRef16, useState as useState31 } from "react";
6460
- import { confirm as confirm10 } from "@ai-matrx/kit/confirm-opener";
6758
+ import { useEffect as useEffect19, useRef as useRef16, useState as useState32 } from "react";
6759
+ import { confirm as confirm11 } from "@ai-matrx/kit/confirm-opener";
6461
6760
  import { Checkbox as Checkbox2 } from "@ai-matrx/design-system";
6462
- import { Badge as Badge8, Button as Button26, Field as Field11, RegionSkeleton as RegionSkeleton2, SegmentedControl as SegmentedControl5, Textarea as Textarea4 } from "@ai-matrx/design-system/controls";
6761
+ import { Badge as Badge8, Button as Button27, Field as Field12, RegionSkeleton as RegionSkeleton2, SegmentedControl as SegmentedControl6, Textarea as Textarea4 } from "@ai-matrx/design-system/controls";
6463
6762
  import { formatAbsoluteDate as formatAbsoluteDate5 } from "@ai-matrx/kit/format";
6464
6763
 
6465
6764
  // src/sharing/secure-link-logic.ts
@@ -6535,23 +6834,23 @@ function sortSent(rows) {
6535
6834
  }
6536
6835
 
6537
6836
  // src/sharing/SecureLinkPanel.tsx
6538
- import { jsx as jsx31, jsxs as jsxs29 } from "react/jsx-runtime";
6837
+ import { jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
6539
6838
  function SecureLinkPanel({ item, port, onClose }) {
6540
6839
  const sharing = port.sharing;
6541
6840
  const { busy, error, notice, run, setNotice } = useConfirmedChange();
6542
- const [remedy, setRemedy] = useState31(null);
6543
- const [options, setOptions] = useState31(null);
6544
- const [optionsError, setOptionsError] = useState31(null);
6545
- const [sent, setSent] = useState31(null);
6546
- const [sentError, setSentError] = useState31(null);
6547
- const [nonce, setNonce] = useState31(0);
6548
- const [email, setEmail] = useState31("");
6549
- const [phone, setPhone] = useState31("");
6550
- const [name, setName] = useState31("");
6551
- const [linkBy, setLinkBy] = useState31("email");
6552
- const [fields, setFields] = useState31([]);
6553
- const [note, setNote] = useState31("");
6554
- const [sameChannelSent, setSameChannelSent] = useState31(false);
6841
+ const [remedy, setRemedy] = useState32(null);
6842
+ const [options, setOptions] = useState32(null);
6843
+ const [optionsError, setOptionsError] = useState32(null);
6844
+ const [sent, setSent] = useState32(null);
6845
+ const [sentError, setSentError] = useState32(null);
6846
+ const [nonce, setNonce] = useState32(0);
6847
+ const [email, setEmail] = useState32("");
6848
+ const [phone, setPhone] = useState32("");
6849
+ const [name, setName] = useState32("");
6850
+ const [linkBy, setLinkBy] = useState32("email");
6851
+ const [fields, setFields] = useState32([]);
6852
+ const [note, setNote] = useState32("");
6853
+ const [sameChannelSent, setSameChannelSent] = useState32(false);
6555
6854
  useEffect19(() => {
6556
6855
  let live = true;
6557
6856
  setOptionsError(null);
@@ -6580,7 +6879,7 @@ function SecureLinkPanel({ item, port, onClose }) {
6580
6879
  live = false;
6581
6880
  };
6582
6881
  }, [sharing, item, nonce]);
6583
- const [phoneTyped, setPhoneTyped] = useState31(false);
6882
+ const [phoneTyped, setPhoneTyped] = useState32(false);
6584
6883
  const prefilled = useRef16(false);
6585
6884
  useEffect19(() => {
6586
6885
  const lookup = sharing.phoneOnFile;
@@ -6644,7 +6943,7 @@ function SecureLinkPanel({ item, port, onClose }) {
6644
6943
  setNonce((n) => n + 1);
6645
6944
  };
6646
6945
  const turnOff = async (row) => {
6647
- const ok = await confirm10({
6946
+ const ok = await confirm11({
6648
6947
  title: "Turn off this link?",
6649
6948
  description: `The link to ${recipientOf(row)} stops working at once and what it carries is deleted. They will need a new one.`,
6650
6949
  confirmLabel: "Turn off",
@@ -6657,23 +6956,23 @@ function SecureLinkPanel({ item, port, onClose }) {
6657
6956
  setNonce((n) => n + 1);
6658
6957
  };
6659
6958
  const toggle2 = (key, on) => setFields((cur) => on ? [...cur.filter((k) => k !== key), key] : cur.filter((k) => k !== key));
6660
- return /* @__PURE__ */ jsxs29(
6959
+ return /* @__PURE__ */ jsxs30(
6661
6960
  Panel,
6662
6961
  {
6663
6962
  title: "Send securely",
6664
6963
  size: "md",
6665
6964
  onClose,
6666
- footer: /* @__PURE__ */ jsxs29(PanelFooter, { status: error || notice ? /* @__PURE__ */ jsx31(StatusLine, { error, notice }) : null, children: [
6667
- sameChannelSent && !error ? /* @__PURE__ */ jsx31(Badge8, { tone: "warning", children: "Both by email" }) : null,
6668
- /* @__PURE__ */ jsx31(Button26, { variant: "quiet", onClick: onClose, children: "Close" }),
6669
- /* @__PURE__ */ jsx31(Button26, { variant: "primary", disabled: !canSend, onClick: () => void send(), children: busy === "send" ? "Sending\u2026" : "Send link" })
6965
+ footer: /* @__PURE__ */ jsxs30(PanelFooter, { status: error || notice ? /* @__PURE__ */ jsx32(StatusLine, { error, notice }) : null, children: [
6966
+ sameChannelSent && !error ? /* @__PURE__ */ jsx32(Badge8, { tone: "warning", children: "Both by email" }) : null,
6967
+ /* @__PURE__ */ jsx32(Button27, { variant: "quiet", onClick: onClose, children: "Close" }),
6968
+ /* @__PURE__ */ jsx32(Button27, { variant: "primary", disabled: !canSend, onClick: () => void send(), children: busy === "send" ? "Sending\u2026" : "Send link" })
6670
6969
  ] }),
6671
6970
  children: [
6672
- remedy ? /* @__PURE__ */ jsx31("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
6673
- /* @__PURE__ */ jsxs29(VaultSection, { title: "Recipient", children: [
6674
- /* @__PURE__ */ jsx31(VaultRow, { label: "Email", children: /* @__PURE__ */ jsx31(Field11, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
6675
- /* @__PURE__ */ jsx31(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ jsx31(
6676
- Field11,
6971
+ remedy ? /* @__PURE__ */ jsx32("p", { className: "px-1 text-xs text-muted-foreground", children: remedy }) : null,
6972
+ /* @__PURE__ */ jsxs30(VaultSection, { title: "Recipient", children: [
6973
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Email", children: /* @__PURE__ */ jsx32(Field12, { type: "email", autoComplete: "off", placeholder: "name@example.com", "aria-label": "Their email", value: email, onChange: (e) => setEmail(e.target.value), className: "w-full" }) }),
6974
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Mobile", hint: "For the code", children: /* @__PURE__ */ jsx32(
6975
+ Field12,
6677
6976
  {
6678
6977
  type: "tel",
6679
6978
  autoComplete: "off",
@@ -6688,9 +6987,9 @@ function SecureLinkPanel({ item, port, onClose }) {
6688
6987
  className: "w-full"
6689
6988
  }
6690
6989
  ) }),
6691
- /* @__PURE__ */ jsx31(VaultRow, { label: "Name", hint: "Optional", children: /* @__PURE__ */ jsx31(Field11, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
6692
- plan && !plan.same ? /* @__PURE__ */ jsx31(VaultRow, { label: "Link by", children: /* @__PURE__ */ jsx31(
6693
- SegmentedControl5,
6990
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Name", hint: "Optional", children: /* @__PURE__ */ jsx32(Field12, { autoComplete: "off", placeholder: "Their name", "aria-label": "Their name", value: name, onChange: (e) => setName(e.target.value), className: "w-full" }) }),
6991
+ plan && !plan.same ? /* @__PURE__ */ jsx32(VaultRow, { label: "Link by", children: /* @__PURE__ */ jsx32(
6992
+ SegmentedControl6,
6694
6993
  {
6695
6994
  "aria-label": "Send the link by",
6696
6995
  value: linkBy,
@@ -6701,28 +7000,28 @@ function SecureLinkPanel({ item, port, onClose }) {
6701
7000
  ]
6702
7001
  }
6703
7002
  ) }) : null,
6704
- email.trim() ? /* @__PURE__ */ jsx31(VaultRow, { label: "Delivery", children: /* @__PURE__ */ jsx31("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
7003
+ email.trim() ? /* @__PURE__ */ jsx32(VaultRow, { label: "Delivery", children: /* @__PURE__ */ jsx32("span", { className: plan?.same ? "text-warning" : "text-foreground", children: planWords(plan) }) }) : null
6705
7004
  ] }),
6706
- /* @__PURE__ */ jsx31(VaultSection, { title: "Include", children: optionsError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ jsxs29("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
6707
- /* @__PURE__ */ jsx31(Checkbox2, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
6708
- /* @__PURE__ */ jsx31("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
6709
- !f.available && f.reason ? /* @__PURE__ */ jsx31("span", { className: "min-w-0 max-w-[55%] truncate text-xs text-muted-foreground", title: f.reason, children: f.reason }) : null
7005
+ /* @__PURE__ */ jsx32(VaultSection, { title: "Include", children: optionsError ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32("span", { className: "text-destructive", children: optionsError }) }) : !options ? /* @__PURE__ */ jsx32(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading what can be sent", className: "px-3 sm:px-4" }) : options.fields.length === 0 ? /* @__PURE__ */ jsx32(Empty, { children: "Name and details only" }) : options.fields.map((f) => /* @__PURE__ */ jsxs30("label", { className: "flex min-h-11 items-center gap-3 px-3 py-1 sm:px-4", "data-clickable": f.available ? "" : void 0, children: [
7006
+ /* @__PURE__ */ jsx32(Checkbox2, { checked: fields.includes(f.key), disabled: !f.available, onCheckedChange: (v) => toggle2(f.key, v === true), "aria-label": f.label }),
7007
+ /* @__PURE__ */ jsx32("span", { className: "min-w-0 flex-1 truncate text-sm text-foreground", children: f.label }),
7008
+ !f.available && f.reason ? /* @__PURE__ */ jsx32("span", { className: "min-w-0 max-w-[55%] truncate text-xs text-muted-foreground", title: f.reason, children: f.reason }) : null
6710
7009
  ] }, f.key)) }),
6711
- /* @__PURE__ */ jsx31(VaultSection, { title: "Message", children: /* @__PURE__ */ jsx31("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ jsx31(Textarea4, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
6712
- options ? /* @__PURE__ */ jsxs29(VaultSection, { title: "Link", children: [
6713
- /* @__PURE__ */ jsx31(VaultRow, { label: "Opens", children: /* @__PURE__ */ jsx31("span", { className: "text-foreground", children: "Once" }) }),
6714
- /* @__PURE__ */ jsx31(VaultRow, { label: "Link expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
7010
+ /* @__PURE__ */ jsx32(VaultSection, { title: "Message", children: /* @__PURE__ */ jsx32("div", { className: "px-3 py-1 sm:px-4", children: /* @__PURE__ */ jsx32(Textarea4, { className: "w-full", rows: 2, maxLength: NOTE_MAX, placeholder: "Shown once, with it", "aria-label": "Message", value: note, onChange: (e) => setNote(e.target.value) }) }) }),
7011
+ options ? /* @__PURE__ */ jsxs30(VaultSection, { title: "Link", children: [
7012
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Opens", children: /* @__PURE__ */ jsx32("span", { className: "text-foreground", children: "Once" }) }),
7013
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Link expires", children: /* @__PURE__ */ jsxs30("span", { className: "text-foreground", children: [
6715
7014
  "After ",
6716
7015
  lifetimeWords(options.linkMinutes)
6717
7016
  ] }) }),
6718
- /* @__PURE__ */ jsx31(VaultRow, { label: "Code expires", children: /* @__PURE__ */ jsxs29("span", { className: "text-foreground", children: [
7017
+ /* @__PURE__ */ jsx32(VaultRow, { label: "Code expires", children: /* @__PURE__ */ jsxs30("span", { className: "text-foreground", children: [
6719
7018
  "After ",
6720
7019
  lifetimeWords(options.codeMinutes)
6721
7020
  ] }) })
6722
7021
  ] }) : null,
6723
- sharing.sentSecureLinks ? /* @__PURE__ */ jsx31(VaultSection, { title: "Sent links", children: sentError ? /* @__PURE__ */ jsx31(Empty, { children: /* @__PURE__ */ jsx31("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ jsx31(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ jsx31(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ jsxs29(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
6724
- /* @__PURE__ */ jsx31(Badge8, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
6725
- row.status === "pending" ? /* @__PURE__ */ jsx31(Button26, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
7022
+ sharing.sentSecureLinks ? /* @__PURE__ */ jsx32(VaultSection, { title: "Sent links", children: sentError ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32("span", { className: "text-destructive", children: sentError }) }) : !sent ? /* @__PURE__ */ jsx32(RegionSkeleton2, { shape: "rows", count: 2, "aria-label": "Loading sent links", className: "px-3 sm:px-4" }) : sent.length === 0 ? /* @__PURE__ */ jsx32(Empty, { children: "None yet" }) : sent.map((row) => /* @__PURE__ */ jsxs30(AccessLine, { glyph: row.status === "pending" ? ClockGlyph : row.fieldKeys.length ? LockGlyph : ShareGlyph, who: recipientOf(row), meta: sentMeta(row, options), children: [
7023
+ /* @__PURE__ */ jsx32(Badge8, { tone: STATUS_TONE[row.status] ?? "neutral", children: statusWord(row.status) }),
7024
+ row.status === "pending" ? /* @__PURE__ */ jsx32(Button27, { variant: "quiet", disabled: busy !== null, onClick: () => void turnOff(row), children: "Turn off" }) : null
6726
7025
  ] }, row.id)) }) : null
6727
7026
  ]
6728
7027
  }
@@ -6735,9 +7034,9 @@ function sentMeta(row, options) {
6735
7034
  }
6736
7035
 
6737
7036
  // src/devices/DevicesPanel.tsx
6738
- import { useCallback as useCallback4, useEffect as useEffect20, useState as useState32 } from "react";
6739
- import { confirm as confirm11 } from "@ai-matrx/kit/confirm-opener";
6740
- import { Button as Button27, RegionSkeleton as RegionSkeleton3 } from "@ai-matrx/design-system/controls";
7037
+ import { useCallback as useCallback4, useEffect as useEffect20, useState as useState33 } from "react";
7038
+ import { confirm as confirm12 } from "@ai-matrx/kit/confirm-opener";
7039
+ import { Button as Button28, RegionSkeleton as RegionSkeleton3 } from "@ai-matrx/design-system/controls";
6741
7040
  import { formatAbsoluteDate as formatAbsoluteDate6 } from "@ai-matrx/kit/format";
6742
7041
 
6743
7042
  // src/devices/logic.ts
@@ -6818,17 +7117,17 @@ function addPasskeyFailure(message2) {
6818
7117
  var isRevoked = (d) => d.revokedAt !== null;
6819
7118
 
6820
7119
  // src/devices/DevicesPanel.tsx
6821
- import { Fragment as Fragment18, jsx as jsx32, jsxs as jsxs30 } from "react/jsx-runtime";
7120
+ import { Fragment as Fragment19, jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
6822
7121
  var messageOf3 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
6823
7122
  function ErrorLine2({ text }) {
6824
- return text ? /* @__PURE__ */ jsx32("p", { role: "alert", className: "px-1 text-sm text-destructive", children: text }) : null;
7123
+ return text ? /* @__PURE__ */ jsx33("p", { role: "alert", className: "px-1 text-sm text-destructive", children: text }) : null;
6825
7124
  }
6826
7125
  function DevicesPanel({ port, onClose }) {
6827
7126
  const confirmed = useConfirmed();
6828
7127
  const notify = useNotify();
6829
- const [devices, setDevices] = useState32(null);
6830
- const [error, setError] = useState32(null);
6831
- const [busyId, setBusyId] = useState32(null);
7128
+ const [devices, setDevices] = useState33(null);
7129
+ const [error, setError] = useState33(null);
7130
+ const [busyId, setBusyId] = useState33(null);
6832
7131
  const load = useCallback4(async () => {
6833
7132
  setError(null);
6834
7133
  try {
@@ -6841,7 +7140,7 @@ function DevicesPanel({ port, onClose }) {
6841
7140
  void load();
6842
7141
  }, [load]);
6843
7142
  const revoke = async (device) => {
6844
- const yes = await confirm11({
7143
+ const yes = await confirm12({
6845
7144
  title: `Revoke ${device.label}?`,
6846
7145
  description: "It stops filling now and the extension there signs out. It fills again only after you sign in there and confirm.",
6847
7146
  confirmLabel: "Revoke",
@@ -6860,19 +7159,19 @@ function DevicesPanel({ port, onClose }) {
6860
7159
  setBusyId(null);
6861
7160
  }
6862
7161
  };
6863
- return /* @__PURE__ */ jsxs30(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
6864
- /* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
6865
- /* @__PURE__ */ jsx32(VaultSection, { children: devices === null ? error ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32(Button27, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx32(RegionSkeleton3, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ jsx32(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
7162
+ return /* @__PURE__ */ jsxs31(Panel, { title: "Browsers that can fill", onClose, size: "md", children: [
7163
+ /* @__PURE__ */ jsx33(ErrorLine2, { text: error }),
7164
+ /* @__PURE__ */ jsx33(VaultSection, { children: devices === null ? error ? /* @__PURE__ */ jsx33(Empty, { children: /* @__PURE__ */ jsx33(Button28, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx33(RegionSkeleton3, { shape: "rows", count: 2, "aria-label": "Loading your browsers", className: "px-3 sm:px-4" }) : devices.length === 0 ? /* @__PURE__ */ jsx33(Empty, { children: "No browser can fill yet. Turn it on in the extension." }) : devices.map((device) => {
6866
7165
  const off = isRevoked(device);
6867
- return /* @__PURE__ */ jsx32(
7166
+ return /* @__PURE__ */ jsx33(
6868
7167
  VaultRow,
6869
7168
  {
6870
7169
  label: off ? "Turned off" : "Can fill",
6871
7170
  hint: off ? formatAbsoluteDate6(device.revokedAt, DAY_FORMAT, "") : void 0,
6872
- actions: off ? null : /* @__PURE__ */ jsx32(Button27, { variant: "outline", icon: /* @__PURE__ */ jsx32(PowerGlyph, {}), disabled: busyId !== null, onClick: () => void revoke(device), children: "Revoke" }),
6873
- children: /* @__PURE__ */ jsxs30("span", { className: "flex min-w-0 flex-col", children: [
6874
- /* @__PURE__ */ jsx32("span", { className: off ? "truncate text-muted-foreground" : "truncate text-foreground", children: device.label }),
6875
- /* @__PURE__ */ jsxs30("span", { className: "truncate text-xs text-muted-foreground", children: [
7171
+ actions: off ? null : /* @__PURE__ */ jsx33(Button28, { variant: "outline", icon: /* @__PURE__ */ jsx33(PowerGlyph, {}), disabled: busyId !== null, onClick: () => void revoke(device), children: "Revoke" }),
7172
+ children: /* @__PURE__ */ jsxs31("span", { className: "flex min-w-0 flex-col", children: [
7173
+ /* @__PURE__ */ jsx33("span", { className: off ? "truncate text-muted-foreground" : "truncate text-foreground", children: device.label }),
7174
+ /* @__PURE__ */ jsxs31("span", { className: "truncate text-xs text-muted-foreground", children: [
6876
7175
  device.lastUsedAt ? `Last used ${formatAbsoluteDate6(device.lastUsedAt, void 0, "")}` : "Never used",
6877
7176
  device.addedAt ? ` \xB7 added ${formatAbsoluteDate6(device.addedAt, DAY_FORMAT, "")}` : ""
6878
7177
  ] })
@@ -6895,10 +7194,10 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6895
7194
  const where = isMac ? "the Mac app" : "the extension";
6896
7195
  const passkeys = port.devices.passkeys;
6897
7196
  const here = passkeys?.available() ?? false;
6898
- const [methods, setMethods] = useState32(null);
6899
- const [busy, setBusy] = useState32(null);
6900
- const [error, setError] = useState32(null);
6901
- const [approvedUntil, setApprovedUntil] = useState32(null);
7197
+ const [methods, setMethods] = useState33(null);
7198
+ const [busy, setBusy] = useState33(null);
7199
+ const [error, setError] = useState33(null);
7200
+ const [approvedUntil, setApprovedUntil] = useState33(null);
6902
7201
  const load = useCallback4(async () => {
6903
7202
  setError(null);
6904
7203
  try {
@@ -6949,55 +7248,55 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
6949
7248
  };
6950
7249
  const canApprove = Boolean(key && passkeys && here && methods?.passkey && !approvedUntil);
6951
7250
  const title = isMac ? "Approve this Mac" : name ? `Approve ${name}` : "Approve this browser";
6952
- const footer = approvedUntil ? /* @__PURE__ */ jsx32(Button27, { variant: "primary", onClick: onClose, children: "Done" }) : /* @__PURE__ */ jsxs30(Fragment18, { children: [
6953
- /* @__PURE__ */ jsx32(Button27, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
6954
- canApprove ? /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void approve(), children: busy === "approve" ? "Approving\u2026" : "Approve with passkey" }) : null
7251
+ const footer = approvedUntil ? /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Done" }) : /* @__PURE__ */ jsxs31(Fragment19, { children: [
7252
+ /* @__PURE__ */ jsx33(Button28, { variant: "quiet", disabled: busy !== null, onClick: refuse, children: key ? "Refuse" : "Close" }),
7253
+ canApprove ? /* @__PURE__ */ jsx33(Button28, { variant: "primary", icon: /* @__PURE__ */ jsx33(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void approve(), children: busy === "approve" ? "Approving\u2026" : "Approve with passkey" }) : null
6955
7254
  ] });
6956
- return /* @__PURE__ */ jsx32(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx32(VaultSection, { children: /* @__PURE__ */ jsxs30(Empty, { children: [
7255
+ return /* @__PURE__ */ jsx33(Panel, { title, onClose: refuse, size: "sm", footer, children: !key ? /* @__PURE__ */ jsx33(VaultSection, { children: /* @__PURE__ */ jsxs31(Empty, { children: [
6957
7256
  "This link names no key. Start again from ",
6958
7257
  where,
6959
7258
  "."
6960
- ] }) }) : /* @__PURE__ */ jsxs30(Fragment18, { children: [
6961
- /* @__PURE__ */ jsxs30(VaultSection, { title: "What is asking", children: [
6962
- /* @__PURE__ */ jsx32(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
6963
- name ? /* @__PURE__ */ jsx32(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx32("span", { className: "block truncate", children: name }) }) : null,
6964
- /* @__PURE__ */ jsx32(VaultRow, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ jsx32("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
7259
+ ] }) }) : /* @__PURE__ */ jsxs31(Fragment19, { children: [
7260
+ /* @__PURE__ */ jsxs31(VaultSection, { title: "What is asking", children: [
7261
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Asking", hint: "Approve only if you just asked", children: asker }),
7262
+ name ? /* @__PURE__ */ jsx33(VaultRow, { label: "Name", children: /* @__PURE__ */ jsx33("span", { className: "block truncate", children: name }) }) : null,
7263
+ /* @__PURE__ */ jsx33(VaultRow, { label: "Code", hint: `Must match ${where}`, children: /* @__PURE__ */ jsx33("span", { className: "font-mono tracking-wider text-foreground", children: shortFingerprint(key) }) })
6965
7264
  ] }),
6966
- /* @__PURE__ */ jsx32(ErrorLine2, { text: error }),
6967
- /* @__PURE__ */ jsx32(VaultSection, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ jsx32(VaultRow, { label: "Approved", actions: /* @__PURE__ */ jsx32(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ jsxs30("span", { className: "text-foreground", children: [
7265
+ /* @__PURE__ */ jsx33(ErrorLine2, { text: error }),
7266
+ /* @__PURE__ */ jsx33(VaultSection, { title: "Confirm it\u2019s you", children: approvedUntil ? /* @__PURE__ */ jsx33(VaultRow, { label: "Approved", actions: /* @__PURE__ */ jsx33(CheckGlyph, { className: "size-4 text-primary" }), children: /* @__PURE__ */ jsxs31("span", { className: "text-foreground", children: [
6968
7267
  "Return to ",
6969
7268
  where,
6970
7269
  " by ",
6971
7270
  formatAbsoluteDate6(approvedUntil, void 0, ""),
6972
7271
  "."
6973
- ] }) }) : !passkeys ? /* @__PURE__ */ jsxs30(Empty, { children: [
7272
+ ] }) }) : !passkeys ? /* @__PURE__ */ jsxs31(Empty, { children: [
6974
7273
  "Approve with your password in ",
6975
7274
  where,
6976
7275
  "."
6977
- ] }) : !here ? /* @__PURE__ */ jsx32(
7276
+ ] }) : !here ? /* @__PURE__ */ jsx33(
6978
7277
  VaultRow,
6979
7278
  {
6980
7279
  label: "Passkey",
6981
7280
  hint: `Passkeys work only on ${passkeys.rpId}`,
6982
- actions: /* @__PURE__ */ jsx32(Button27, { variant: "outline", icon: /* @__PURE__ */ jsx32(ExternalGlyph, {}), onClick: openOnDomain, children: "Open there" }),
6983
- children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: "Not on this page" })
7281
+ actions: /* @__PURE__ */ jsx33(Button28, { variant: "outline", icon: /* @__PURE__ */ jsx33(ExternalGlyph, {}), onClick: openOnDomain, children: "Open there" }),
7282
+ children: /* @__PURE__ */ jsx33("span", { className: "text-muted-foreground", children: "Not on this page" })
6984
7283
  }
6985
- ) : methods === null ? error ? /* @__PURE__ */ jsx32(Empty, { children: /* @__PURE__ */ jsx32(Button27, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx32(RegionSkeleton3, { shape: "rows", count: 1, "aria-label": "Checking your account", className: "px-3 sm:px-4" }) : !methods.passkey ? /* @__PURE__ */ jsx32(
7284
+ ) : methods === null ? error ? /* @__PURE__ */ jsx33(Empty, { children: /* @__PURE__ */ jsx33(Button28, { variant: "outline", onClick: () => void load(), children: "Try again" }) }) : /* @__PURE__ */ jsx33(RegionSkeleton3, { shape: "rows", count: 1, "aria-label": "Checking your account", className: "px-3 sm:px-4" }) : !methods.passkey ? /* @__PURE__ */ jsx33(
6986
7285
  VaultRow,
6987
7286
  {
6988
7287
  label: "Passkey",
6989
7288
  hint: methods.password ? `Or type your password in ${where}` : "Add one to approve",
6990
- actions: /* @__PURE__ */ jsx32(Button27, { variant: "primary", icon: /* @__PURE__ */ jsx32(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
6991
- children: /* @__PURE__ */ jsx32("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
7289
+ actions: /* @__PURE__ */ jsx33(Button28, { variant: "primary", icon: /* @__PURE__ */ jsx33(FingerprintGlyph, {}), disabled: busy !== null, onClick: () => void addPasskey(), children: busy === "add" ? "Adding\u2026" : "Add passkey" }),
7290
+ children: /* @__PURE__ */ jsx33("span", { className: "text-muted-foreground", children: methods.password ? "None yet" : "No password or passkey" })
6992
7291
  }
6993
- ) : /* @__PURE__ */ jsx32(VaultRow, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ jsx32("span", { className: "text-foreground", children: "Ready" }) }) })
7292
+ ) : /* @__PURE__ */ jsx33(VaultRow, { label: "Passkey", hint: "Your device asks for it next", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: "Ready" }) }) })
6994
7293
  ] }) });
6995
7294
  }
6996
7295
 
6997
7296
  // src/native/NativeImportPanel.tsx
6998
- import { useEffect as useEffect22, useMemo as useMemo5, useState as useState34 } from "react";
6999
- import { confirm as confirm12 } from "@ai-matrx/kit/confirm-opener";
7000
- import { Badge as Badge9, Button as Button28, Select as Select9 } from "@ai-matrx/design-system/controls";
7297
+ import { useEffect as useEffect22, useMemo as useMemo5, useState as useState35 } from "react";
7298
+ import { confirm as confirm13 } from "@ai-matrx/kit/confirm-opener";
7299
+ import { Badge as Badge9, Button as Button29, Select as Select10 } from "@ai-matrx/design-system/controls";
7001
7300
 
7002
7301
  // src/native/logic.ts
7003
7302
  var ACTIVE_PHASES = /* @__PURE__ */ new Set(["authorizing", "importing"]);
@@ -7058,12 +7357,12 @@ async function loadFullPreview(bridge, operationId, current) {
7058
7357
  }
7059
7358
 
7060
7359
  // src/native/use-native-import.ts
7061
- import { useEffect as useEffect21, useRef as useRef17, useState as useState33 } from "react";
7360
+ import { useEffect as useEffect21, useRef as useRef17, useState as useState34 } from "react";
7062
7361
  var fail = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
7063
7362
  var RESTART = "Your account changed. The import was stopped; start it again.";
7064
7363
  function useNativeImport(bridge, stillAllowed, onImported) {
7065
- const [screen, setScreen] = useState33({ kind: "idle", message: null });
7066
- const [busy, setBusy] = useState33(false);
7364
+ const [screen, setScreen] = useState34({ kind: "idle", message: null });
7365
+ const [busy, setBusy] = useState34(false);
7067
7366
  const generation = useRef17(0);
7068
7367
  const mounted = useRef17(false);
7069
7368
  const op = useRef17(null);
@@ -7171,7 +7470,7 @@ function useNativeImport(bridge, stillAllowed, onImported) {
7171
7470
  }
7172
7471
  };
7173
7472
  refreshRef.current = refresh;
7174
- const confirm14 = async () => {
7473
+ const confirm15 = async () => {
7175
7474
  if (screen.kind !== "preview") return;
7176
7475
  const active = op.current;
7177
7476
  if (!active?.organizationId || active.id !== screen.preview.operation_id) return;
@@ -7253,11 +7552,11 @@ function useNativeImport(bridge, stillAllowed, onImported) {
7253
7552
  off?.();
7254
7553
  };
7255
7554
  }, [bridge]);
7256
- return { screen, busy, begin, refresh: () => refresh(false), confirm: confirm14, cancel, recover, reset };
7555
+ return { screen, busy, begin, refresh: () => refresh(false), confirm: confirm15, cancel, recover, reset };
7257
7556
  }
7258
7557
 
7259
7558
  // src/native/NativeImportPanel.tsx
7260
- import { Fragment as Fragment19, jsx as jsx33, jsxs as jsxs31 } from "react/jsx-runtime";
7559
+ import { Fragment as Fragment20, jsx as jsx34, jsxs as jsxs32 } from "react/jsx-runtime";
7261
7560
  var TONE = {
7262
7561
  eligible: "success",
7263
7562
  committed: "success",
@@ -7268,15 +7567,15 @@ var TONE = {
7268
7567
  };
7269
7568
  function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
7270
7569
  if (!bridge) {
7271
- return /* @__PURE__ */ jsx33(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ jsx33(VaultSection, { children: /* @__PURE__ */ jsx33(Empty, { children: "Passkey import needs the desktop app." }) }) });
7570
+ return /* @__PURE__ */ jsx34(Panel, { title: "Import passkeys", size: "md", onClose, footer: /* @__PURE__ */ jsx34(Button29, { variant: "primary", onClick: onClose, children: "Close" }), children: /* @__PURE__ */ jsx34(VaultSection, { children: /* @__PURE__ */ jsx34(Empty, { children: "Passkey import needs the desktop app." }) }) });
7272
7571
  }
7273
- return /* @__PURE__ */ jsx33(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
7572
+ return /* @__PURE__ */ jsx34(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
7274
7573
  }
7275
7574
  function Importer({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
7276
7575
  const options = useMemo5(() => organizations.map((o) => ({ value: o.id, label: o.name })), [organizations]);
7277
- const [organizationId, setOrganizationId] = useState34(() => organizations.some((o) => o.id === activeOrganizationId) ? activeOrganizationId : organizations[0]?.id ?? "");
7278
- const [limits, setLimits] = useState34(null);
7279
- const [limitError, setLimitError] = useState34(null);
7576
+ const [organizationId, setOrganizationId] = useState35(() => organizations.some((o) => o.id === activeOrganizationId) ? activeOrganizationId : organizations[0]?.id ?? "");
7577
+ const [limits, setLimits] = useState35(null);
7578
+ const [limitError, setLimitError] = useState35(null);
7280
7579
  const flow = useNativeImport(bridge, (id) => organizations.some((o) => o.id === id), onChanged);
7281
7580
  const { screen, busy } = flow;
7282
7581
  const orgName = organizations.find((o) => o.id === organizationId)?.name ?? "this organization";
@@ -7298,64 +7597,64 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
7298
7597
  const active = status !== null && !TERMINAL_PHASES.has(status.phase);
7299
7598
  const ready = preview?.slots.filter((s) => s.disposition === "eligible").length ?? 0;
7300
7599
  const importNow = async () => {
7301
- const yes = await confirm12({ title: `Add ${plural2(ready, "passkey")} to ${orgName}?`, description: "Passkeys already there are skipped.", confirmLabel: "Import" });
7600
+ const yes = await confirm13({ title: `Add ${plural2(ready, "passkey")} to ${orgName}?`, description: "Passkeys already there are skipped.", confirmLabel: "Import" });
7302
7601
  if (yes) await flow.confirm();
7303
7602
  };
7304
- const footer = preview ? /* @__PURE__ */ jsxs31(Fragment19, { children: [
7305
- /* @__PURE__ */ jsx33(Button28, { variant: "quiet", disabled: busy, onClick: () => void flow.cancel(), children: "Cancel" }),
7306
- /* @__PURE__ */ jsxs31(Button28, { variant: "primary", icon: /* @__PURE__ */ jsx33(ImportGlyph, { className: "size-4" }), disabled: busy || ready === 0, onClick: () => void importNow(), children: [
7603
+ const footer = preview ? /* @__PURE__ */ jsxs32(Fragment20, { children: [
7604
+ /* @__PURE__ */ jsx34(Button29, { variant: "quiet", disabled: busy, onClick: () => void flow.cancel(), children: "Cancel" }),
7605
+ /* @__PURE__ */ jsxs32(Button29, { variant: "primary", icon: /* @__PURE__ */ jsx34(ImportGlyph, { className: "size-4" }), disabled: busy || ready === 0, onClick: () => void importNow(), children: [
7307
7606
  "Import ",
7308
7607
  ready
7309
7608
  ] })
7310
- ] }) : status ? active ? /* @__PURE__ */ jsxs31(Fragment19, { children: [
7311
- /* @__PURE__ */ jsx33(Button28, { variant: "outline", disabled: busy, onClick: () => void flow.refresh(), children: "Refresh" }),
7312
- /* @__PURE__ */ jsx33(Button28, { variant: "outline", disabled: busy, onClick: () => void flow.cancel(), children: "Cancel import" })
7313
- ] }) : /* @__PURE__ */ jsxs31(Fragment19, { children: [
7314
- /* @__PURE__ */ jsx33(Button28, { variant: "quiet", onClick: flow.reset, children: "New file" }),
7315
- /* @__PURE__ */ jsx33(Button28, { variant: "primary", onClick: onClose, children: "Done" })
7316
- ] }) : /* @__PURE__ */ jsx33(Button28, { variant: "quiet", onClick: onClose, children: "Close" });
7317
- return /* @__PURE__ */ jsxs31(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
7318
- screen.kind === "idle" ? /* @__PURE__ */ jsxs31(VaultSection, { children: [
7319
- /* @__PURE__ */ jsx33(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx33(Select9, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
7320
- /* @__PURE__ */ jsx33(VaultRow, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ jsx33(Button28, { variant: "outline", icon: /* @__PURE__ */ jsx33(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
7321
- /* @__PURE__ */ jsx33(VaultRow, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ jsx33(Button28, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
7609
+ ] }) : status ? active ? /* @__PURE__ */ jsxs32(Fragment20, { children: [
7610
+ /* @__PURE__ */ jsx34(Button29, { variant: "outline", disabled: busy, onClick: () => void flow.refresh(), children: "Refresh" }),
7611
+ /* @__PURE__ */ jsx34(Button29, { variant: "outline", disabled: busy, onClick: () => void flow.cancel(), children: "Cancel import" })
7612
+ ] }) : /* @__PURE__ */ jsxs32(Fragment20, { children: [
7613
+ /* @__PURE__ */ jsx34(Button29, { variant: "quiet", onClick: flow.reset, children: "New file" }),
7614
+ /* @__PURE__ */ jsx34(Button29, { variant: "primary", onClick: onClose, children: "Done" })
7615
+ ] }) : /* @__PURE__ */ jsx34(Button29, { variant: "quiet", onClick: onClose, children: "Close" });
7616
+ return /* @__PURE__ */ jsxs32(Panel, { title: "Import passkeys", size: "lg", onClose, footer, children: [
7617
+ screen.kind === "idle" ? /* @__PURE__ */ jsxs32(VaultSection, { children: [
7618
+ /* @__PURE__ */ jsx34(VaultRow, { label: "Save to", children: /* @__PURE__ */ jsx34(Select10, { value: organizationId, options, "aria-label": "Save to", disabled: busy, onValueChange: setOrganizationId }) }),
7619
+ /* @__PURE__ */ jsx34(VaultRow, { label: "File", hint: limits ? `Up to ${plural2(limits.maxItems, "passkey")}` : "A passkey exchange file", children: /* @__PURE__ */ jsx34(Button29, { variant: "outline", icon: /* @__PURE__ */ jsx34(ImportGlyph, { className: "size-4" }), disabled: busy || !organizationId || limitError !== null, onClick: () => void flow.begin(organizationId), children: busy ? "Opening\u2026" : "Choose file" }) }),
7620
+ /* @__PURE__ */ jsx34(VaultRow, { label: "Interrupted", hint: "Finish or clear an earlier import", children: /* @__PURE__ */ jsx34(Button29, { variant: "quiet", disabled: busy, onClick: () => void flow.recover(), children: "Recover" }) })
7322
7621
  ] }) : null,
7323
- preview ? /* @__PURE__ */ jsx33(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ jsx33(
7622
+ preview ? /* @__PURE__ */ jsx34(VaultSection, { title: `${ready} of ${preview.total} ready`, children: /* @__PURE__ */ jsx34(
7324
7623
  Windowed,
7325
7624
  {
7326
7625
  items: preview.slots,
7327
- render: (slot) => /* @__PURE__ */ jsx33(VaultRow, { label: /* @__PURE__ */ jsx33(Badge9, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ jsx33("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
7626
+ render: (slot) => /* @__PURE__ */ jsx34(VaultRow, { label: /* @__PURE__ */ jsx34(Badge9, { tone: TONE[slot.disposition], children: dispositionLabel(slot.disposition) }), hint: void 0, children: /* @__PURE__ */ jsx34("span", { className: "block truncate text-foreground", title: slot.reason ?? void 0, children: slot.title ?? "Unnamed passkey" }) }, slot.slot_id)
7328
7627
  }
7329
7628
  ) }) : null,
7330
- status && !preview ? /* @__PURE__ */ jsxs31(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
7331
- /* @__PURE__ */ jsx33(VaultRow, { label: "Imported", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.committed }) }),
7332
- /* @__PURE__ */ jsx33(VaultRow, { label: "Already there", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.already_present }) }),
7333
- /* @__PURE__ */ jsx33(VaultRow, { label: "Can't import", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.unsupported }) }),
7334
- /* @__PURE__ */ jsx33(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx33("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
7335
- status.uncertain > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Needs recovery", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.uncertain }) }) : null,
7336
- status.not_attempted > 0 ? /* @__PURE__ */ jsx33(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx33("span", { className: "text-foreground", children: status.not_attempted }) }) : null
7629
+ status && !preview ? /* @__PURE__ */ jsxs32(VaultSection, { title: `${accounted(status)} of ${status.total} done`, children: [
7630
+ /* @__PURE__ */ jsx34(VaultRow, { label: "Imported", children: /* @__PURE__ */ jsx34("span", { className: "text-foreground", children: status.committed }) }),
7631
+ /* @__PURE__ */ jsx34(VaultRow, { label: "Already there", children: /* @__PURE__ */ jsx34("span", { className: "text-foreground", children: status.already_present }) }),
7632
+ /* @__PURE__ */ jsx34(VaultRow, { label: "Can't import", children: /* @__PURE__ */ jsx34("span", { className: "text-foreground", children: status.unsupported }) }),
7633
+ /* @__PURE__ */ jsx34(VaultRow, { label: "Failed", children: /* @__PURE__ */ jsx34("span", { className: status.failed > 0 ? "text-destructive" : "text-foreground", children: status.failed }) }),
7634
+ status.uncertain > 0 ? /* @__PURE__ */ jsx34(VaultRow, { label: "Needs recovery", children: /* @__PURE__ */ jsx34("span", { className: "text-foreground", children: status.uncertain }) }) : null,
7635
+ status.not_attempted > 0 ? /* @__PURE__ */ jsx34(VaultRow, { label: "Not tried", children: /* @__PURE__ */ jsx34("span", { className: "text-foreground", children: status.not_attempted }) }) : null
7337
7636
  ] }) : null,
7338
- screen.message ? /* @__PURE__ */ jsx33("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
7339
- /* @__PURE__ */ jsx33(ErrorLine, { message: limitError })
7637
+ screen.message ? /* @__PURE__ */ jsx34("p", { role: "status", className: "px-1 text-sm text-muted-foreground", children: screen.message }) : null,
7638
+ /* @__PURE__ */ jsx34(ErrorLine, { message: limitError })
7340
7639
  ] });
7341
7640
  }
7342
7641
 
7343
7642
  // src/extension/PageView.tsx
7344
- import { useState as useState38 } from "react";
7345
- import { DropdownMenu as DropdownMenu5, DropdownMenuContent as DropdownMenuContent5, DropdownMenuItem as DropdownMenuItem4, DropdownMenuTrigger as DropdownMenuTrigger5, SiteIcon } from "@ai-matrx/design-system";
7346
- import { Button as Button32 } from "@ai-matrx/design-system/controls";
7643
+ import { useState as useState39 } from "react";
7644
+ import { DropdownMenu as DropdownMenu5, DropdownMenuContent as DropdownMenuContent5, DropdownMenuItem as DropdownMenuItem5, DropdownMenuTrigger as DropdownMenuTrigger5, SiteIcon } from "@ai-matrx/design-system";
7645
+ import { Button as Button33 } from "@ai-matrx/design-system/controls";
7347
7646
  import { GlobeIcon as GlobeIcon4 } from "@ai-matrx/design-system/icons";
7348
7647
 
7349
7648
  // src/extension/CaptureCard.tsx
7350
- import { useState as useState35, useSyncExternalStore as useSyncExternalStore3 } from "react";
7351
- import { Button as Button29, SearchField as SearchField3 } from "@ai-matrx/design-system/controls";
7352
- import { Fragment as Fragment20, jsx as jsx34, jsxs as jsxs32 } from "react/jsx-runtime";
7649
+ import { useState as useState36, useSyncExternalStore as useSyncExternalStore3 } from "react";
7650
+ import { Button as Button30, SearchField as SearchField3 } from "@ai-matrx/design-system/controls";
7651
+ import { Fragment as Fragment21, jsx as jsx35, jsxs as jsxs33 } from "react/jsx-runtime";
7353
7652
  var SEARCH_FROM = 4;
7354
7653
  function CaptureCard({ capture, onChanged }) {
7355
7654
  const prompt = useSyncExternalStore3(capture.subscribe, capture.get, capture.get);
7356
7655
  const notify = useNotify();
7357
- const [busy, setBusy] = useState35(false);
7358
- const [q, setQ] = useState35("");
7656
+ const [busy, setBusy] = useState36(false);
7657
+ const [q, setQ] = useState36("");
7359
7658
  if (!prompt) return null;
7360
7659
  const decide = async (d) => {
7361
7660
  setBusy(true);
@@ -7373,53 +7672,53 @@ function CaptureCard({ capture, onChanged }) {
7373
7672
  const existing = prompt.existing;
7374
7673
  const needle = q.trim().toLocaleLowerCase();
7375
7674
  const shown = needle ? existing.filter((x) => x.name.toLocaleLowerCase().includes(needle)) : existing;
7376
- return /* @__PURE__ */ jsxs32("section", { "aria-label": "Save this login", className: "flex flex-col gap-2 rounded-xl border border-border bg-card px-3 py-2.5", children: [
7377
- /* @__PURE__ */ jsxs32("div", { className: "flex items-center gap-2.5", children: [
7378
- /* @__PURE__ */ jsx34(ShieldGlyph, { className: "size-5 shrink-0 text-primary" }),
7379
- /* @__PURE__ */ jsxs32("div", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
7380
- /* @__PURE__ */ jsx34("span", { className: "truncate text-sm font-medium", children: prompt.unavailable ? "Couldn\u2019t hold this login" : "Save this login?" }),
7381
- /* @__PURE__ */ jsx34("span", { className: "truncate text-xs text-muted-foreground", children: prompt.username ? `${prompt.host} \xB7 ${prompt.username}` : prompt.host })
7675
+ return /* @__PURE__ */ jsxs33("section", { "aria-label": "Save this login", className: "flex flex-col gap-2 rounded-xl border border-border bg-card px-3 py-2.5", children: [
7676
+ /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-2.5", children: [
7677
+ /* @__PURE__ */ jsx35(ShieldGlyph, { className: "size-5 shrink-0 text-primary" }),
7678
+ /* @__PURE__ */ jsxs33("div", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
7679
+ /* @__PURE__ */ jsx35("span", { className: "truncate text-sm font-medium", children: prompt.unavailable ? "Couldn\u2019t hold this login" : "Save this login?" }),
7680
+ /* @__PURE__ */ jsx35("span", { className: "truncate text-xs text-muted-foreground", children: prompt.username ? `${prompt.host} \xB7 ${prompt.username}` : prompt.host })
7382
7681
  ] }),
7383
- /* @__PURE__ */ jsx34(Button29, { variant: "quiet", icon: /* @__PURE__ */ jsx34(XGlyph, {}), "aria-label": "Not now", disabled: busy, onClick: () => void decide({ action: "dismiss" }) })
7682
+ /* @__PURE__ */ jsx35(Button30, { variant: "quiet", icon: /* @__PURE__ */ jsx35(XGlyph, {}), "aria-label": "Not now", disabled: busy, onClick: () => void decide({ action: "dismiss" }) })
7384
7683
  ] }),
7385
- prompt.unavailable ? /* @__PURE__ */ jsx34("p", { className: "text-xs text-muted-foreground", children: "Save it by hand with Save a login." }) : /* @__PURE__ */ jsxs32(Fragment20, { children: [
7386
- existing.length > 0 ? /* @__PURE__ */ jsxs32("div", { className: "flex flex-col gap-1", children: [
7387
- existing.length >= SEARCH_FROM ? /* @__PURE__ */ jsx34(SearchField3, { value: q, onChange: (e) => setQ(e.target.value), placeholder: "Search logins", "aria-label": "Search logins to update" }) : null,
7388
- /* @__PURE__ */ jsxs32("ul", { className: "flex max-h-36 flex-col gap-px overflow-y-auto", children: [
7684
+ prompt.unavailable ? /* @__PURE__ */ jsx35("p", { className: "text-xs text-muted-foreground", children: "Save it by hand with Save a login." }) : /* @__PURE__ */ jsxs33(Fragment21, { children: [
7685
+ existing.length > 0 ? /* @__PURE__ */ jsxs33("div", { className: "flex flex-col gap-1", children: [
7686
+ existing.length >= SEARCH_FROM ? /* @__PURE__ */ jsx35(SearchField3, { value: q, onChange: (e) => setQ(e.target.value), placeholder: "Search logins", "aria-label": "Search logins to update" }) : null,
7687
+ /* @__PURE__ */ jsxs33("ul", { className: "flex max-h-36 flex-col gap-px overflow-y-auto", children: [
7389
7688
  shown.map((x) => {
7390
7689
  const tag = distinguish(x, existing);
7391
- return /* @__PURE__ */ jsxs32("li", { className: "flex h-9 items-center gap-2 px-1", children: [
7392
- /* @__PURE__ */ jsxs32("span", { className: "min-w-0 flex-1 truncate text-sm", children: [
7690
+ return /* @__PURE__ */ jsxs33("li", { className: "flex h-9 items-center gap-2 px-1", children: [
7691
+ /* @__PURE__ */ jsxs33("span", { className: "min-w-0 flex-1 truncate text-sm", children: [
7393
7692
  x.name,
7394
- tag ? /* @__PURE__ */ jsxs32("span", { className: "text-muted-foreground", children: [
7693
+ tag ? /* @__PURE__ */ jsxs33("span", { className: "text-muted-foreground", children: [
7395
7694
  " \xB7 ",
7396
7695
  tag
7397
7696
  ] }) : null
7398
7697
  ] }),
7399
- /* @__PURE__ */ jsx34(Button29, { variant: "primary", disabled: busy, onClick: () => void decide({ action: "update", itemId: x.itemId }), "aria-label": `Update ${x.name}`, children: "Update" })
7698
+ /* @__PURE__ */ jsx35(Button30, { variant: "primary", disabled: busy, onClick: () => void decide({ action: "update", itemId: x.itemId }), "aria-label": `Update ${x.name}`, children: "Update" })
7400
7699
  ] }, x.itemId);
7401
7700
  }),
7402
- shown.length === 0 ? /* @__PURE__ */ jsx34("li", { className: "px-1 py-2 text-xs text-muted-foreground", children: "No saved login matches." }) : null
7701
+ shown.length === 0 ? /* @__PURE__ */ jsx35("li", { className: "px-1 py-2 text-xs text-muted-foreground", children: "No saved login matches." }) : null
7403
7702
  ] })
7404
7703
  ] }) : null,
7405
- /* @__PURE__ */ jsxs32("div", { className: "flex flex-wrap items-center gap-2", children: [
7406
- /* @__PURE__ */ jsx34(Button29, { variant: existing.length > 0 ? "outline" : "primary", disabled: busy, onClick: () => void decide({ action: "save" }), children: existing.length > 0 ? "Save as new" : "Save" }),
7407
- /* @__PURE__ */ jsx34(Button29, { variant: "quiet", disabled: busy, onClick: () => void decide({ action: "never" }), children: "Never here" })
7704
+ /* @__PURE__ */ jsxs33("div", { className: "flex flex-wrap items-center gap-2", children: [
7705
+ /* @__PURE__ */ jsx35(Button30, { variant: existing.length > 0 ? "outline" : "primary", disabled: busy, onClick: () => void decide({ action: "save" }), children: existing.length > 0 ? "Save as new" : "Save" }),
7706
+ /* @__PURE__ */ jsx35(Button30, { variant: "quiet", disabled: busy, onClick: () => void decide({ action: "never" }), children: "Never here" })
7408
7707
  ] })
7409
7708
  ] })
7410
7709
  ] });
7411
7710
  }
7412
7711
 
7413
7712
  // src/extension/FillSetupCard.tsx
7414
- import { useRef as useRef18, useState as useState36, useSyncExternalStore as useSyncExternalStore4 } from "react";
7415
- import { Button as Button30, Field as Field12 } from "@ai-matrx/design-system/controls";
7416
- import { jsx as jsx35, jsxs as jsxs33 } from "react/jsx-runtime";
7713
+ import { useRef as useRef18, useState as useState37, useSyncExternalStore as useSyncExternalStore4 } from "react";
7714
+ import { Button as Button31, Field as Field13 } from "@ai-matrx/design-system/controls";
7715
+ import { jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
7417
7716
  function FillSetupCard({ fillSetup }) {
7418
7717
  const notify = useNotify();
7419
7718
  const state = useSyncExternalStore4(fillSetup.subscribe, fillSetup.get, fillSetup.get);
7420
7719
  const box = useRef18(null);
7421
- const [busy, setBusy] = useState36(false);
7422
- const [error, setError] = useState36(null);
7720
+ const [busy, setBusy] = useState37(false);
7721
+ const [error, setError] = useState37(null);
7423
7722
  if (state.status !== "off") return null;
7424
7723
  const finish = async (run) => {
7425
7724
  setBusy(true);
@@ -7445,15 +7744,15 @@ function FillSetupCard({ fillSetup }) {
7445
7744
  const neither = m !== null && !m.password && !m.passkey;
7446
7745
  const showPassword = !neither && (m === null || m.password);
7447
7746
  const showPasskey = state.passkey !== null && (neither || m === null || m.passkey);
7448
- return /* @__PURE__ */ jsxs33("section", { "aria-label": "Turn on filling", "data-testid": "fill-setup", className: "flex flex-col gap-2 rounded-xl border border-border bg-card px-3 py-2.5", children: [
7449
- /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-2.5", children: [
7450
- /* @__PURE__ */ jsx35(KeyGlyph, { className: "size-5 shrink-0 text-primary" }),
7451
- /* @__PURE__ */ jsxs33("div", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
7452
- /* @__PURE__ */ jsx35("span", { className: "truncate text-sm font-medium", children: "Turn on filling" }),
7453
- /* @__PURE__ */ jsx35("span", { className: "truncate text-xs text-muted-foreground", children: neither ? "Add a passkey on the web first." : "Confirm it\u2019s you once in this browser." })
7747
+ return /* @__PURE__ */ jsxs34("section", { "aria-label": "Turn on filling", "data-testid": "fill-setup", className: "flex flex-col gap-2 rounded-xl border border-border bg-card px-3 py-2.5", children: [
7748
+ /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2.5", children: [
7749
+ /* @__PURE__ */ jsx36(KeyGlyph, { className: "size-5 shrink-0 text-primary" }),
7750
+ /* @__PURE__ */ jsxs34("div", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
7751
+ /* @__PURE__ */ jsx36("span", { className: "truncate text-sm font-medium", children: "Turn on filling" }),
7752
+ /* @__PURE__ */ jsx36("span", { className: "truncate text-xs text-muted-foreground", children: neither ? "Add a passkey on the web first." : "Confirm it\u2019s you once in this browser." })
7454
7753
  ] })
7455
7754
  ] }),
7456
- showPassword ? /* @__PURE__ */ jsxs33(
7755
+ showPassword ? /* @__PURE__ */ jsxs34(
7457
7756
  "form",
7458
7757
  {
7459
7758
  className: "flex items-center gap-2",
@@ -7462,42 +7761,42 @@ function FillSetupCard({ fillSetup }) {
7462
7761
  withPassword();
7463
7762
  },
7464
7763
  children: [
7465
- /* @__PURE__ */ jsx35(Field12, { ref: box, className: "min-w-0 flex-1", type: "password", autoComplete: "current-password", placeholder: "AI Matrx password", "aria-label": "Your AI Matrx password", disabled: busy }),
7466
- /* @__PURE__ */ jsx35(Button30, { variant: "primary", type: "submit", disabled: busy, children: "Turn on" })
7764
+ /* @__PURE__ */ jsx36(Field13, { ref: box, className: "min-w-0 flex-1", type: "password", autoComplete: "current-password", placeholder: "AI Matrx password", "aria-label": "Your AI Matrx password", disabled: busy }),
7765
+ /* @__PURE__ */ jsx36(Button31, { variant: "primary", type: "submit", disabled: busy, children: "Turn on" })
7467
7766
  ]
7468
7767
  }
7469
7768
  ) : null,
7470
- showPasskey ? /* @__PURE__ */ jsx35(Button30, { variant: "outline", iconEnd: /* @__PURE__ */ jsx35(ExternalGlyph, {}), disabled: busy, onClick: () => {
7769
+ showPasskey ? /* @__PURE__ */ jsx36(Button31, { variant: "outline", iconEnd: /* @__PURE__ */ jsx36(ExternalGlyph, {}), disabled: busy, onClick: () => {
7471
7770
  setError(null);
7472
7771
  fillSetup.openPasskey();
7473
7772
  }, children: neither ? "Add a passkey" : "Use a passkey" }) : null,
7474
- showPasskey && state.awaitingPasskey && state.passkey ? /* @__PURE__ */ jsxs33("div", { className: "flex items-center gap-2", "data-testid": "fill-setup-waiting", children: [
7475
- /* @__PURE__ */ jsxs33("span", { className: "min-w-0 flex-1 text-xs text-muted-foreground", children: [
7773
+ showPasskey && state.awaitingPasskey && state.passkey ? /* @__PURE__ */ jsxs34("div", { className: "flex items-center gap-2", "data-testid": "fill-setup-waiting", children: [
7774
+ /* @__PURE__ */ jsxs34("span", { className: "min-w-0 flex-1 text-xs text-muted-foreground", children: [
7476
7775
  "Approve code ",
7477
- /* @__PURE__ */ jsx35("span", { className: "font-mono text-foreground", children: state.passkey.code }),
7776
+ /* @__PURE__ */ jsx36("span", { className: "font-mono text-foreground", children: state.passkey.code }),
7478
7777
  " on that page."
7479
7778
  ] }),
7480
- /* @__PURE__ */ jsx35(Button30, { variant: "primary", disabled: busy, onClick: () => void finish(() => fillSetup.finishPasskey()), children: "I approved" })
7779
+ /* @__PURE__ */ jsx36(Button31, { variant: "primary", disabled: busy, onClick: () => void finish(() => fillSetup.finishPasskey()), children: "I approved" })
7481
7780
  ] }) : null,
7482
- error ? /* @__PURE__ */ jsx35("p", { role: "alert", className: "text-xs text-destructive", children: error }) : null
7781
+ error ? /* @__PURE__ */ jsx36("p", { role: "alert", className: "text-xs text-destructive", children: error }) : null
7483
7782
  ] });
7484
7783
  }
7485
7784
 
7486
7785
  // src/extension/PageGenerator.tsx
7487
- import { useState as useState37 } from "react";
7786
+ import { useState as useState38 } from "react";
7488
7787
  import { Popover as Popover2, PopoverContent as PopoverContent2, PopoverTrigger as PopoverTrigger2 } from "@ai-matrx/design-system";
7489
- import { Button as Button31 } from "@ai-matrx/design-system/controls";
7490
- import { CopyIcon as CopyIcon7 } from "@ai-matrx/design-system/icons";
7491
- import { Fragment as Fragment21, jsx as jsx36, jsxs as jsxs34 } from "react/jsx-runtime";
7788
+ import { Button as Button32 } from "@ai-matrx/design-system/controls";
7789
+ import { CopyIcon as CopyIcon8 } from "@ai-matrx/design-system/icons";
7790
+ import { Fragment as Fragment22, jsx as jsx37, jsxs as jsxs35 } from "react/jsx-runtime";
7492
7791
  var HOLD_MS = 6e4;
7493
7792
  function PageGenerator({ fields }) {
7494
7793
  const limits = useGeneratorLimitsSource();
7495
7794
  const copy = useCopy();
7496
7795
  const held = useTransientSecret(HOLD_MS);
7497
- const [open, setOpen] = useState37(false);
7498
- const [busy, setBusy] = useState37(false);
7499
- const [targets, setTargets] = useState37([]);
7500
- const [said, setSaid] = useState37(null);
7796
+ const [open, setOpen] = useState38(false);
7797
+ const [busy, setBusy] = useState38(false);
7798
+ const [targets, setTargets] = useState38([]);
7799
+ const [said, setSaid] = useState38(null);
7501
7800
  if (!limits) return null;
7502
7801
  const say3 = setSaid;
7503
7802
  const put = async (targetId, value2) => {
@@ -7539,30 +7838,30 @@ function PageGenerator({ fields }) {
7539
7838
  }
7540
7839
  };
7541
7840
  const value = held.value;
7542
- return /* @__PURE__ */ jsxs34(Fragment21, { children: [
7543
- /* @__PURE__ */ jsx36(
7841
+ return /* @__PURE__ */ jsxs35(Fragment22, { children: [
7842
+ /* @__PURE__ */ jsx37(
7544
7843
  VaultRow,
7545
7844
  {
7546
7845
  label: "New password",
7547
- actions: /* @__PURE__ */ jsxs34(Fragment21, { children: [
7548
- value ? /* @__PURE__ */ jsx36(Button31, { variant: "quiet", icon: /* @__PURE__ */ jsx36(CopyIcon7, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
7549
- /* @__PURE__ */ jsxs34(Popover2, { open, onOpenChange: setOpen, children: [
7550
- /* @__PURE__ */ jsx36(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx36(Button31, { variant: "outline", icon: /* @__PURE__ */ jsx36(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
7551
- /* @__PURE__ */ jsx36(PopoverContent2, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ jsx36(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
7846
+ actions: /* @__PURE__ */ jsxs35(Fragment22, { children: [
7847
+ value ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(CopyIcon8, {}), "aria-label": "Copy password", onClick: () => void copy(value, "Password") }) : null,
7848
+ /* @__PURE__ */ jsxs35(Popover2, { open, onOpenChange: setOpen, children: [
7849
+ /* @__PURE__ */ jsx37(PopoverTrigger2, { asChild: true, children: /* @__PURE__ */ jsx37(Button32, { variant: "outline", icon: /* @__PURE__ */ jsx37(KeyGlyph, {}), disabled: busy, children: "Generate" }) }),
7850
+ /* @__PURE__ */ jsx37(PopoverContent2, { sizing: "content", align: "end", children: open ? /* @__PURE__ */ jsx37(PasswordGenerator, { limits, useLabel: "Fill page", onUse: (v) => void onUse(v) }) : null })
7552
7851
  ] })
7553
7852
  ] }),
7554
- children: said ? /* @__PURE__ */ jsx36("span", { role: "status", className: said.tone === "success" ? "line-clamp-2 text-xs text-foreground" : "line-clamp-2 text-xs text-muted-foreground", children: said.text }) : targets.length > 0 ? /* @__PURE__ */ jsx36("span", { className: "text-xs text-muted-foreground", children: "Choose the boxes to fill." }) : /* @__PURE__ */ jsx36("span", { className: "text-xs text-disabled-foreground", children: "Fills the page\u2019s new-password box" })
7853
+ children: said ? /* @__PURE__ */ jsx37("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__ */ jsx37("span", { className: "text-xs text-muted-foreground", children: "Choose the boxes to fill." }) : /* @__PURE__ */ jsx37("span", { className: "text-xs text-disabled-foreground", children: "Fills the page\u2019s new-password box" })
7555
7854
  }
7556
7855
  ),
7557
- value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ jsx36(VaultRow, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ jsx36(Button31, { variant: "primary", icon: /* @__PURE__ */ jsx36(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ jsx36("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
7856
+ value && targets.length > 0 ? targets.map((t) => /* @__PURE__ */ jsx37(VaultRow, { label: t.topFrame ? "This page" : "In a frame", actions: /* @__PURE__ */ jsx37(Button32, { variant: "primary", icon: /* @__PURE__ */ jsx37(CheckGlyph, {}), disabled: busy, onClick: () => void put(t.id, value), children: "Fill" }), children: /* @__PURE__ */ jsx37("span", { className: "block truncate text-sm", children: targetLabel(t) }) }, t.id)) : null
7558
7857
  ] });
7559
7858
  }
7560
7859
 
7561
7860
  // src/extension/PageView.tsx
7562
- import { jsx as jsx37, jsxs as jsxs35 } from "react/jsx-runtime";
7861
+ import { jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
7563
7862
  function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, items, definitions, onOpen, onNewForPage, onBrowse, onChanged, header }) {
7564
- const [running, setRunning] = useState38(null);
7565
- const [said, setSaid] = useState38(null);
7863
+ const [running, setRunning] = useState39(null);
7864
+ const [said, setSaid] = useState39(null);
7566
7865
  const site = pageSite(page.url);
7567
7866
  const state = page.matchState ?? { status: "ready" };
7568
7867
  const fillable = new Set(page.fillableItemIds ?? page.matchingItemIds);
@@ -7583,20 +7882,20 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7583
7882
  }
7584
7883
  };
7585
7884
  let body;
7586
- if (!page.url) body = /* @__PURE__ */ jsx37(Empty, { children: "No page is open in this tab." });
7885
+ if (!page.url) body = /* @__PURE__ */ jsx38(Empty, { children: "No page is open in this tab." });
7587
7886
  else if (state.status === "error") {
7588
- body = /* @__PURE__ */ jsxs35("div", { className: "flex items-center gap-2 px-3 py-2 sm:px-4", children: [
7589
- /* @__PURE__ */ jsx37("span", { role: "alert", className: "min-w-0 flex-1 text-sm text-muted-foreground", children: MATCH_ERROR_WORDS[state.reason] }),
7590
- /* @__PURE__ */ jsx37(Button32, { variant: "outline", icon: /* @__PURE__ */ jsx37(RefreshGlyph, {}), onClick: state.retry, children: "Retry" })
7887
+ body = /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 px-3 py-2 sm:px-4", children: [
7888
+ /* @__PURE__ */ jsx38("span", { role: "alert", className: "min-w-0 flex-1 text-sm text-muted-foreground", children: MATCH_ERROR_WORDS[state.reason] }),
7889
+ /* @__PURE__ */ jsx38(Button33, { variant: "outline", icon: /* @__PURE__ */ jsx38(RefreshGlyph, {}), onClick: state.retry, children: "Retry" })
7591
7890
  ] });
7592
7891
  } else if (state.status === "loading") {
7593
- body = /* @__PURE__ */ jsx37("div", { "aria-busy": "true", "aria-label": "Checking saved logins", className: "flex flex-col", children: [0, 1].map((n) => /* @__PURE__ */ jsxs35("div", { className: "flex h-12 items-center gap-3 px-3", children: [
7594
- /* @__PURE__ */ jsx37("div", { className: "size-8 animate-pulse rounded-lg bg-muted" }),
7595
- /* @__PURE__ */ jsx37("div", { className: "h-3 w-1/2 animate-pulse rounded bg-muted" })
7892
+ body = /* @__PURE__ */ jsx38("div", { "aria-busy": "true", "aria-label": "Checking saved logins", className: "flex flex-col", children: [0, 1].map((n) => /* @__PURE__ */ jsxs36("div", { className: "flex h-12 items-center gap-3 px-3", children: [
7893
+ /* @__PURE__ */ jsx38("div", { className: "size-8 animate-pulse rounded-lg bg-muted" }),
7894
+ /* @__PURE__ */ jsx38("div", { className: "h-3 w-1/2 animate-pulse rounded bg-muted" })
7596
7895
  ] }, n)) });
7597
- } else if (matches.length === 0) body = /* @__PURE__ */ jsx37(Empty, { children: "No saved login for this site." });
7896
+ } else if (matches.length === 0) body = /* @__PURE__ */ jsx38(Empty, { children: "No saved login for this site." });
7598
7897
  else {
7599
- body = /* @__PURE__ */ jsx37("ul", { className: "flex flex-col", children: matches.map(({ itemId, item }) => /* @__PURE__ */ jsx37(
7898
+ body = /* @__PURE__ */ jsx38("ul", { className: "flex flex-col", children: matches.map(({ itemId, item }) => /* @__PURE__ */ jsx38(
7600
7899
  MatchRow,
7601
7900
  {
7602
7901
  itemId,
@@ -7613,40 +7912,40 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
7613
7912
  itemId
7614
7913
  )) });
7615
7914
  }
7616
- return /* @__PURE__ */ jsx37("div", { className: "flex h-full min-h-0 flex-col overflow-y-auto bg-background text-foreground", children: /* @__PURE__ */ jsxs35("div", { className: "flex flex-col gap-3 px-3 pb-4 pt-3", children: [
7915
+ return /* @__PURE__ */ jsx38("div", { className: "flex h-full min-h-0 flex-col overflow-y-auto bg-background text-foreground", children: /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-3 px-3 pb-4 pt-3", children: [
7617
7916
  header,
7618
- /* @__PURE__ */ jsxs35("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
7619
- /* @__PURE__ */ jsx37(SiteIcon, { site: page.url, fallback: GlobeIcon4, className: "size-4" }),
7620
- /* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
7621
- page.refresh ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
7622
- onBrowse ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
7917
+ /* @__PURE__ */ jsxs36("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
7918
+ /* @__PURE__ */ jsx38(SiteIcon, { site: page.url, fallback: GlobeIcon4, className: "size-4" }),
7919
+ /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
7920
+ page.refresh ? /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
7921
+ onBrowse ? /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
7623
7922
  ] }),
7624
- fillSetup ? /* @__PURE__ */ jsx37(FillSetupCard, { fillSetup }) : null,
7625
- capture ? /* @__PURE__ */ jsx37(CaptureCard, { capture, onChanged }) : null,
7626
- /* @__PURE__ */ jsx37(
7923
+ fillSetup ? /* @__PURE__ */ jsx38(FillSetupCard, { fillSetup }) : null,
7924
+ capture ? /* @__PURE__ */ jsx38(CaptureCard, { capture, onChanged }) : null,
7925
+ /* @__PURE__ */ jsx38(
7627
7926
  VaultSection,
7628
7927
  {
7629
7928
  title: "This site",
7630
- actions: canSave ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
7929
+ actions: canSave ? /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(PlusGlyph, {}), onClick: () => onNewForPage(normalizeLoginUrl2(page.url) ?? page.url), children: "Save a login" }) : null,
7631
7930
  children: body
7632
7931
  }
7633
7932
  ),
7634
- said ? /* @__PURE__ */ jsx37(Outcome, { said, onDismiss: () => setSaid(null) }) : page.blocked && page.url && state.status === "ready" ? /* @__PURE__ */ jsx37("p", { className: "px-1 text-xs text-muted-foreground", children: BLOCK_WORDS[page.blocked] }) : null,
7635
- newPasswordFields && canSave ? /* @__PURE__ */ jsx37(VaultSection, { children: /* @__PURE__ */ jsx37(PageGenerator, { fields: newPasswordFields }) }) : null
7933
+ said ? /* @__PURE__ */ jsx38(Outcome, { said, onDismiss: () => setSaid(null) }) : page.blocked && page.url && state.status === "ready" ? /* @__PURE__ */ jsx38("p", { className: "px-1 text-xs text-muted-foreground", children: BLOCK_WORDS[page.blocked] }) : null,
7934
+ newPasswordFields && canSave ? /* @__PURE__ */ jsx38(VaultSection, { children: /* @__PURE__ */ jsx38(PageGenerator, { fields: newPasswordFields }) }) : null
7636
7935
  ] }) });
7637
7936
  }
7638
7937
  function Outcome({ said, onDismiss }) {
7639
- return /* @__PURE__ */ jsxs35("div", { role: "status", className: "flex items-center gap-2 px-1", children: [
7640
- said.tone === "success" ? /* @__PURE__ */ jsx37(CheckGlyph, { className: "size-4 shrink-0 text-primary" }) : /* @__PURE__ */ jsx37(ShieldGlyph, { className: "size-4 shrink-0 text-destructive" }),
7641
- /* @__PURE__ */ jsx37("span", { className: "min-w-0 flex-1 text-xs text-foreground", children: said.text }),
7642
- /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(XGlyph, {}), "aria-label": "Dismiss", onClick: onDismiss })
7938
+ return /* @__PURE__ */ jsxs36("div", { role: "status", className: "flex items-center gap-2 px-1", children: [
7939
+ said.tone === "success" ? /* @__PURE__ */ jsx38(CheckGlyph, { className: "size-4 shrink-0 text-primary" }) : /* @__PURE__ */ jsx38(ShieldGlyph, { className: "size-4 shrink-0 text-destructive" }),
7940
+ /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 text-xs text-foreground", children: said.text }),
7941
+ /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(XGlyph, {}), "aria-label": "Dismiss", onClick: onDismiss })
7643
7942
  ] });
7644
7943
  }
7645
7944
  function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFill, onSignIn }) {
7646
7945
  const confirmed = useConfirmed();
7647
7946
  const copy = useCopy();
7648
7947
  const notify = useNotify();
7649
- const [reading, setReading] = useState38(false);
7948
+ const [reading, setReading] = useState39(false);
7650
7949
  const usable = item?.capabilities.canUse ?? false;
7651
7950
  const user = usable ? item?.fields.find((f) => USERNAME_KEYS.test(f.key) && f.handling !== "sealed" && f.active) : void 0;
7652
7951
  const secret = usable && item?.capabilities.canReveal ? item?.fields.find((f) => f.key === "password" && f.handling === "revealable" && f.active) : void 0;
@@ -7662,27 +7961,27 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
7662
7961
  }
7663
7962
  };
7664
7963
  const subtitle = [item ? loginSiteOf(item) || item.definitionLabel : "", tag].filter(Boolean).join(" \xB7 ");
7665
- return /* @__PURE__ */ jsxs35("li", { className: "flex h-12 items-center gap-1 pl-1 pr-2", "data-item": itemId, children: [
7666
- /* @__PURE__ */ jsxs35("button", { type: "button", onClick: () => onOpen(itemId), className: "flex h-11 min-w-0 flex-1 items-center gap-3 rounded-lg px-2 text-left hover:bg-accent", children: [
7667
- /* @__PURE__ */ jsx37(ItemIcon, { definitionKey: item?.definitionKey ?? "website_login", family, site: item ? loginSiteOf(item) : "" }),
7668
- /* @__PURE__ */ jsxs35("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
7669
- /* @__PURE__ */ jsx37("span", { className: "truncate text-sm font-medium", children: item?.name ?? "Saved login" }),
7670
- subtitle ? /* @__PURE__ */ jsx37("span", { className: "truncate text-xs text-muted-foreground", children: subtitle }) : null
7964
+ return /* @__PURE__ */ jsxs36("li", { className: "flex h-12 items-center gap-1 pl-1 pr-2", "data-item": itemId, children: [
7965
+ /* @__PURE__ */ jsxs36("button", { type: "button", onClick: () => onOpen(itemId), className: "flex h-11 min-w-0 flex-1 items-center gap-3 rounded-lg px-2 text-left hover:bg-accent", children: [
7966
+ /* @__PURE__ */ jsx38(ItemIcon, { definitionKey: item?.definitionKey ?? "website_login", family, site: item ? loginSiteOf(item) : "" }),
7967
+ /* @__PURE__ */ jsxs36("span", { className: "flex min-w-0 flex-1 flex-col leading-tight", children: [
7968
+ /* @__PURE__ */ jsx38("span", { className: "truncate text-sm font-medium", children: item?.name ?? "Saved login" }),
7969
+ subtitle ? /* @__PURE__ */ jsx38("span", { className: "truncate text-xs text-muted-foreground", children: subtitle }) : null
7671
7970
  ] })
7672
7971
  ] }),
7673
- onFill ? /* @__PURE__ */ jsx37(Button32, { variant: "primary", disabled: busy, "aria-busy": running || void 0, onClick: onFill, "aria-label": `Fill ${item?.name ?? "this login"}`, children: running ? "Filling\u2026" : "Fill" }) : null,
7674
- user && item ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(UserGlyph, {}), "aria-label": `Copy ${user.label}`, title: `Copy ${user.label}`, disabled: reading, onClick: () => void read(user.label, () => port.reveal(item, user.key)) }) : null,
7675
- secret && item ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(KeyGlyph, {}), "aria-label": "Copy password", title: "Copy password", disabled: reading, onClick: () => void read("Password", () => port.reveal(item, secret.key)) }) : null,
7676
- otp ? /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(ClockGlyph, {}), "aria-label": "Copy one-time code", title: "Copy one-time code", disabled: reading, onClick: () => void read("One-time code", async () => (await port.authenticator.code(otp)).code) }) : null,
7677
- onSignIn ? /* @__PURE__ */ jsxs35(DropdownMenu5, { children: [
7678
- /* @__PURE__ */ jsx37(DropdownMenuTrigger5, { asChild: true, children: /* @__PURE__ */ jsx37(Button32, { variant: "quiet", icon: /* @__PURE__ */ jsx37(MoreGlyph, {}), "aria-label": "More", disabled: busy }) }),
7679
- /* @__PURE__ */ jsxs35(DropdownMenuContent5, { align: "end", children: [
7680
- /* @__PURE__ */ jsxs35(DropdownMenuItem4, { onSelect: onSignIn, children: [
7681
- /* @__PURE__ */ jsx37(ShieldGlyph, { className: "size-4" }),
7972
+ onFill ? /* @__PURE__ */ jsx38(Button33, { variant: "primary", disabled: busy, "aria-busy": running || void 0, onClick: onFill, "aria-label": `Fill ${item?.name ?? "this login"}`, children: running ? "Filling\u2026" : "Fill" }) : null,
7973
+ user && item ? /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(UserGlyph, {}), "aria-label": `Copy ${user.label}`, title: `Copy ${user.label}`, disabled: reading, onClick: () => void read(user.label, () => port.reveal(item, user.key)) }) : null,
7974
+ secret && item ? /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(KeyGlyph, {}), "aria-label": "Copy password", title: "Copy password", disabled: reading, onClick: () => void read("Password", () => port.reveal(item, secret.key)) }) : null,
7975
+ otp ? /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(ClockGlyph, {}), "aria-label": "Copy one-time code", title: "Copy one-time code", disabled: reading, onClick: () => void read("One-time code", async () => (await port.authenticator.code(otp)).code) }) : null,
7976
+ onSignIn ? /* @__PURE__ */ jsxs36(DropdownMenu5, { children: [
7977
+ /* @__PURE__ */ jsx38(DropdownMenuTrigger5, { asChild: true, children: /* @__PURE__ */ jsx38(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx38(MoreGlyph, {}), "aria-label": "More", disabled: busy }) }),
7978
+ /* @__PURE__ */ jsxs36(DropdownMenuContent5, { align: "end", children: [
7979
+ /* @__PURE__ */ jsxs36(DropdownMenuItem5, { onSelect: onSignIn, children: [
7980
+ /* @__PURE__ */ jsx38(ShieldGlyph, { className: "size-4" }),
7682
7981
  "Sign me in"
7683
7982
  ] }),
7684
- /* @__PURE__ */ jsxs35(DropdownMenuItem4, { onSelect: () => onOpen(itemId), children: [
7685
- /* @__PURE__ */ jsx37(ListGlyph, { className: "size-4" }),
7983
+ /* @__PURE__ */ jsxs36(DropdownMenuItem5, { onSelect: () => onOpen(itemId), children: [
7984
+ /* @__PURE__ */ jsx38(ListGlyph, { className: "size-4" }),
7686
7985
  "Open item"
7687
7986
  ] })
7688
7987
  ] })
@@ -7691,11 +7990,11 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
7691
7990
  }
7692
7991
 
7693
7992
  // src/Sidebar.tsx
7694
- import { useState as useState39 } from "react";
7993
+ import { useState as useState40 } from "react";
7695
7994
  import { cn as cn15, useLook as useLook2 } from "@ai-matrx/design-system";
7696
- import { Select as Select10 } from "@ai-matrx/design-system/controls";
7995
+ import { Select as Select11 } from "@ai-matrx/design-system/controls";
7697
7996
  import { GlobeIcon as GlobeIcon5 } from "@ai-matrx/design-system/icons";
7698
- import { jsx as jsx38, jsxs as jsxs36 } from "react/jsx-runtime";
7997
+ import { jsx as jsx39, jsxs as jsxs37 } from "react/jsx-runtime";
7699
7998
  var AUTHENTICATOR_LABEL = "Authenticator";
7700
7999
  function vaultChoices(items, organizations, current) {
7701
8000
  const n = (f) => items.filter(f).length;
@@ -7709,7 +8008,7 @@ function vaultChoices(items, organizations, current) {
7709
8008
  ];
7710
8009
  }
7711
8010
  function VaultSelect({ value, choices, onChange }) {
7712
- return /* @__PURE__ */ jsx38(Select10, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
8011
+ return /* @__PURE__ */ jsx39(Select11, { value, onValueChange: onChange, "aria-label": "Vault", options: choices.map((c) => ({ value: c.value, label: c.label, meta: String(c.count) })) });
7713
8012
  }
7714
8013
  var CATEGORY_GLYPHS = { logins: GlobeIcon5, passkeys: ShieldGlyph, api: KeyGlyph, oauth: PlugGlyph, infra: DatabaseGlyph, env: TerminalGlyph, files: FileGlyph, other: NoteGlyph };
7715
8014
  var familyOf = (key, definitions) => definitions.find((d) => d.key === key)?.family ?? "generic";
@@ -7755,7 +8054,7 @@ function viewOptions(views, allCount, deletedCount, hasFavorites, hasRecents, ha
7755
8054
  }
7756
8055
  function Entry({ on, glyph: Icon, label, count: count2, onClick }) {
7757
8056
  const desktop = useLook2() === "desktop";
7758
- return /* @__PURE__ */ jsxs36(
8057
+ return /* @__PURE__ */ jsxs37(
7759
8058
  "button",
7760
8059
  {
7761
8060
  type: "button",
@@ -7763,62 +8062,62 @@ function Entry({ on, glyph: Icon, label, count: count2, onClick }) {
7763
8062
  onClick,
7764
8063
  className: cn15("flex h-8 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm", on ? desktop ? "bg-sidebar-accent text-primary" : "bg-sidebar-accent font-medium text-sidebar-accent-foreground" : "text-sidebar-foreground hover:bg-sidebar-accent"),
7765
8064
  children: [
7766
- /* @__PURE__ */ jsx38(Icon, { className: "size-4 shrink-0" }),
7767
- /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate", children: label }),
7768
- count2 !== void 0 ? /* @__PURE__ */ jsx38("span", { className: "text-xs tabular-nums text-muted-foreground", children: count2 }) : null
8065
+ /* @__PURE__ */ jsx39(Icon, { className: "size-4 shrink-0" }),
8066
+ /* @__PURE__ */ jsx39("span", { className: "min-w-0 flex-1 truncate", children: label }),
8067
+ count2 !== void 0 ? /* @__PURE__ */ jsx39("span", { className: "text-xs tabular-nums text-muted-foreground", children: count2 }) : null
7769
8068
  ]
7770
8069
  }
7771
8070
  );
7772
8071
  }
7773
8072
  function Group({ title, children }) {
7774
- return /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5", children: [
7775
- /* @__PURE__ */ jsx38("div", { className: "px-2.5 pb-1 text-xs font-medium text-muted-foreground", children: title }),
8073
+ return /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-0.5", children: [
8074
+ /* @__PURE__ */ jsx39("div", { className: "px-2.5 pb-1 text-xs font-medium text-muted-foreground", children: title }),
7776
8075
  children
7777
8076
  ] });
7778
8077
  }
7779
8078
  function VaultSidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
7780
- const [tagsOpen, setTagsOpen] = useState39(view.startsWith("tag:"));
7781
- return /* @__PURE__ */ jsxs36("nav", { "aria-label": "Vault", className: "flex h-full min-h-0 flex-col border-r border-sidebar-border bg-sidebar-background text-sidebar-foreground", children: [
7782
- /* @__PURE__ */ jsxs36("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
7783
- /* @__PURE__ */ jsx38(SafeGlyph, { className: "size-5 shrink-0 text-primary" }),
7784
- /* @__PURE__ */ jsx38("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx38(VaultSelect, { value: vault, choices, onChange: onVault }) })
8079
+ const [tagsOpen, setTagsOpen] = useState40(view.startsWith("tag:"));
8080
+ return /* @__PURE__ */ jsxs37("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: [
8081
+ /* @__PURE__ */ jsxs37("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
8082
+ /* @__PURE__ */ jsx39(SafeGlyph, { className: "size-5 shrink-0 text-primary" }),
8083
+ /* @__PURE__ */ jsx39("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsx39(VaultSelect, { value: vault, choices, onChange: onVault }) })
7785
8084
  ] }),
7786
- /* @__PURE__ */ jsxs36("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
7787
- /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5", children: [
7788
- hasPage ? /* @__PURE__ */ jsx38(Entry, { on: view === "page", glyph: GlobeIcon5, label: "This page", onClick: () => onView("page") }) : null,
7789
- /* @__PURE__ */ jsx38(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
7790
- hasFavorites ? /* @__PURE__ */ jsx38(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
7791
- hasRecents ? /* @__PURE__ */ jsx38(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
7792
- /* @__PURE__ */ jsx38(Entry, { on: view === "authenticator", glyph: LockGlyph, label: AUTHENTICATOR_LABEL, count: views.authenticator, onClick: () => onView("authenticator") })
8085
+ /* @__PURE__ */ jsxs37("div", { className: "flex min-h-0 flex-1 flex-col gap-5 overflow-y-auto px-2 pb-3 pt-1", children: [
8086
+ /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-0.5", children: [
8087
+ hasPage ? /* @__PURE__ */ jsx39(Entry, { on: view === "page", glyph: GlobeIcon5, label: "This page", onClick: () => onView("page") }) : null,
8088
+ /* @__PURE__ */ jsx39(Entry, { on: view === "all", glyph: GridGlyph, label: "All items", count: allCount, onClick: () => onView("all") }),
8089
+ hasFavorites ? /* @__PURE__ */ jsx39(Entry, { on: view === "favorites", glyph: StarGlyph, label: "Favorites", count: views.favorites, onClick: () => onView("favorites") }) : null,
8090
+ hasRecents ? /* @__PURE__ */ jsx39(Entry, { on: view === "recent", glyph: ClockGlyph, label: "Recently opened", count: views.recent, onClick: () => onView("recent") }) : null,
8091
+ /* @__PURE__ */ jsx39(Entry, { on: view === "authenticator", glyph: LockGlyph, label: AUTHENTICATOR_LABEL, count: views.authenticator, onClick: () => onView("authenticator") })
7793
8092
  ] }),
7794
- views.categories.length > 0 ? /* @__PURE__ */ jsx38(Group, { title: "Categories", children: views.categories.map((e) => /* @__PURE__ */ jsx38(Entry, { on: view === e.view, glyph: e.glyph, label: e.label, count: e.count, onClick: () => onView(e.view) }, e.view)) }) : null,
7795
- views.tags.length > 0 ? /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5", children: [
7796
- /* @__PURE__ */ jsxs36("button", { type: "button", "aria-expanded": tagsOpen, onClick: () => setTagsOpen((o) => !o), className: "flex h-7 items-center gap-1 rounded-md px-2.5 text-left text-xs font-medium text-muted-foreground hover:text-foreground", children: [
7797
- tagsOpen ? /* @__PURE__ */ jsx38(ChevronDownGlyph, { className: "size-3.5" }) : /* @__PURE__ */ jsx38(ChevronRightGlyph, { className: "size-3.5" }),
8093
+ views.categories.length > 0 ? /* @__PURE__ */ jsx39(Group, { title: "Categories", children: views.categories.map((e) => /* @__PURE__ */ jsx39(Entry, { on: view === e.view, glyph: e.glyph, label: e.label, count: e.count, onClick: () => onView(e.view) }, e.view)) }) : null,
8094
+ views.tags.length > 0 ? /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-0.5", children: [
8095
+ /* @__PURE__ */ jsxs37("button", { type: "button", "aria-expanded": tagsOpen, onClick: () => setTagsOpen((o) => !o), className: "flex h-7 items-center gap-1 rounded-md px-2.5 text-left text-xs font-medium text-muted-foreground hover:text-foreground", children: [
8096
+ tagsOpen ? /* @__PURE__ */ jsx39(ChevronDownGlyph, { className: "size-3.5" }) : /* @__PURE__ */ jsx39(ChevronRightGlyph, { className: "size-3.5" }),
7798
8097
  "Tags",
7799
- /* @__PURE__ */ jsx38("span", { className: "ml-auto tabular-nums", children: views.tags.length })
8098
+ /* @__PURE__ */ jsx39("span", { className: "ml-auto tabular-nums", children: views.tags.length })
7800
8099
  ] }),
7801
- tagsOpen ? views.tags.map((e) => /* @__PURE__ */ jsx38(Entry, { on: view === e.view, glyph: e.glyph, label: e.label, count: e.count, onClick: () => onView(e.view) }, e.view)) : null
8100
+ tagsOpen ? views.tags.map((e) => /* @__PURE__ */ jsx39(Entry, { on: view === e.view, glyph: e.glyph, label: e.label, count: e.count, onClick: () => onView(e.view) }, e.view)) : null
7802
8101
  ] }) : null
7803
8102
  ] }),
7804
- /* @__PURE__ */ jsxs36("div", { className: "flex flex-col gap-0.5 border-t border-sidebar-border p-2", children: [
7805
- /* @__PURE__ */ jsx38(Entry, { on: view === "trash", glyph: TrashGlyph, label: "Trash", count: deletedCount, onClick: () => onView("trash") }),
7806
- /* @__PURE__ */ jsx38(Entry, { on: false, glyph: ImportGlyph, label: "Import", onClick: () => onPanel("import") }),
7807
- /* @__PURE__ */ jsx38(Entry, { on: false, glyph: ExportGlyph, label: "Export", onClick: () => onPanel("export") }),
7808
- /* @__PURE__ */ jsx38(Entry, { on: false, glyph: SafeGlyph, label: "Backup", onClick: () => onPanel("backup") }),
7809
- /* @__PURE__ */ jsx38(Entry, { on: false, glyph: ShieldGlyph, label: "Browsers that fill", onClick: () => onPanel("devices") }),
7810
- hasNativeImport ? /* @__PURE__ */ jsx38(Entry, { on: false, glyph: ImportGlyph, label: "Import passkeys", onClick: () => onPanel("import-passkeys") }) : null,
7811
- nativeProvider && nativeProvider.status !== "unavailable" ? /* @__PURE__ */ jsxs36("button", { type: "button", onClick: nativeProvider.openSetup, className: "flex h-8 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm hover:bg-sidebar-accent", children: [
7812
- /* @__PURE__ */ jsx38(ShieldGlyph, { className: "size-4 shrink-0" }),
7813
- /* @__PURE__ */ jsx38("span", { className: "min-w-0 flex-1 truncate", children: "System AutoFill" }),
7814
- /* @__PURE__ */ jsx38("span", { className: cn15("text-xs", nativeProvider.status === "ready" ? "text-success" : "text-warning"), children: nativeProvider.status === "ready" ? "On" : "Set up" })
8103
+ /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-0.5 border-t border-sidebar-border p-2", children: [
8104
+ /* @__PURE__ */ jsx39(Entry, { on: view === "trash", glyph: TrashGlyph, label: "Trash", count: deletedCount, onClick: () => onView("trash") }),
8105
+ /* @__PURE__ */ jsx39(Entry, { on: false, glyph: ImportGlyph, label: "Import", onClick: () => onPanel("import") }),
8106
+ /* @__PURE__ */ jsx39(Entry, { on: false, glyph: ExportGlyph, label: "Export", onClick: () => onPanel("export") }),
8107
+ /* @__PURE__ */ jsx39(Entry, { on: false, glyph: SafeGlyph, label: "Backup", onClick: () => onPanel("backup") }),
8108
+ /* @__PURE__ */ jsx39(Entry, { on: false, glyph: ShieldGlyph, label: "Browsers that fill", onClick: () => onPanel("devices") }),
8109
+ hasNativeImport ? /* @__PURE__ */ jsx39(Entry, { on: false, glyph: ImportGlyph, label: "Import passkeys", onClick: () => onPanel("import-passkeys") }) : null,
8110
+ nativeProvider && nativeProvider.status !== "unavailable" ? /* @__PURE__ */ jsxs37("button", { type: "button", onClick: nativeProvider.openSetup, className: "flex h-8 w-full items-center gap-2.5 rounded-lg px-2.5 text-left text-sm hover:bg-sidebar-accent", children: [
8111
+ /* @__PURE__ */ jsx39(ShieldGlyph, { className: "size-4 shrink-0" }),
8112
+ /* @__PURE__ */ jsx39("span", { className: "min-w-0 flex-1 truncate", children: "System AutoFill" }),
8113
+ /* @__PURE__ */ jsx39("span", { className: cn15("text-xs", nativeProvider.status === "ready" ? "text-success" : "text-warning"), children: nativeProvider.status === "ready" ? "On" : "Set up" })
7815
8114
  ] }) : null
7816
8115
  ] })
7817
8116
  ] });
7818
8117
  }
7819
8118
 
7820
8119
  // src/VaultApp.tsx
7821
- import { jsx as jsx39, jsxs as jsxs37 } from "react/jsx-runtime";
8120
+ import { jsx as jsx40, jsxs as jsxs38 } from "react/jsx-runtime";
7822
8121
  var FULL_AT = 1120;
7823
8122
  var SPLIT_AT = 640;
7824
8123
  var NO_HOST = {};
@@ -7837,7 +8136,7 @@ var generatorLimitsFrom = (knobs) => knobs ? async () => {
7837
8136
  } : void 0;
7838
8137
  function ImportWithLimits(props) {
7839
8138
  const { knobs, ...rest } = props;
7840
- const [state, setState] = useState40(null);
8139
+ const [state, setState] = useState41(null);
7841
8140
  useEffect23(() => {
7842
8141
  if (!knobs) return setState({ error: "Import is not set up for this organization yet." });
7843
8142
  knobs().then(
@@ -7851,18 +8150,18 @@ function ImportWithLimits(props) {
7851
8150
  (e) => setState({ error: e instanceof Error ? e.message : "The import settings could not be read." })
7852
8151
  );
7853
8152
  }, [knobs]);
7854
- if (state && "limits" in state) return /* @__PURE__ */ jsx39(ImportPanel, { ...rest, limits: state.limits });
7855
- return /* @__PURE__ */ jsx39(Panel, { title: "Import", onClose: rest.onClose, children: /* @__PURE__ */ jsx39(Empty, { children: state ? state.error : "Reading this organization\u2019s import settings\u2026" }) });
8153
+ if (state && "limits" in state) return /* @__PURE__ */ jsx40(ImportPanel, { ...rest, limits: state.limits });
8154
+ return /* @__PURE__ */ jsx40(Panel, { title: "Import", onClose: rest.onClose, children: /* @__PURE__ */ jsx40(Empty, { children: state ? state.error : "Reading this organization\u2019s import settings\u2026" }) });
7856
8155
  }
7857
8156
  function VaultApp(props) {
7858
8157
  const lock = props.host?.lock;
7859
8158
  const locked = useLocked(lock);
7860
8159
  const port = useMemo6(() => lock ? guardPort(props.port, () => lock.locked()) : props.port, [props.port, lock]);
7861
- return /* @__PURE__ */ jsx39(LookScope, { look: props.look ?? "web", className: "h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39("div", { className: "relative h-full min-h-0 w-full", children: /* @__PURE__ */ jsx39(NoticeProvider, { notify: props.notify, children: lock && locked ? /* @__PURE__ */ jsx39(LockedScreen, { lock }) : /* @__PURE__ */ jsx39(ClipboardProvider, { clipboard: props.host?.clipboard, children: /* @__PURE__ */ jsx39(RevealSecondsProvider, { seconds: props.host?.revealSeconds, children: /* @__PURE__ */ jsx39(IdentityGate, { identity: props.host?.identity, children: /* @__PURE__ */ jsx39(GeneratorLimitsProvider, { resolve: generatorLimitsFrom(props.host?.knobs), children: /* @__PURE__ */ jsx39(Workspace, { ...props, port }) }) }) }) }) }) }) });
8160
+ return /* @__PURE__ */ jsx40(LookScope, { look: props.look ?? "web", className: "h-full min-h-0 w-full", children: /* @__PURE__ */ jsx40("div", { className: "relative h-full min-h-0 w-full", children: /* @__PURE__ */ jsx40(NoticeProvider, { notify: props.notify, children: lock && locked ? /* @__PURE__ */ jsx40(LockedScreen, { lock }) : /* @__PURE__ */ jsx40(ClipboardProvider, { clipboard: props.host?.clipboard, children: /* @__PURE__ */ jsx40(RevealSecondsProvider, { seconds: props.host?.revealSeconds, children: /* @__PURE__ */ jsx40(IdentityGate, { identity: props.host?.identity, children: /* @__PURE__ */ jsx40(GeneratorLimitsProvider, { resolve: generatorLimitsFrom(props.host?.knobs), children: /* @__PURE__ */ jsx40(Workspace, { ...props, port }) }) }) }) }) }) }) });
7862
8161
  }
7863
8162
  function LockedScreen({ lock }) {
7864
- const [busy, setBusy] = useState40(false);
7865
- const [error, setError] = useState40(null);
8163
+ const [busy, setBusy] = useState41(false);
8164
+ const [error, setError] = useState41(null);
7866
8165
  const unlock = async () => {
7867
8166
  setBusy(true);
7868
8167
  setError(null);
@@ -7874,29 +8173,29 @@ function LockedScreen({ lock }) {
7874
8173
  setBusy(false);
7875
8174
  }
7876
8175
  };
7877
- return /* @__PURE__ */ jsxs37("div", { role: "region", "aria-label": "Vault locked", className: "flex h-full min-h-0 flex-col items-center justify-center gap-3 p-6 text-center", children: [
7878
- /* @__PURE__ */ jsx39(LockGlyph, { className: "size-8 text-muted-foreground" }),
7879
- /* @__PURE__ */ jsx39("div", { className: "text-base font-medium text-foreground", children: "Vault locked" }),
7880
- /* @__PURE__ */ jsx39(Button33, { variant: "primary", disabled: busy, onClick: () => void unlock(), children: lock.unlockLabel ?? "Unlock" }),
7881
- error ? /* @__PURE__ */ jsx39("div", { role: "alert", className: "max-w-sm text-sm text-destructive", children: error }) : null
8176
+ return /* @__PURE__ */ jsxs38("div", { role: "region", "aria-label": "Vault locked", className: "flex h-full min-h-0 flex-col items-center justify-center gap-3 p-6 text-center", children: [
8177
+ /* @__PURE__ */ jsx40(LockGlyph, { className: "size-8 text-muted-foreground" }),
8178
+ /* @__PURE__ */ jsx40("div", { className: "text-base font-medium text-foreground", children: "Vault locked" }),
8179
+ /* @__PURE__ */ jsx40(Button34, { variant: "primary", disabled: busy, onClick: () => void unlock(), children: lock.unlockLabel ?? "Unlock" }),
8180
+ error ? /* @__PURE__ */ jsx40("div", { role: "alert", className: "max-w-sm text-sm text-destructive", children: error }) : null
7882
8181
  ] });
7883
8182
  }
7884
- function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocationChange }) {
8183
+ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocationChange, onInventory }) {
7885
8184
  const rootRef = useRef19(null);
7886
8185
  const width = useElementWidth(rootRef);
7887
8186
  const mode = layout !== "auto" ? layout : width >= FULL_AT ? "full" : width >= SPLIT_AT ? "split" : "stack";
7888
8187
  const notify = useNotify();
7889
- const [snap, setSnap] = useState40(null);
7890
- const [items, setItems] = useState40([]);
7891
- const [deleted, setDeleted] = useState40([]);
7892
- const [favorites, setFavorites] = useState40(null);
7893
- const [recents, setRecents] = useState40(null);
7894
- const [error, setError] = useState40(null);
7895
- const [inner, setInner] = useState40(DEFAULT_LOCATION);
8188
+ const [snap, setSnap] = useState41(null);
8189
+ const [items, setItems] = useState41([]);
8190
+ const [deleted, setDeleted] = useState41([]);
8191
+ const [favorites, setFavorites] = useState41(null);
8192
+ const [recents, setRecents] = useState41(null);
8193
+ const [error, setError] = useState41(null);
8194
+ const [inner, setInner] = useState41(DEFAULT_LOCATION);
7896
8195
  const loc = location ?? inner;
7897
8196
  const dirty = useRef19(false);
7898
- const [notice, setNotice] = useState40(null);
7899
- const [firstCode, setFirstCode] = useState40(null);
8197
+ const [notice, setNotice] = useState41(null);
8198
+ const [firstCode, setFirstCode] = useState41(null);
7900
8199
  const move = useCallback5(
7901
8200
  (next, how) => {
7902
8201
  if (!location) setInner(next);
@@ -7916,7 +8215,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
7916
8215
  move(next, how);
7917
8216
  };
7918
8217
  if (leaving && dirty.current) {
7919
- void confirm13({ title: "Discard your changes?", description: "What you changed in this item is not saved.", confirmLabel: "Discard", cancelLabel: "Keep editing", variant: "destructive" }).then((ok) => ok && proceed());
8218
+ void confirm14({ title: "Discard your changes?", description: "What you changed in this item is not saved.", confirmLabel: "Discard", cancelLabel: "Keep editing", variant: "destructive" }).then((ok) => ok && proceed());
7920
8219
  return;
7921
8220
  }
7922
8221
  proceed();
@@ -7949,7 +8248,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
7949
8248
  }, []);
7950
8249
  const knobsRef = useRef19(host.knobs);
7951
8250
  knobsRef.current = host.knobs;
7952
- const [signedOut, setSignedOut] = useState40(false);
8251
+ const [signedOut, setSignedOut] = useState41(false);
7953
8252
  const load = useCallback5(() => {
7954
8253
  setError(null);
7955
8254
  port.load().then((s) => {
@@ -7969,6 +8268,11 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
7969
8268
  port.lists.recents?.list().then(setRecents, () => void 0);
7970
8269
  }, [port]);
7971
8270
  useEffect23(load, [load]);
8271
+ const inventoryRef = useRef19(onInventory);
8272
+ inventoryRef.current = onInventory;
8273
+ useEffect23(() => {
8274
+ if (snap) inventoryRef.current?.({ items, definitions: snap.definitions });
8275
+ }, [snap, items]);
7972
8276
  useEffect23(() => {
7973
8277
  if (!loc.itemId || !port.lists.recents) return;
7974
8278
  const id = loc.itemId;
@@ -7988,7 +8292,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
7988
8292
  return inView(i, loc.view);
7989
8293
  });
7990
8294
  if (loc.view === "recent" && recents) return [...filtered].sort((a, b) => recents.indexOf(a.id) - recents.indexOf(b.id));
7991
- return sortItems(filtered, loc.sort);
8295
+ return sortItems(filtered, loc.sort, recents);
7992
8296
  }, [inThisVault, loc.view, loc.q, loc.sort, favorites, recents, definitions]);
7993
8297
  const choices = useMemo6(() => vaultChoices(items, orgs, loc.vault), [items, orgs, loc.vault]);
7994
8298
  const matchingIds = useMemo6(() => host.page ? new Set(host.page.matchingItemIds) : void 0, [host.page]);
@@ -8015,35 +8319,35 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8015
8319
  });
8016
8320
  };
8017
8321
  if (error) {
8018
- return /* @__PURE__ */ jsxs37("div", { ref: rootRef, role: "alert", className: "flex h-full flex-col items-center justify-center gap-3 bg-background p-6 text-center text-sm", children: [
8019
- /* @__PURE__ */ jsx39(SafeGlyph, { className: "size-8 text-muted-foreground" }),
8020
- /* @__PURE__ */ jsx39("div", { className: "font-medium", children: "The vault couldn\u2019t open" }),
8021
- /* @__PURE__ */ jsx39("div", { className: "max-w-xs text-muted-foreground", children: signedOut ? "You\u2019ve been signed out." : plainLoadError(error) }),
8022
- /* @__PURE__ */ jsxs37("div", { className: "flex gap-2", children: [
8023
- signedOut && host.signIn ? /* @__PURE__ */ jsx39(Button33, { variant: "primary", onClick: host.signIn, children: "Sign in" }) : null,
8024
- /* @__PURE__ */ jsx39(Button33, { variant: signedOut && host.signIn ? "outline" : "primary", onClick: load, children: "Try again" })
8322
+ return /* @__PURE__ */ jsxs38("div", { ref: rootRef, role: "alert", className: "flex h-full flex-col items-center justify-center gap-3 bg-background p-6 text-center text-sm", children: [
8323
+ /* @__PURE__ */ jsx40(SafeGlyph, { className: "size-8 text-muted-foreground" }),
8324
+ /* @__PURE__ */ jsx40("div", { className: "font-medium", children: "The vault couldn\u2019t open" }),
8325
+ /* @__PURE__ */ jsx40("div", { className: "max-w-xs text-muted-foreground", children: signedOut ? "You\u2019ve been signed out." : plainLoadError(error) }),
8326
+ /* @__PURE__ */ jsxs38("div", { className: "flex gap-2", children: [
8327
+ signedOut && host.signIn ? /* @__PURE__ */ jsx40(Button34, { variant: "primary", onClick: host.signIn, children: "Sign in" }) : null,
8328
+ /* @__PURE__ */ jsx40(Button34, { variant: signedOut && host.signIn ? "outline" : "primary", onClick: load, children: "Try again" })
8025
8329
  ] })
8026
8330
  ] });
8027
8331
  }
8028
8332
  if (!snap) {
8029
- return /* @__PURE__ */ jsx39("div", { ref: rootRef, className: "flex h-full bg-background", "aria-busy": "true", "aria-label": "Opening the vault", children: /* @__PURE__ */ jsx39("div", { className: "flex w-full max-w-sm flex-col gap-1 p-3", children: [0, 1, 2, 3, 4, 5, 6].map((n) => /* @__PURE__ */ jsxs37("div", { className: "flex h-12 items-center gap-3 px-2", children: [
8030
- /* @__PURE__ */ jsx39("div", { className: "size-8 animate-pulse rounded-lg bg-muted" }),
8031
- /* @__PURE__ */ jsxs37("div", { className: "flex flex-1 flex-col gap-1.5", children: [
8032
- /* @__PURE__ */ jsx39("div", { className: "h-3 w-2/3 animate-pulse rounded bg-muted" }),
8033
- /* @__PURE__ */ jsx39("div", { className: "h-2.5 w-1/3 animate-pulse rounded bg-muted" })
8333
+ return /* @__PURE__ */ jsx40("div", { ref: rootRef, className: "flex h-full bg-background", "aria-busy": "true", "aria-label": "Opening the vault", children: /* @__PURE__ */ jsx40("div", { className: "flex w-full max-w-sm flex-col gap-1 p-3", children: [0, 1, 2, 3, 4, 5, 6].map((n) => /* @__PURE__ */ jsxs38("div", { className: "flex h-12 items-center gap-3 px-2", children: [
8334
+ /* @__PURE__ */ jsx40("div", { className: "size-8 animate-pulse rounded-lg bg-muted" }),
8335
+ /* @__PURE__ */ jsxs38("div", { className: "flex flex-1 flex-col gap-1.5", children: [
8336
+ /* @__PURE__ */ jsx40("div", { className: "h-3 w-2/3 animate-pulse rounded bg-muted" }),
8337
+ /* @__PURE__ */ jsx40("div", { className: "h-2.5 w-1/3 animate-pulse rounded bg-muted" })
8034
8338
  ] })
8035
8339
  ] }, n)) }) });
8036
8340
  }
8037
8341
  const hasFavorites = port.lists.favorites !== void 0;
8038
8342
  const title = loc.vault === "all" && loc.view === "all" ? "All items" : viewLabel(loc.view, views);
8039
- const compactHeader = mode === "full" ? void 0 : /* @__PURE__ */ jsxs37("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto_auto] gap-2", children: [
8040
- /* @__PURE__ */ jsx39(VaultSelect, { value: loc.vault, choices, onChange: (vault) => go({ vault, itemId: null, panel: null }) }),
8041
- /* @__PURE__ */ jsx39(Select11, { value: loc.view, onValueChange: (view) => go({ view, itemId: null, panel: null }), options: viewOptions(views, inThisVault.length, deleted.length, hasFavorites, port.lists.recents !== void 0, host.page !== void 0), "aria-label": "Show" }),
8042
- /* @__PURE__ */ jsx39(
8043
- Button33,
8343
+ const compactHeader = mode === "full" ? void 0 : /* @__PURE__ */ jsxs38("div", { className: "grid grid-cols-[minmax(0,1fr)_minmax(0,1fr)_auto_auto] gap-2", children: [
8344
+ /* @__PURE__ */ jsx40(VaultSelect, { value: loc.vault, choices, onChange: (vault) => go({ vault, itemId: null, panel: null }) }),
8345
+ /* @__PURE__ */ jsx40(Select12, { value: loc.view, onValueChange: (view) => go({ view, itemId: null, panel: null }), options: viewOptions(views, inThisVault.length, deleted.length, hasFavorites, port.lists.recents !== void 0, host.page !== void 0), "aria-label": "Show" }),
8346
+ /* @__PURE__ */ jsx40(
8347
+ Button34,
8044
8348
  {
8045
8349
  variant: loc.view === "authenticator" ? "outline" : "quiet",
8046
- icon: /* @__PURE__ */ jsx39(LockGlyph, {}),
8350
+ icon: /* @__PURE__ */ jsx40(LockGlyph, {}),
8047
8351
  "aria-label": AUTHENTICATOR_LABEL,
8048
8352
  "aria-pressed": loc.view === "authenticator",
8049
8353
  title: AUTHENTICATOR_LABEL,
@@ -8051,46 +8355,50 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8051
8355
  children: mode === "split" ? AUTHENTICATOR_LABEL : null
8052
8356
  }
8053
8357
  ),
8054
- /* @__PURE__ */ jsxs37(DropdownMenu6, { children: [
8055
- /* @__PURE__ */ jsx39(DropdownMenuTrigger6, { asChild: true, children: /* @__PURE__ */ jsx39(Button33, { variant: "quiet", icon: /* @__PURE__ */ jsx39(MoreGlyph, {}), "aria-label": "Vault actions" }) }),
8056
- /* @__PURE__ */ jsxs37(DropdownMenuContent6, { align: "end", children: [
8057
- /* @__PURE__ */ jsxs37(DropdownMenuItem5, { onSelect: () => go({ panel: "import" }), children: [
8058
- /* @__PURE__ */ jsx39(ImportGlyph, { className: "size-4" }),
8358
+ /* @__PURE__ */ jsxs38(DropdownMenu6, { children: [
8359
+ /* @__PURE__ */ jsx40(DropdownMenuTrigger6, { asChild: true, children: /* @__PURE__ */ jsx40(Button34, { variant: "quiet", icon: /* @__PURE__ */ jsx40(MoreGlyph, {}), "aria-label": "Vault actions" }) }),
8360
+ /* @__PURE__ */ jsxs38(DropdownMenuContent6, { align: "end", children: [
8361
+ /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: () => go({ panel: "import" }), children: [
8362
+ /* @__PURE__ */ jsx40(ImportGlyph, { className: "size-4" }),
8059
8363
  "Import"
8060
8364
  ] }),
8061
- /* @__PURE__ */ jsxs37(DropdownMenuItem5, { onSelect: () => go({ panel: "export" }), children: [
8062
- /* @__PURE__ */ jsx39(ExportGlyph, { className: "size-4" }),
8365
+ /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: () => go({ panel: "export" }), children: [
8366
+ /* @__PURE__ */ jsx40(ExportGlyph, { className: "size-4" }),
8063
8367
  "Export"
8064
8368
  ] }),
8065
- /* @__PURE__ */ jsxs37(DropdownMenuItem5, { onSelect: () => go({ panel: "backup" }), children: [
8066
- /* @__PURE__ */ jsx39(SafeGlyph, { className: "size-4" }),
8369
+ /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: () => go({ panel: "backup" }), children: [
8370
+ /* @__PURE__ */ jsx40(SafeGlyph, { className: "size-4" }),
8067
8371
  "Backup"
8068
8372
  ] }),
8069
- /* @__PURE__ */ jsxs37(DropdownMenuItem5, { onSelect: () => go({ panel: "devices" }), children: [
8070
- /* @__PURE__ */ jsx39(ShieldGlyph, { className: "size-4" }),
8373
+ /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: () => go({ panel: "devices" }), children: [
8374
+ /* @__PURE__ */ jsx40(ShieldGlyph, { className: "size-4" }),
8071
8375
  "Browsers that fill"
8072
8376
  ] }),
8073
- host.nativeImport ? /* @__PURE__ */ jsxs37(DropdownMenuItem5, { onSelect: () => go({ panel: "import-passkeys" }), children: [
8074
- /* @__PURE__ */ jsx39(ImportGlyph, { className: "size-4" }),
8377
+ host.nativeImport ? /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: () => go({ panel: "import-passkeys" }), children: [
8378
+ /* @__PURE__ */ jsx40(ImportGlyph, { className: "size-4" }),
8075
8379
  "Import passkeys"
8076
8380
  ] }) : null,
8077
- host.nativeProvider && host.nativeProvider.status !== "unavailable" ? /* @__PURE__ */ jsxs37(DropdownMenuItem5, { onSelect: host.nativeProvider.openSetup, children: [
8078
- /* @__PURE__ */ jsx39(ShieldGlyph, { className: "size-4" }),
8381
+ host.nativeProvider && host.nativeProvider.status !== "unavailable" ? /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: host.nativeProvider.openSetup, children: [
8382
+ /* @__PURE__ */ jsx40(ShieldGlyph, { className: "size-4" }),
8079
8383
  "System AutoFill"
8080
8384
  ] }) : null,
8081
- host.lock?.lock ? /* @__PURE__ */ jsxs37(DropdownMenuItem5, { onSelect: () => void host.lock?.lock?.(), children: [
8082
- /* @__PURE__ */ jsx39(LockGlyph, { className: "size-4" }),
8385
+ host.lock?.lock ? /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: () => void host.lock?.lock?.(), children: [
8386
+ /* @__PURE__ */ jsx40(LockGlyph, { className: "size-4" }),
8083
8387
  "Lock"
8388
+ ] }) : null,
8389
+ host.openWebVault ? /* @__PURE__ */ jsxs38(DropdownMenuItem6, { onSelect: host.openWebVault, children: [
8390
+ /* @__PURE__ */ jsx40(ExternalGlyph, { className: "size-4" }),
8391
+ "Open on the web"
8084
8392
  ] }) : null
8085
8393
  ] })
8086
8394
  ] })
8087
8395
  ] });
8088
- const viewHeader = /* @__PURE__ */ jsxs37("div", { className: "flex flex-col gap-2", children: [
8396
+ const viewHeader = /* @__PURE__ */ jsxs38("div", { className: "flex flex-col gap-2", children: [
8089
8397
  compactHeader,
8090
- /* @__PURE__ */ jsx39(SearchField4, { value: loc.q, onChange: (e) => go({ q: e.target.value }, "replace"), placeholder: `Search ${viewLabel(loc.view, views)}`, "aria-label": `Search ${viewLabel(loc.view, views)}` })
8398
+ /* @__PURE__ */ jsx40(SearchField4, { value: loc.q, onChange: (e) => go({ q: e.target.value }, "replace"), placeholder: `Search ${viewLabel(loc.view, views)}`, "aria-label": `Search ${viewLabel(loc.view, views)}` })
8091
8399
  ] });
8092
8400
  const viewProps = { port, host, items: inThisVault, deleted, definitions, query: loc.q, onOpen: (id) => go({ view: "all", itemId: id, mode: "view", panel: null }), onChanged: load, header: viewHeader };
8093
- const pageView = loc.view === "page" && host.page && !loc.q ? /* @__PURE__ */ jsx39(
8401
+ const pageView = loc.view === "page" && host.page && !loc.q ? /* @__PURE__ */ jsx40(
8094
8402
  PageView,
8095
8403
  {
8096
8404
  port,
@@ -8108,8 +8416,8 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8108
8416
  ...compactHeader ? { header: compactHeader } : {}
8109
8417
  }
8110
8418
  ) : null;
8111
- const specialView = pageView ?? (loc.view === "authenticator" ? /* @__PURE__ */ jsx39(AuthenticatorView, { ...viewProps }) : loc.view === "trash" ? /* @__PURE__ */ jsx39(TrashView, { ...viewProps }) : null);
8112
- const list = specialView ?? /* @__PURE__ */ jsx39(
8419
+ const specialView = pageView ?? (loc.view === "authenticator" ? /* @__PURE__ */ jsx40(AuthenticatorView, { ...viewProps }) : loc.view === "trash" ? /* @__PURE__ */ jsx40(TrashView, { ...viewProps }) : null);
8420
+ const list = specialView ?? /* @__PURE__ */ jsx40(
8113
8421
  ItemList,
8114
8422
  {
8115
8423
  title,
@@ -8123,6 +8431,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8123
8431
  onQuery: (q) => go({ q }, "replace"),
8124
8432
  sort: loc.sort,
8125
8433
  onSort: (sort) => go({ sort }, "replace"),
8434
+ canSortViewed: port.lists.recents !== void 0,
8126
8435
  onNew: () => go({ itemId: null, mode: "new", kind: null, panel: null }),
8127
8436
  ...matchingIds ? { matchingIds } : {},
8128
8437
  ...compactHeader ? { header: compactHeader } : {}
@@ -8136,9 +8445,9 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8136
8445
  const onPanel = (panel2) => go({ panel: panel2 }, "push");
8137
8446
  let detail;
8138
8447
  if (loc.mode === "new" && !kindDefinition) {
8139
- detail = /* @__PURE__ */ jsx39(NewItemFlow, { definitions, url: loc.url, onUrl: (url) => go({ url }, "replace"), onChoose: (kind, _name, url) => go({ kind, url }, "push"), onCancel: () => go({ mode: "view", kind: null, url: "", itemId: null }) });
8448
+ detail = /* @__PURE__ */ jsx40(NewItemFlow, { definitions, url: loc.url, onUrl: (url) => go({ url }, "replace"), onChoose: (kind, _name, url) => go({ kind, url }, "push"), onCancel: () => go({ mode: "view", kind: null, url: "", itemId: null }) });
8140
8449
  } else if (loc.mode === "new" && kindDefinition) {
8141
- detail = /* @__PURE__ */ jsx39(
8450
+ detail = /* @__PURE__ */ jsx40(
8142
8451
  ItemPane,
8143
8452
  {
8144
8453
  port,
@@ -8170,7 +8479,7 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8170
8479
  `new-${kindDefinition.key}`
8171
8480
  );
8172
8481
  } else if (selected) {
8173
- detail = /* @__PURE__ */ jsx39(
8482
+ detail = /* @__PURE__ */ jsx40(
8174
8483
  ItemPane,
8175
8484
  {
8176
8485
  port,
@@ -8214,23 +8523,23 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8214
8523
  selected.id
8215
8524
  );
8216
8525
  } else if (loc.itemId) {
8217
- detail = /* @__PURE__ */ jsx39(Blank, { children: "This item is not in your vault, or you cannot see it." });
8526
+ detail = /* @__PURE__ */ jsx40(Blank, { children: "This item is not in your vault, or you cannot see it." });
8218
8527
  } else {
8219
- detail = /* @__PURE__ */ jsx39(Blank, { children: visible.length === 0 ? "" : "Select an item" });
8528
+ detail = /* @__PURE__ */ jsx40(Blank, { children: visible.length === 0 ? "" : "Select an item" });
8220
8529
  }
8221
8530
  const [panelName, panelArg] = (loc.panel ?? "").split(/:(.*)/s);
8222
8531
  const closePanel = () => go({ panel: null }, "push");
8223
8532
  const vaultPanelProps = { port, host, items, definitions, organizations: orgs, onClose: closePanel, onChanged: load };
8224
8533
  let panel = null;
8225
- if (panelName === "import") panel = /* @__PURE__ */ jsx39(ImportWithLimits, { ...vaultPanelProps, knobs: host.knobs });
8226
- else if (panelName === "devices") panel = /* @__PURE__ */ jsx39(DevicesPanel, { ...vaultPanelProps });
8227
- else if (panelName === "approve" && panelArg) panel = /* @__PURE__ */ jsx39(ApprovePanel, { ...vaultPanelProps, ...approvalFromParams(panelArg, new URLSearchParams(globalThis.location?.search ?? "")) });
8228
- else if (panelName === "import-passkeys" && host.nativeImport) panel = /* @__PURE__ */ jsx39(NativeImportPanel, { ...vaultPanelProps, bridge: host.nativeImport, readLimits: port.native.limits, activeOrganizationId: orgs[0]?.id ?? null });
8229
- else if (panelName === "export") panel = /* @__PURE__ */ jsx39(ExportPanel, { ...vaultPanelProps });
8230
- else if (panelName === "backup") panel = /* @__PURE__ */ jsx39(BackupPanel, { ...vaultPanelProps });
8534
+ if (panelName === "import") panel = /* @__PURE__ */ jsx40(ImportWithLimits, { ...vaultPanelProps, knobs: host.knobs });
8535
+ else if (panelName === "devices") panel = /* @__PURE__ */ jsx40(DevicesPanel, { ...vaultPanelProps });
8536
+ else if (panelName === "approve" && panelArg) panel = /* @__PURE__ */ jsx40(ApprovePanel, { ...vaultPanelProps, ...approvalFromParams(panelArg, new URLSearchParams(globalThis.location?.search ?? "")) });
8537
+ else if (panelName === "import-passkeys" && host.nativeImport) panel = /* @__PURE__ */ jsx40(NativeImportPanel, { ...vaultPanelProps, bridge: host.nativeImport, readLimits: port.native.limits, activeOrganizationId: orgs[0]?.id ?? null });
8538
+ else if (panelName === "export") panel = /* @__PURE__ */ jsx40(ExportPanel, { ...vaultPanelProps });
8539
+ else if (panelName === "backup") panel = /* @__PURE__ */ jsx40(BackupPanel, { ...vaultPanelProps });
8231
8540
  else if (panelName && selected && ITEM_PANELS[panelName]) {
8232
8541
  const P = ITEM_PANELS[panelName];
8233
- panel = /* @__PURE__ */ jsx39(
8542
+ panel = /* @__PURE__ */ jsx40(
8234
8543
  P,
8235
8544
  {
8236
8545
  item: selected,
@@ -8253,17 +8562,17 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8253
8562
  }
8254
8563
  const grid = mode === "full" ? "grid-cols-[15rem_21rem_minmax(0,1fr)]" : mode === "split" ? "grid-cols-[19rem_minmax(0,1fr)]" : "grid-cols-1";
8255
8564
  const shown = panesShown(mode, specialView !== null, showingDetail);
8256
- return /* @__PURE__ */ jsxs37("div", { ref: rootRef, className: "flex h-full min-h-0 w-full flex-col bg-background text-foreground", children: [
8257
- snap.unavailable.length > 0 ? /* @__PURE__ */ jsxs37("div", { role: "status", className: "flex items-center gap-3 border-b border-border bg-muted px-4 py-2 text-sm", children: [
8258
- /* @__PURE__ */ jsxs37("span", { className: "min-w-0 flex-1 truncate text-warning", children: [
8565
+ return /* @__PURE__ */ jsxs38("div", { ref: rootRef, className: "flex h-full min-h-0 w-full flex-col bg-background text-foreground", children: [
8566
+ snap.unavailable.length > 0 ? /* @__PURE__ */ jsxs38("div", { role: "status", className: "flex items-center gap-3 border-b border-border bg-muted px-4 py-2 text-sm", children: [
8567
+ /* @__PURE__ */ jsxs38("span", { className: "min-w-0 flex-1 truncate text-warning", children: [
8259
8568
  "Couldn\u2019t load ",
8260
8569
  snap.unavailable.join(", "),
8261
8570
  ". Showing the rest."
8262
8571
  ] }),
8263
- /* @__PURE__ */ jsx39("button", { type: "button", className: "shrink-0 text-primary hover:underline", onClick: load, children: "Try again" })
8572
+ /* @__PURE__ */ jsx40("button", { type: "button", className: "shrink-0 text-primary hover:underline", onClick: load, children: "Try again" })
8264
8573
  ] }) : null,
8265
- /* @__PURE__ */ jsxs37("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
8266
- mode === "full" ? /* @__PURE__ */ jsx39(
8574
+ /* @__PURE__ */ jsxs38("div", { className: `grid min-h-0 w-full flex-1 ${grid} overflow-hidden`, children: [
8575
+ mode === "full" ? /* @__PURE__ */ jsx40(
8267
8576
  VaultSidebar,
8268
8577
  {
8269
8578
  vault: loc.vault,
@@ -8282,10 +8591,10 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
8282
8591
  hasPage: host.page !== void 0
8283
8592
  }
8284
8593
  ) : null,
8285
- shown.list ? /* @__PURE__ */ jsx39("div", { className: specialView && mode !== "stack" ? "col-span-2 min-h-0" : "min-h-0", children: list }) : null,
8594
+ shown.list ? /* @__PURE__ */ jsx40("div", { className: specialView && mode !== "stack" ? "col-span-2 min-h-0" : "min-h-0", children: list }) : null,
8286
8595
  shown.detail ? detail : null,
8287
8596
  panel,
8288
- firstCode ? /* @__PURE__ */ jsx39(FirstCodePanel, { port, item: firstCode, onClose: () => setFirstCode(null), onDone: () => setFirstCode(null) }) : null
8597
+ firstCode ? /* @__PURE__ */ jsx40(FirstCodePanel, { port, item: firstCode, onClose: () => setFirstCode(null), onDone: () => setFirstCode(null) }) : null
8289
8598
  ] })
8290
8599
  ] });
8291
8600
  }
@@ -8293,8 +8602,8 @@ function plainLoadError(message2) {
8293
8602
  return /load failed|failed to fetch|network|timed? ?out/i.test(message2) ? "The connection dropped. Check you\u2019re online, then try again." : message2;
8294
8603
  }
8295
8604
  function Blank({ children }) {
8296
- return /* @__PURE__ */ jsxs37("div", { className: "flex h-full flex-col items-center justify-center gap-3 bg-background text-sm text-muted-foreground", children: [
8297
- /* @__PURE__ */ jsx39(SafeGlyph, { className: "size-10 text-disabled-foreground" }),
8605
+ return /* @__PURE__ */ jsxs38("div", { className: "flex h-full flex-col items-center justify-center gap-3 bg-background text-sm text-muted-foreground", children: [
8606
+ /* @__PURE__ */ jsx40(SafeGlyph, { className: "size-10 text-disabled-foreground" }),
8298
8607
  children
8299
8608
  ] });
8300
8609
  }
@@ -8664,6 +8973,20 @@ function createListsPort(ctx, door) {
8664
8973
 
8665
8974
  // src/sharing/api.ts
8666
8975
  import * as account6 from "@ai-matrx/api/account";
8976
+
8977
+ // src/secret-field-in.ts
8978
+ function secretFieldIn(s) {
8979
+ const envKey = s.envKey?.trim() || null;
8980
+ return {
8981
+ field_key: fieldKeyOf(s.label),
8982
+ value: s.value,
8983
+ handling: s.handling ?? "revealable",
8984
+ ...envKey ? { env_key: envKey } : {},
8985
+ ...envKey && s.injectIntoSandbox ? { inject_into_sandbox: true } : {}
8986
+ };
8987
+ }
8988
+
8989
+ // src/sharing/api.ts
8667
8990
  function grantOf(w) {
8668
8991
  const org = Boolean(w.organization_id);
8669
8992
  return {
@@ -8763,7 +9086,7 @@ function createSharingPort(ctx, options = {}) {
8763
9086
  non_secret_fields: [...meta.map((f) => ({ key: f.key, label: f.label, value: draft.values[f.key] ?? "" })), ...draft.custom.filter((c) => c.label.trim() !== "").map((c) => ({ key: c.key || fieldKeyOf(c.label), label: c.label, value: c.value }))],
8764
9087
  fields: [
8765
9088
  ...encrypted.map((f) => ({ field_key: f.key, value: draft.values[f.key] ?? "", handling: f.handling })),
8766
- ...draft.secrets.filter((s) => s.label.trim() !== "" && s.value !== "").map((s) => ({ field_key: fieldKeyOf(s.label), value: s.value, handling: "revealable" }))
9089
+ ...draft.secrets.filter((s) => s.label.trim() !== "" && s.value !== "").map(secretFieldIn)
8767
9090
  ]
8768
9091
  }
8769
9092
  });
@@ -9049,14 +9372,14 @@ function createApiVaultPort(api, options = {}) {
9049
9372
  login_urls: draft.loginUrls,
9050
9373
  // A login a person saves with its website is offered on that website (the server's own
9051
9374
  // default is off, which made "Save a login" on a page answer "No saved login" there).
9052
- ...draft.loginUrls.length > 0 ? { browser_fill_enabled: true } : {},
9375
+ ...draft.browser ? { uri_match_mode: draft.browser.uriMatchMode, browser_fill_enabled: draft.browser.browserFillEnabled } : draft.loginUrls.length > 0 ? { browser_fill_enabled: true } : {},
9053
9376
  notes: draft.notes || null,
9054
9377
  principal: organizationId ? { type: "organization", organization_id: organizationId } : { type: "user" },
9055
9378
  initiation: "user",
9056
9379
  non_secret_fields: [...meta.map((f) => ({ key: f.key, label: f.label, value: draft.values[f.key] ?? "" })), ...draft.custom.filter((c) => c.label.trim() !== "").map((c) => ({ key: c.key || fieldKeyOf(c.label), label: c.label, value: c.value }))],
9057
9380
  fields: [
9058
9381
  ...encrypted.map((f) => ({ field_key: f.key, value: draft.values[f.key] ?? "", handling: f.handling })),
9059
- ...draft.secrets.filter((s) => s.label.trim() !== "" && s.value !== "").map((s) => ({ field_key: fieldKeyOf(s.label), value: s.value, handling: "revealable" })),
9382
+ ...draft.secrets.filter((s) => s.label.trim() !== "" && s.value !== "").map(secretFieldIn),
9060
9383
  // Backup codes on a type that does not declare them (a website login): their own encrypted field.
9061
9384
  ...!declared.some((f) => f.key === RECOVERY_CODES_KEY) && (draft.values[RECOVERY_CODES_KEY] ?? "").trim() !== "" ? [{ field_key: RECOVERY_CODES_KEY, value: parseRecoveryCodes(draft.values[RECOVERY_CODES_KEY] ?? "").join("\n"), handling: "revealable", description: "One-time account recovery codes" }] : []
9062
9385
  ]
@@ -9096,7 +9419,7 @@ function createApiVaultPort(api, options = {}) {
9096
9419
  }
9097
9420
  for (const s of draft.secrets) {
9098
9421
  if (s.label.trim() === "" || s.value === "") continue;
9099
- await account9.addField(api, { path: { item_id: item.id }, body: { field_key: fieldKeyOf(s.label), value: s.value, handling: "revealable" } }, opts);
9422
+ await account9.addField(api, { path: { item_id: item.id }, body: secretFieldIn(s) }, opts);
9100
9423
  }
9101
9424
  for (const id of draft.removed) await account9.deleteField(api, { path: { item_id: item.id, field_id: id } }, opts);
9102
9425
  return { item: await refetch(item.id, item.owner), notice: null };
@@ -9121,6 +9444,44 @@ function createVaultKnobs(client, address) {
9121
9444
  return snap.resolved;
9122
9445
  };
9123
9446
  }
9447
+
9448
+ // src/agent-context.ts
9449
+ var hostOf = (url) => {
9450
+ try {
9451
+ return new URL(/^[a-z][a-z0-9+.-]*:\/\//i.test(url) ? url : `https://${url}`).host || null;
9452
+ } catch {
9453
+ return null;
9454
+ }
9455
+ };
9456
+ function providerOf(item, definitions) {
9457
+ return definitions.find((d) => d.key === item.definitionKey)?.providerKey ?? null;
9458
+ }
9459
+ function vaultItemFacts(item, definitions) {
9460
+ const provider = providerOf(item, definitions);
9461
+ const hosts = item.loginUrls.map(hostOf).filter((h) => Boolean(h));
9462
+ const keys = item.fields.map((f) => f.key).filter((k) => !isAuthenticatorStorage(k));
9463
+ return [
9464
+ `Name: ${item.name}`,
9465
+ ...item.definitionLabel ? [`Type: ${item.definitionLabel}`] : [],
9466
+ ...provider ? [`Provider: ${provider}`] : [],
9467
+ ...hosts.length ? [`Sites: ${hosts.join(", ")}`] : [],
9468
+ `Owner: ${item.owner.label}`,
9469
+ `Status: ${item.turnedOff ? "turned off" : "active"}`,
9470
+ ...item.accessMode ? [`Access: ${item.accessMode}`] : [],
9471
+ ...item.tags.length ? [`Tags: ${item.tags.join(", ")}`] : [],
9472
+ ...keys.length ? [`Fields: ${keys.join(", ")}`] : [],
9473
+ ...item.authenticator ? ["Has a one-time password"] : []
9474
+ ];
9475
+ }
9476
+ function vaultInventoryScope(inventory, clicked = null) {
9477
+ const { items, definitions } = inventory;
9478
+ const providers = [...new Set(items.map((i) => providerOf(i, definitions)).filter((p) => Boolean(p)))];
9479
+ const content = clicked ? vaultItemFacts(clicked, definitions) : [`Vault \u2014 ${items.length} ${items.length === 1 ? "item" : "items"}`, ...items.map((i) => `\u2022 ${i.name}${i.definitionLabel ? ` \u2014 ${i.definitionLabel}` : ""}`)];
9480
+ return { content: content.join("\n"), credential_count: items.length, credential_labels: items.map((i) => i.name), credential_providers: providers };
9481
+ }
9482
+ function itemIdAt(target) {
9483
+ return target?.closest("[data-item]")?.getAttribute("data-item") ?? null;
9484
+ }
9124
9485
  export {
9125
9486
  CATEGORIES,
9126
9487
  CONFIRM_RETURN_KEY,
@@ -9139,15 +9500,19 @@ export {
9139
9500
  guardPort,
9140
9501
  inferFromUrl,
9141
9502
  isHiddenItem,
9503
+ itemIdAt,
9142
9504
  locationFromParams,
9143
9505
  locationToParams,
9144
9506
  loginSiteOf,
9145
9507
  matchesQuery,
9146
9508
  needsRecentSignIn,
9147
9509
  parseDefinitions,
9510
+ providerOf,
9148
9511
  siteDomainOf,
9149
9512
  sortItems,
9150
9513
  useConfirmed,
9514
+ vaultInventoryScope,
9515
+ vaultItemFacts,
9151
9516
  wasCancelled
9152
9517
  };
9153
9518
  //# sourceMappingURL=index.js.map