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