@ai-matrx/vault 0.1.4 → 0.1.6
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 +24 -0
- package/README.md +1 -1
- package/dist/index.cjs +338 -240
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +62 -5
- package/dist/index.d.ts +62 -5
- package/dist/index.js +129 -31
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.cjs
CHANGED
|
@@ -138,11 +138,15 @@ __export(src_exports, {
|
|
|
138
138
|
CATEGORIES: () => CATEGORIES,
|
|
139
139
|
DEFAULT_LOCATION: () => DEFAULT_LOCATION,
|
|
140
140
|
GenerateButton: () => GenerateButton,
|
|
141
|
+
LOCKED_MESSAGE: () => LOCKED_MESSAGE,
|
|
141
142
|
VaultApp: () => VaultApp,
|
|
143
|
+
VaultLockedError: () => VaultLockedError,
|
|
142
144
|
categoryOf: () => categoryOf,
|
|
145
|
+
copyValue: () => copyValue,
|
|
143
146
|
createApiVaultPort: () => createApiVaultPort,
|
|
144
147
|
createSupabaseIdentity: () => createSupabaseIdentity,
|
|
145
148
|
createVaultKnobs: () => createVaultKnobs,
|
|
149
|
+
guardPort: () => guardPort,
|
|
146
150
|
inferFromUrl: () => inferFromUrl,
|
|
147
151
|
locationFromParams: () => locationFromParams,
|
|
148
152
|
locationToParams: () => locationToParams,
|
|
@@ -155,7 +159,7 @@ __export(src_exports, {
|
|
|
155
159
|
module.exports = __toCommonJS(src_exports);
|
|
156
160
|
|
|
157
161
|
// src/VaultApp.tsx
|
|
158
|
-
var
|
|
162
|
+
var import_react41 = require("react");
|
|
159
163
|
var import_design_system25 = require("@ai-matrx/design-system");
|
|
160
164
|
var import_controls34 = require("@ai-matrx/design-system/controls");
|
|
161
165
|
var import_confirm_opener13 = require("@ai-matrx/kit/confirm-opener");
|
|
@@ -169,9 +173,28 @@ var Ctx = (0, import_react.createContext)(() => void 0);
|
|
|
169
173
|
function useNotify() {
|
|
170
174
|
return (0, import_react.useContext)(Ctx);
|
|
171
175
|
}
|
|
176
|
+
async function copyValue(text, label, options, deps) {
|
|
177
|
+
const secret = options.secret ?? true;
|
|
178
|
+
if (deps.clipboard) {
|
|
179
|
+
try {
|
|
180
|
+
await deps.clipboard.copy(text, { secret });
|
|
181
|
+
deps.notify(`${label} copied`, "success");
|
|
182
|
+
return true;
|
|
183
|
+
} catch (e) {
|
|
184
|
+
deps.notify(e instanceof Error && e.message ? e.message : `${label} could not be copied`, "error");
|
|
185
|
+
return false;
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
return (0, import_clipboard.copyText)(text, { successMessage: `${label} copied`, failureMessage: `${label} could not be copied`, notify: (m, k) => deps.notify(m, k === "error" ? "error" : "success") });
|
|
189
|
+
}
|
|
190
|
+
var ClipboardCtx = (0, import_react.createContext)(void 0);
|
|
191
|
+
function ClipboardProvider({ clipboard, children }) {
|
|
192
|
+
return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(ClipboardCtx.Provider, { value: clipboard, children });
|
|
193
|
+
}
|
|
172
194
|
function useCopy() {
|
|
173
195
|
const notify = useNotify();
|
|
174
|
-
|
|
196
|
+
const clipboard = (0, import_react.useContext)(ClipboardCtx);
|
|
197
|
+
return (0, import_react.useCallback)((text, label, options = {}) => copyValue(text, label, options, { clipboard, notify }), [notify, clipboard]);
|
|
175
198
|
}
|
|
176
199
|
function NoticeProvider({ notify, children }) {
|
|
177
200
|
const [shown, setShown] = (0, import_react.useState)(null);
|
|
@@ -549,7 +572,15 @@ var import_design_system5 = require("@ai-matrx/design-system");
|
|
|
549
572
|
|
|
550
573
|
// src/hooks.ts
|
|
551
574
|
var import_react3 = require("react");
|
|
552
|
-
|
|
575
|
+
var DEFAULT_REVEAL_MS = 2e4;
|
|
576
|
+
var RevealMs = (0, import_react3.createContext)(DEFAULT_REVEAL_MS);
|
|
577
|
+
function RevealSecondsProvider({ seconds, children }) {
|
|
578
|
+
const ms = seconds !== void 0 && Number.isFinite(seconds) && seconds > 0 ? seconds * 1e3 : DEFAULT_REVEAL_MS;
|
|
579
|
+
return (0, import_react3.createElement)(RevealMs.Provider, { value: ms }, children);
|
|
580
|
+
}
|
|
581
|
+
function useTransientSecret(given) {
|
|
582
|
+
const fromHost = (0, import_react3.useContext)(RevealMs);
|
|
583
|
+
const ms = given ?? fromHost;
|
|
553
584
|
const [value, setValue] = (0, import_react3.useState)(null);
|
|
554
585
|
const timer2 = (0, import_react3.useRef)(null);
|
|
555
586
|
const clear = (0, import_react3.useCallback)(() => {
|
|
@@ -664,7 +695,7 @@ function SecretText({ value, multiline }) {
|
|
|
664
695
|
var quietError = (e, fallback) => wasCancelled(e) ? null : e instanceof Error ? e.message : fallback;
|
|
665
696
|
function SecretRow({ port, item, field, extra }) {
|
|
666
697
|
const confirmed = useConfirmed();
|
|
667
|
-
const
|
|
698
|
+
const copyValue2 = useCopy();
|
|
668
699
|
const secret = useTransientSecret();
|
|
669
700
|
const [plain, setPlain] = (0, import_react5.useState)(null);
|
|
670
701
|
const [busy, setBusy] = (0, import_react5.useState)(false);
|
|
@@ -705,7 +736,7 @@ function SecretRow({ port, item, field, extra }) {
|
|
|
705
736
|
}
|
|
706
737
|
async function copy() {
|
|
707
738
|
const v = await fetchValue();
|
|
708
|
-
if (v !== null) await
|
|
739
|
+
if (v !== null) await copyValue2(v, field.label, { secret: !visible });
|
|
709
740
|
}
|
|
710
741
|
const multiline = field.kind === "multiline";
|
|
711
742
|
const shown = visible ? plain : secret.value;
|
|
@@ -724,7 +755,7 @@ function SecretRow({ port, item, field, extra }) {
|
|
|
724
755
|
);
|
|
725
756
|
}
|
|
726
757
|
function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
727
|
-
const
|
|
758
|
+
const copyValue2 = useCopy();
|
|
728
759
|
const isUrl = /^https?:\/\//i.test(value);
|
|
729
760
|
return /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(
|
|
730
761
|
Row,
|
|
@@ -735,7 +766,7 @@ function PlainRow({ label, value, hint, openUrl, extra, multiline = false }) {
|
|
|
735
766
|
actions: /* @__PURE__ */ (0, import_jsx_runtime5.jsxs)(import_jsx_runtime5.Fragment, { children: [
|
|
736
767
|
extra,
|
|
737
768
|
isUrl && openUrl ? /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(ExternalGlyph, {}), "aria-label": `Open ${value}`, onClick: () => openUrl(value) }) : null,
|
|
738
|
-
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CopyGlyph, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void
|
|
769
|
+
/* @__PURE__ */ (0, import_jsx_runtime5.jsx)(import_controls2.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime5.jsx)(CopyGlyph, {}), "aria-label": `Copy ${typeof label === "string" ? label : "value"}`, onClick: () => void copyValue2(value, typeof label === "string" && label ? label : "Value", { secret: false }) })
|
|
739
770
|
] }),
|
|
740
771
|
children: isUrl && openUrl ? (
|
|
741
772
|
// A real link (right-click, copy link address, open in a new tab); a click goes through the host's opener.
|
|
@@ -1381,7 +1412,7 @@ function HistoryPanel({ item, port, arg, onClose, onChanged }) {
|
|
|
1381
1412
|
function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, onError }) {
|
|
1382
1413
|
const confirmed = useConfirmed();
|
|
1383
1414
|
const secret = useTransientSecret();
|
|
1384
|
-
const
|
|
1415
|
+
const copyValue2 = useCopy();
|
|
1385
1416
|
const [busy, setBusy] = (0, import_react7.useState)(false);
|
|
1386
1417
|
const when = formatDate(entry.recordedAt, true);
|
|
1387
1418
|
async function read() {
|
|
@@ -1404,7 +1435,7 @@ function HistoryRow({ item, port, page, entry, label, onRestored, onConflict, on
|
|
|
1404
1435
|
}
|
|
1405
1436
|
async function copy() {
|
|
1406
1437
|
const v = await read();
|
|
1407
|
-
if (v !== null) await
|
|
1438
|
+
if (v !== null) await copyValue2(v, `Earlier ${label.toLowerCase()}`);
|
|
1408
1439
|
}
|
|
1409
1440
|
async function restore() {
|
|
1410
1441
|
const yes = await (0, import_confirm_opener.confirm)({
|
|
@@ -1589,13 +1620,13 @@ function CountdownRing({ remaining, period, loading = false, className }) {
|
|
|
1589
1620
|
}
|
|
1590
1621
|
function useCopied() {
|
|
1591
1622
|
const [copied, setCopied] = (0, import_react8.useState)(false);
|
|
1592
|
-
const
|
|
1623
|
+
const copyValue2 = useCopy();
|
|
1593
1624
|
const t = (0, import_react8.useRef)(null);
|
|
1594
1625
|
(0, import_react8.useEffect)(() => () => void (t.current && clearTimeout(t.current)), []);
|
|
1595
1626
|
return {
|
|
1596
1627
|
copied,
|
|
1597
1628
|
copy: async (code) => {
|
|
1598
|
-
const ok = await
|
|
1629
|
+
const ok = await copyValue2(code, "One-time code");
|
|
1599
1630
|
if (!ok) return;
|
|
1600
1631
|
setCopied(true);
|
|
1601
1632
|
if (t.current) clearTimeout(t.current);
|
|
@@ -2810,7 +2841,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
|
|
|
2810
2841
|
const [candidate, setCandidate] = (0, import_react15.useState)(null);
|
|
2811
2842
|
const [revealed, setRevealed] = (0, import_react15.useState)(false);
|
|
2812
2843
|
const [note, setNote] = (0, import_react15.useState)(null);
|
|
2813
|
-
const
|
|
2844
|
+
const copyValue2 = useCopy();
|
|
2814
2845
|
const expiry = (0, import_react15.useRef)(null);
|
|
2815
2846
|
const drop = () => {
|
|
2816
2847
|
if (expiry.current) clearTimeout(expiry.current);
|
|
@@ -2870,7 +2901,7 @@ function PasswordGenerator({ limits: source, onUse, useLabel = "Use" }) {
|
|
|
2870
2901
|
const strength = candidate ? strengthOf(candidate.bits) : null;
|
|
2871
2902
|
const copy = async () => {
|
|
2872
2903
|
if (!candidate) return;
|
|
2873
|
-
const ok = await
|
|
2904
|
+
const ok = await copyValue2(candidate.value, "Generated password");
|
|
2874
2905
|
setNote(ok ? { tone: "success", text: "Copied. Your clipboard keeps it." } : { tone: "destructive", text: "Couldn\u2019t copy. Reveal it and copy by hand." });
|
|
2875
2906
|
};
|
|
2876
2907
|
const use = () => {
|
|
@@ -2981,8 +3012,47 @@ function importLimitsFrom(resolved) {
|
|
|
2981
3012
|
return out;
|
|
2982
3013
|
}
|
|
2983
3014
|
|
|
3015
|
+
// src/lock.ts
|
|
3016
|
+
var import_react16 = require("react");
|
|
3017
|
+
var LOCKED_MESSAGE = "The vault is locked. Unlock it first.";
|
|
3018
|
+
var VaultLockedError = class extends Error {
|
|
3019
|
+
code = "vault_locked";
|
|
3020
|
+
constructor() {
|
|
3021
|
+
super(LOCKED_MESSAGE);
|
|
3022
|
+
this.name = "VaultLockedError";
|
|
3023
|
+
}
|
|
3024
|
+
};
|
|
3025
|
+
function guardPort(port, locked) {
|
|
3026
|
+
const cache = /* @__PURE__ */ new WeakMap();
|
|
3027
|
+
const wrap = (target) => {
|
|
3028
|
+
const hit = cache.get(target);
|
|
3029
|
+
if (hit) return hit;
|
|
3030
|
+
const proxy = new Proxy(target, {
|
|
3031
|
+
get(obj2, key, receiver) {
|
|
3032
|
+
const value = Reflect.get(obj2, key, receiver);
|
|
3033
|
+
if (typeof value === "function") {
|
|
3034
|
+
return (...args) => {
|
|
3035
|
+
if (locked()) return Promise.reject(new VaultLockedError());
|
|
3036
|
+
return value.apply(obj2, args);
|
|
3037
|
+
};
|
|
3038
|
+
}
|
|
3039
|
+
if (value && typeof value === "object") return wrap(value);
|
|
3040
|
+
return value;
|
|
3041
|
+
}
|
|
3042
|
+
});
|
|
3043
|
+
cache.set(target, proxy);
|
|
3044
|
+
return proxy;
|
|
3045
|
+
};
|
|
3046
|
+
return wrap(port);
|
|
3047
|
+
}
|
|
3048
|
+
var NEVER = () => () => void 0;
|
|
3049
|
+
var UNLOCKED = () => false;
|
|
3050
|
+
function useLocked(lock) {
|
|
3051
|
+
return (0, import_react16.useSyncExternalStore)(lock ? lock.subscribe : NEVER, lock ? () => lock.locked() : UNLOCKED, UNLOCKED);
|
|
3052
|
+
}
|
|
3053
|
+
|
|
2984
3054
|
// src/io/BackupPanel.tsx
|
|
2985
|
-
var
|
|
3055
|
+
var import_react18 = require("react");
|
|
2986
3056
|
var import_controls13 = require("@ai-matrx/design-system/controls");
|
|
2987
3057
|
var import_download = require("@ai-matrx/kit/download");
|
|
2988
3058
|
var import_confirm_opener4 = require("@ai-matrx/kit/confirm-opener");
|
|
@@ -3075,7 +3145,7 @@ function startNewRestoreRun(preview) {
|
|
|
3075
3145
|
}
|
|
3076
3146
|
|
|
3077
3147
|
// src/io/lines.tsx
|
|
3078
|
-
var
|
|
3148
|
+
var import_react17 = require("react");
|
|
3079
3149
|
var import_design_system11 = require("@ai-matrx/design-system");
|
|
3080
3150
|
var import_controls12 = require("@ai-matrx/design-system/controls");
|
|
3081
3151
|
var import_jsx_runtime15 = require("react/jsx-runtime");
|
|
@@ -3088,7 +3158,7 @@ function PickLine({ checked, onChange, disabled = false, title, detail, badge, t
|
|
|
3088
3158
|
] });
|
|
3089
3159
|
}
|
|
3090
3160
|
function Windowed({ items, size = 150, render }) {
|
|
3091
|
-
const [all, setAll] = (0,
|
|
3161
|
+
const [all, setAll] = (0, import_react17.useState)(false);
|
|
3092
3162
|
const shown = all ? items : items.slice(0, size);
|
|
3093
3163
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)(import_jsx_runtime15.Fragment, { children: [
|
|
3094
3164
|
shown.map(render),
|
|
@@ -3099,7 +3169,7 @@ function Windowed({ items, size = 150, render }) {
|
|
|
3099
3169
|
] });
|
|
3100
3170
|
}
|
|
3101
3171
|
function More({ title = "More", children }) {
|
|
3102
|
-
const [open, setOpen] = (0,
|
|
3172
|
+
const [open, setOpen] = (0, import_react17.useState)(false);
|
|
3103
3173
|
return /* @__PURE__ */ (0, import_jsx_runtime15.jsxs)("div", { className: "flex flex-col gap-2", children: [
|
|
3104
3174
|
/* @__PURE__ */ (0, import_jsx_runtime15.jsx)(import_controls12.DisclosureHeader, { open, title, onClick: () => setOpen((o) => !o) }),
|
|
3105
3175
|
open ? children : null
|
|
@@ -3138,21 +3208,21 @@ function Omissions({ omissions, accepted, onAccepted, verb }) {
|
|
|
3138
3208
|
}
|
|
3139
3209
|
function BackupPanel({ port, items, onClose, onChanged }) {
|
|
3140
3210
|
const confirmed = useConfirmed();
|
|
3141
|
-
const fileInput = (0,
|
|
3142
|
-
const abort = (0,
|
|
3143
|
-
const [mode, setMode] = (0,
|
|
3144
|
-
const [busy, setBusy] = (0,
|
|
3145
|
-
const [error, setError] = (0,
|
|
3146
|
-
const [passphrase, setPassphrase] = (0,
|
|
3147
|
-
const [repeat, setRepeat] = (0,
|
|
3148
|
-
const [accepted, setAccepted] = (0,
|
|
3149
|
-
const [selected, setSelected] = (0,
|
|
3150
|
-
const [backup, setBackup] = (0,
|
|
3151
|
-
const [file, setFile] = (0,
|
|
3152
|
-
const [restorePreview, setRestorePreview] = (0,
|
|
3153
|
-
const [runId, setRunId] = (0,
|
|
3154
|
-
const [result, setResult] = (0,
|
|
3155
|
-
(0,
|
|
3211
|
+
const fileInput = (0, import_react18.useRef)(null);
|
|
3212
|
+
const abort = (0, import_react18.useRef)(null);
|
|
3213
|
+
const [mode, setMode] = (0, import_react18.useState)("backup");
|
|
3214
|
+
const [busy, setBusy] = (0, import_react18.useState)(false);
|
|
3215
|
+
const [error, setError] = (0, import_react18.useState)(null);
|
|
3216
|
+
const [passphrase, setPassphrase] = (0, import_react18.useState)("");
|
|
3217
|
+
const [repeat, setRepeat] = (0, import_react18.useState)("");
|
|
3218
|
+
const [accepted, setAccepted] = (0, import_react18.useState)(false);
|
|
3219
|
+
const [selected, setSelected] = (0, import_react18.useState)(/* @__PURE__ */ new Set());
|
|
3220
|
+
const [backup, setBackup] = (0, import_react18.useState)(null);
|
|
3221
|
+
const [file, setFile] = (0, import_react18.useState)(null);
|
|
3222
|
+
const [restorePreview, setRestorePreview] = (0, import_react18.useState)(null);
|
|
3223
|
+
const [runId, setRunId] = (0, import_react18.useState)(null);
|
|
3224
|
+
const [result, setResult] = (0, import_react18.useState)(null);
|
|
3225
|
+
(0, import_react18.useEffect)(() => () => abort.current?.abort(), []);
|
|
3156
3226
|
const switchMode = (next) => {
|
|
3157
3227
|
abort.current?.abort();
|
|
3158
3228
|
setMode(next);
|
|
@@ -3323,7 +3393,7 @@ function BackupPanel({ port, items, onClose, onChanged }) {
|
|
|
3323
3393
|
}
|
|
3324
3394
|
|
|
3325
3395
|
// src/io/ExportPanel.tsx
|
|
3326
|
-
var
|
|
3396
|
+
var import_react19 = require("react");
|
|
3327
3397
|
var import_controls14 = require("@ai-matrx/design-system/controls");
|
|
3328
3398
|
var import_download2 = require("@ai-matrx/kit/download");
|
|
3329
3399
|
var import_confirm_opener5 = require("@ai-matrx/kit/confirm-opener");
|
|
@@ -3347,12 +3417,12 @@ function omissionText2(omissions) {
|
|
|
3347
3417
|
}
|
|
3348
3418
|
function ExportPanel({ port, items, onClose }) {
|
|
3349
3419
|
const confirmed = useConfirmed();
|
|
3350
|
-
const logins = (0,
|
|
3351
|
-
const [profile, setProfile] = (0,
|
|
3352
|
-
const [selected, setSelected] = (0,
|
|
3353
|
-
const [preview, setPreview] = (0,
|
|
3354
|
-
const [busy, setBusy] = (0,
|
|
3355
|
-
const [error, setError] = (0,
|
|
3420
|
+
const logins = (0, import_react19.useMemo)(() => items.filter((i) => i.definitionKey === WEBSITE_LOGIN), [items]);
|
|
3421
|
+
const [profile, setProfile] = (0, import_react19.useState)("matrx_login_csv_v1");
|
|
3422
|
+
const [selected, setSelected] = (0, import_react19.useState)(/* @__PURE__ */ new Set());
|
|
3423
|
+
const [preview, setPreview] = (0, import_react19.useState)(null);
|
|
3424
|
+
const [busy, setBusy] = (0, import_react19.useState)(false);
|
|
3425
|
+
const [error, setError] = (0, import_react19.useState)(null);
|
|
3356
3426
|
const format = FORMATS.find((f) => f.value === profile);
|
|
3357
3427
|
const reasons = new Map(preview?.items.map((p) => [p.item_id, p]) ?? []);
|
|
3358
3428
|
const eligible = preview?.items.filter((p) => p.eligible).length ?? 0;
|
|
@@ -3477,7 +3547,7 @@ function ExportPanel({ port, items, onClose }) {
|
|
|
3477
3547
|
}
|
|
3478
3548
|
|
|
3479
3549
|
// src/io/ImportPanel.tsx
|
|
3480
|
-
var
|
|
3550
|
+
var import_react20 = require("react");
|
|
3481
3551
|
var import_controls15 = require("@ai-matrx/design-system/controls");
|
|
3482
3552
|
|
|
3483
3553
|
// src/io/csv-import.ts
|
|
@@ -4336,24 +4406,24 @@ var STATE_BADGE = {
|
|
|
4336
4406
|
var ME = "me";
|
|
4337
4407
|
function ImportPanel({ port, host, items, organizations, onClose, onChanged, limits }) {
|
|
4338
4408
|
const confirmed = useConfirmed();
|
|
4339
|
-
const fileInput = (0,
|
|
4340
|
-
const abort = (0,
|
|
4341
|
-
const stop = (0,
|
|
4342
|
-
const keys = (0,
|
|
4343
|
-
const [source, setSource] = (0,
|
|
4344
|
-
const [envText, setEnvText] = (0,
|
|
4345
|
-
const [injectSandbox, setInjectSandbox] = (0,
|
|
4346
|
-
const [fileName, setFileName] = (0,
|
|
4347
|
-
const [reading, setReading] = (0,
|
|
4348
|
-
const [draft, setDraft] = (0,
|
|
4349
|
-
const [destination, setDestination] = (0,
|
|
4350
|
-
const [browserFill, setBrowserFill] = (0,
|
|
4351
|
-
const [approvedVisible, setApprovedVisible] = (0,
|
|
4352
|
-
const [selected, setSelected] = (0,
|
|
4353
|
-
const [running, setRunning] = (0,
|
|
4354
|
-
const [done, setDone] = (0,
|
|
4355
|
-
const [error, setError] = (0,
|
|
4356
|
-
(0,
|
|
4409
|
+
const fileInput = (0, import_react20.useRef)(null);
|
|
4410
|
+
const abort = (0, import_react20.useRef)(null);
|
|
4411
|
+
const stop = (0, import_react20.useRef)(false);
|
|
4412
|
+
const keys = (0, import_react20.useRef)(/* @__PURE__ */ new Map());
|
|
4413
|
+
const [source, setSource] = (0, import_react20.useState)("auto");
|
|
4414
|
+
const [envText, setEnvText] = (0, import_react20.useState)("");
|
|
4415
|
+
const [injectSandbox, setInjectSandbox] = (0, import_react20.useState)(false);
|
|
4416
|
+
const [fileName, setFileName] = (0, import_react20.useState)(null);
|
|
4417
|
+
const [reading, setReading] = (0, import_react20.useState)(false);
|
|
4418
|
+
const [draft, setDraft] = (0, import_react20.useState)(null);
|
|
4419
|
+
const [destination, setDestination] = (0, import_react20.useState)(ME);
|
|
4420
|
+
const [browserFill, setBrowserFill] = (0, import_react20.useState)(false);
|
|
4421
|
+
const [approvedVisible, setApprovedVisible] = (0, import_react20.useState)(false);
|
|
4422
|
+
const [selected, setSelected] = (0, import_react20.useState)(/* @__PURE__ */ new Set());
|
|
4423
|
+
const [running, setRunning] = (0, import_react20.useState)(null);
|
|
4424
|
+
const [done, setDone] = (0, import_react20.useState)(null);
|
|
4425
|
+
const [error, setError] = (0, import_react20.useState)(null);
|
|
4426
|
+
(0, import_react20.useEffect)(
|
|
4357
4427
|
() => () => {
|
|
4358
4428
|
abort.current?.abort();
|
|
4359
4429
|
stop.current = true;
|
|
@@ -4362,9 +4432,9 @@ function ImportPanel({ port, host, items, organizations, onClose, onChanged, lim
|
|
|
4362
4432
|
);
|
|
4363
4433
|
const organizationId = destination === ME ? null : destination;
|
|
4364
4434
|
const existingIn = (org) => items.filter((i) => org === null ? i.owner.kind === "me" : i.owner.organizationId === org).map((i) => ({ displayName: i.name, loginUrls: i.loginUrls }));
|
|
4365
|
-
const existing = (0,
|
|
4366
|
-
const destinationOptions = (0,
|
|
4367
|
-
const lines = (0,
|
|
4435
|
+
const existing = (0, import_react20.useMemo)(() => existingIn(organizationId), [items, organizationId]);
|
|
4436
|
+
const destinationOptions = (0, import_react20.useMemo)(() => [{ value: ME, label: "Personal" }, ...organizations.map((o) => ({ value: o.id, label: o.name }))], [organizations]);
|
|
4437
|
+
const lines = (0, import_react20.useMemo)(
|
|
4368
4438
|
() => draft?.kind === "file" ? reviewLines(draft.parsed, { organizationId, browserFill, existing, limits, mapping: draft.mapping }) : [],
|
|
4369
4439
|
[draft, organizationId, browserFill, existing, limits]
|
|
4370
4440
|
);
|
|
@@ -4616,7 +4686,7 @@ function Notices({ draft }) {
|
|
|
4616
4686
|
}
|
|
4617
4687
|
|
|
4618
4688
|
// src/ItemList.tsx
|
|
4619
|
-
var
|
|
4689
|
+
var import_react28 = require("react");
|
|
4620
4690
|
var import_design_system18 = require("@ai-matrx/design-system");
|
|
4621
4691
|
var import_design_system19 = require("@ai-matrx/design-system");
|
|
4622
4692
|
var import_controls22 = require("@ai-matrx/design-system/controls");
|
|
@@ -4636,14 +4706,14 @@ function ItemIcon({ definitionKey, family, site, size = "md", inverted = false }
|
|
|
4636
4706
|
}
|
|
4637
4707
|
|
|
4638
4708
|
// src/ItemPane.tsx
|
|
4639
|
-
var
|
|
4709
|
+
var import_react27 = require("react");
|
|
4640
4710
|
var import_design_system16 = require("@ai-matrx/design-system");
|
|
4641
4711
|
var import_design_system17 = require("@ai-matrx/design-system");
|
|
4642
4712
|
var import_controls21 = require("@ai-matrx/design-system/controls");
|
|
4643
4713
|
var import_confirm_opener9 = require("@ai-matrx/kit/confirm-opener");
|
|
4644
4714
|
|
|
4645
4715
|
// src/activity/FilesSection.tsx
|
|
4646
|
-
var
|
|
4716
|
+
var import_react21 = require("react");
|
|
4647
4717
|
var import_controls16 = require("@ai-matrx/design-system/controls");
|
|
4648
4718
|
var import_design_system13 = require("@ai-matrx/design-system");
|
|
4649
4719
|
var import_confirm_opener6 = require("@ai-matrx/kit/confirm-opener");
|
|
@@ -4659,11 +4729,11 @@ var PROTECTION = [
|
|
|
4659
4729
|
function FilesSection({ item, port, editing, onChanged }) {
|
|
4660
4730
|
const confirmed = useConfirmed();
|
|
4661
4731
|
const canEdit = editing && item.capabilities.canEdit;
|
|
4662
|
-
const [busy, setBusy] = (0,
|
|
4663
|
-
const [error, setError] = (0,
|
|
4664
|
-
const [pending, setPending] = (0,
|
|
4665
|
-
const [dragging, setDragging] = (0,
|
|
4666
|
-
const picker = (0,
|
|
4732
|
+
const [busy, setBusy] = (0, import_react21.useState)(null);
|
|
4733
|
+
const [error, setError] = (0, import_react21.useState)(null);
|
|
4734
|
+
const [pending, setPending] = (0, import_react21.useState)(null);
|
|
4735
|
+
const [dragging, setDragging] = (0, import_react21.useState)(false);
|
|
4736
|
+
const picker = (0, import_react21.useRef)(null);
|
|
4667
4737
|
if (!canEdit && item.attachments.length === 0) return null;
|
|
4668
4738
|
async function run(key, work, fallback) {
|
|
4669
4739
|
setBusy(key);
|
|
@@ -4739,8 +4809,8 @@ function FilesSection({ item, port, editing, onChanged }) {
|
|
|
4739
4809
|
);
|
|
4740
4810
|
}
|
|
4741
4811
|
function EditableFile({ port, item: it, file: a, busy: b, run: go, onDownload, onTooBig }) {
|
|
4742
|
-
const [open, setOpen] = (0,
|
|
4743
|
-
const replacer = (0,
|
|
4812
|
+
const [open, setOpen] = (0, import_react21.useState)(false);
|
|
4813
|
+
const replacer = (0, import_react21.useRef)(null);
|
|
4744
4814
|
async function remove() {
|
|
4745
4815
|
const yes = await (0, import_confirm_opener6.confirm)({ title: `Delete ${a.label}?`, description: "The encrypted file is removed from this item.", confirmLabel: "Delete", variant: "destructive" });
|
|
4746
4816
|
if (yes) await go(`delete:${a.id}`, () => port.activity.deleteFile(it, a.id), "The file could not be deleted.");
|
|
@@ -4798,9 +4868,9 @@ function Protection({ value, locked, onChange }) {
|
|
|
4798
4868
|
);
|
|
4799
4869
|
}
|
|
4800
4870
|
function NewFile({ file, busy, onAdd, onCancel }) {
|
|
4801
|
-
const [label, setLabel] = (0,
|
|
4802
|
-
const [description, setDescription] = (0,
|
|
4803
|
-
const [handling, setHandling] = (0,
|
|
4871
|
+
const [label, setLabel] = (0, import_react21.useState)(file.name);
|
|
4872
|
+
const [description, setDescription] = (0, import_react21.useState)("");
|
|
4873
|
+
const [handling, setHandling] = (0, import_react21.useState)("revealable");
|
|
4804
4874
|
async function add() {
|
|
4805
4875
|
if (handling === "sealed" && !await confirmSeal(label)) return;
|
|
4806
4876
|
await onAdd({ label: label.trim(), description: description.trim() || null, handling });
|
|
@@ -4820,10 +4890,10 @@ function NewFile({ file, busy, onAdd, onCancel }) {
|
|
|
4820
4890
|
] });
|
|
4821
4891
|
}
|
|
4822
4892
|
function FileDetailsRows({ file, busy, onSave, onCancel }) {
|
|
4823
|
-
const [label, setLabel] = (0,
|
|
4824
|
-
const [description, setDescription] = (0,
|
|
4825
|
-
const [fileName, setFileName] = (0,
|
|
4826
|
-
const [handling, setHandling] = (0,
|
|
4893
|
+
const [label, setLabel] = (0, import_react21.useState)(file.label);
|
|
4894
|
+
const [description, setDescription] = (0, import_react21.useState)(file.description);
|
|
4895
|
+
const [fileName, setFileName] = (0, import_react21.useState)(file.fileName);
|
|
4896
|
+
const [handling, setHandling] = (0, import_react21.useState)(file.handling);
|
|
4827
4897
|
const changed = label !== file.label || description !== file.description || fileName !== file.fileName || handling !== file.handling;
|
|
4828
4898
|
async function save() {
|
|
4829
4899
|
if (handling === "sealed" && file.handling !== "sealed" && !await confirmSeal(label)) return;
|
|
@@ -4850,18 +4920,18 @@ function confirmSeal(label) {
|
|
|
4850
4920
|
}
|
|
4851
4921
|
|
|
4852
4922
|
// src/fields/RecoveryCodesRow.tsx
|
|
4853
|
-
var
|
|
4923
|
+
var import_react22 = require("react");
|
|
4854
4924
|
var import_controls17 = require("@ai-matrx/design-system/controls");
|
|
4855
4925
|
var import_jsx_runtime21 = require("react/jsx-runtime");
|
|
4856
4926
|
var MASK4 = "\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022\u2022";
|
|
4857
4927
|
var say2 = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
|
|
4858
4928
|
function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
4859
4929
|
const confirmed = useConfirmed();
|
|
4860
|
-
const
|
|
4930
|
+
const copyValue2 = useCopy();
|
|
4861
4931
|
const secret = useTransientSecret();
|
|
4862
|
-
const [busy, setBusy] = (0,
|
|
4863
|
-
const [error, setError] = (0,
|
|
4864
|
-
const [draft, setDraft] = (0,
|
|
4932
|
+
const [busy, setBusy] = (0, import_react22.useState)(false);
|
|
4933
|
+
const [error, setError] = (0, import_react22.useState)(null);
|
|
4934
|
+
const [draft, setDraft] = (0, import_react22.useState)(null);
|
|
4865
4935
|
const canEdit = item.capabilities.canEdit;
|
|
4866
4936
|
const run = async (step) => {
|
|
4867
4937
|
setBusy(true);
|
|
@@ -4945,7 +5015,7 @@ function RecoveryCodesRow({ item, field, port, onChanged }) {
|
|
|
4945
5015
|
children: sealed ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Badge, { icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(LockGlyph, {}), children: "Sealed" }) : codes ? /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("ul", { className: "flex flex-col gap-0.5", "aria-label": "Recovery codes", children: [
|
|
4946
5016
|
codes.map((code, i) => /* @__PURE__ */ (0, import_jsx_runtime21.jsxs)("li", { className: "flex min-h-7 items-center gap-1", children: [
|
|
4947
5017
|
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)("code", { className: "min-w-0 flex-1 break-all font-mono text-sm text-foreground", children: code }),
|
|
4948
|
-
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopyGlyph, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void
|
|
5018
|
+
/* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CopyGlyph, {}), "aria-label": `Copy code ${i + 1}`, onClick: () => void copyValue2(code, "Recovery code") }),
|
|
4949
5019
|
canEdit ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(import_controls17.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime21.jsx)(CheckGlyph, {}), disabled: busy, onClick: () => void markUsed(i), children: "Mark used" }) : null
|
|
4950
5020
|
] }, `${i}-${code}`)),
|
|
4951
5021
|
error ? /* @__PURE__ */ (0, import_jsx_runtime21.jsx)("li", { role: "alert", className: "text-xs text-destructive", children: error }) : null
|
|
@@ -5096,7 +5166,7 @@ function targetLabel(t) {
|
|
|
5096
5166
|
}
|
|
5097
5167
|
|
|
5098
5168
|
// src/extension/UseOnSiteButton.tsx
|
|
5099
|
-
var
|
|
5169
|
+
var import_react23 = require("react");
|
|
5100
5170
|
var import_controls18 = require("@ai-matrx/design-system/controls");
|
|
5101
5171
|
var import_jsx_runtime22 = require("react/jsx-runtime");
|
|
5102
5172
|
function canUseOnSite(item, pageUrl) {
|
|
@@ -5104,7 +5174,7 @@ function canUseOnSite(item, pageUrl) {
|
|
|
5104
5174
|
}
|
|
5105
5175
|
function UseOnSiteButton({ port, item, pageUrl, onChanged }) {
|
|
5106
5176
|
const notify = useNotify();
|
|
5107
|
-
const [busy, setBusy] = (0,
|
|
5177
|
+
const [busy, setBusy] = (0, import_react23.useState)(false);
|
|
5108
5178
|
if (!canUseOnSite(item, pageUrl)) return null;
|
|
5109
5179
|
const site = pageSite(pageUrl);
|
|
5110
5180
|
const run = async () => {
|
|
@@ -5123,7 +5193,7 @@ function UseOnSiteButton({ port, item, pageUrl, onChanged }) {
|
|
|
5123
5193
|
}
|
|
5124
5194
|
|
|
5125
5195
|
// src/sharing/SharePanel.tsx
|
|
5126
|
-
var
|
|
5196
|
+
var import_react26 = require("react");
|
|
5127
5197
|
var import_confirm_opener8 = require("@ai-matrx/kit/confirm-opener");
|
|
5128
5198
|
var import_controls20 = require("@ai-matrx/design-system/controls");
|
|
5129
5199
|
var import_design_system15 = require("@ai-matrx/design-system");
|
|
@@ -5180,7 +5250,7 @@ function shareSummary(grants) {
|
|
|
5180
5250
|
var MEMBER_CHOICE_DEFAULT = "default";
|
|
5181
5251
|
|
|
5182
5252
|
// src/sharing/parts.tsx
|
|
5183
|
-
var
|
|
5253
|
+
var import_react24 = require("react");
|
|
5184
5254
|
var import_design_system14 = require("@ai-matrx/design-system");
|
|
5185
5255
|
var import_jsx_runtime23 = require("react/jsx-runtime");
|
|
5186
5256
|
var message = (e, fallback) => {
|
|
@@ -5189,9 +5259,9 @@ var message = (e, fallback) => {
|
|
|
5189
5259
|
};
|
|
5190
5260
|
function useAction() {
|
|
5191
5261
|
const confirmed = useConfirmed();
|
|
5192
|
-
const [busy, setBusy] = (0,
|
|
5193
|
-
const [error, setError] = (0,
|
|
5194
|
-
const [notice, setNotice] = (0,
|
|
5262
|
+
const [busy, setBusy] = (0, import_react24.useState)(null);
|
|
5263
|
+
const [error, setError] = (0, import_react24.useState)(null);
|
|
5264
|
+
const [notice, setNotice] = (0, import_react24.useState)(null);
|
|
5195
5265
|
async function run(key, fn, done) {
|
|
5196
5266
|
setBusy(key);
|
|
5197
5267
|
setError(null);
|
|
@@ -5225,7 +5295,7 @@ function StatusLine({ error, notice }) {
|
|
|
5225
5295
|
}
|
|
5226
5296
|
|
|
5227
5297
|
// src/sharing/MovePanel.tsx
|
|
5228
|
-
var
|
|
5298
|
+
var import_react25 = require("react");
|
|
5229
5299
|
var import_confirm_opener7 = require("@ai-matrx/kit/confirm-opener");
|
|
5230
5300
|
var import_controls19 = require("@ai-matrx/design-system/controls");
|
|
5231
5301
|
var import_jsx_runtime24 = require("react/jsx-runtime");
|
|
@@ -5234,9 +5304,9 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5234
5304
|
const { busy, error, notice, run, setNotice } = useAction();
|
|
5235
5305
|
const moves = moveDestinations(item, organizations);
|
|
5236
5306
|
const copies = copyDestinations(organizations, item);
|
|
5237
|
-
const [moveTo, setMoveTo] = (0,
|
|
5238
|
-
const [copyTo, setCopyTo] = (0,
|
|
5239
|
-
const [email, setEmail] = (0,
|
|
5307
|
+
const [moveTo, setMoveTo] = (0, import_react25.useState)("");
|
|
5308
|
+
const [copyTo, setCopyTo] = (0, import_react25.useState)("");
|
|
5309
|
+
const [email, setEmail] = (0, import_react25.useState)("");
|
|
5240
5310
|
const passkey = isPasskey(item);
|
|
5241
5311
|
const canMove = item.capabilities.canManage && !passkey && moves.length > 0;
|
|
5242
5312
|
const canGive = item.capabilities.canManage && item.owner.kind === "me" && !passkey;
|
|
@@ -5317,11 +5387,11 @@ function MovePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5317
5387
|
// src/sharing/SharePanel.tsx
|
|
5318
5388
|
var import_jsx_runtime25 = require("react/jsx-runtime");
|
|
5319
5389
|
function useGrants(port, item) {
|
|
5320
|
-
const [grants, setGrants] = (0,
|
|
5321
|
-
const [loadError, setLoadError] = (0,
|
|
5322
|
-
const [nonce, setNonce] = (0,
|
|
5390
|
+
const [grants, setGrants] = (0, import_react26.useState)(null);
|
|
5391
|
+
const [loadError, setLoadError] = (0, import_react26.useState)(null);
|
|
5392
|
+
const [nonce, setNonce] = (0, import_react26.useState)(0);
|
|
5323
5393
|
const allowed = item.capabilities.canManage;
|
|
5324
|
-
(0,
|
|
5394
|
+
(0, import_react26.useEffect)(() => {
|
|
5325
5395
|
if (!allowed) return;
|
|
5326
5396
|
let live = true;
|
|
5327
5397
|
setLoadError(null);
|
|
@@ -5338,9 +5408,9 @@ function useGrants(port, item) {
|
|
|
5338
5408
|
function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
5339
5409
|
const { grants, setGrants, loadError, reload } = useGrants(port, item);
|
|
5340
5410
|
const { busy, error, notice, run } = useAction();
|
|
5341
|
-
const [email, setEmail] = (0,
|
|
5342
|
-
const [level, setLevel] = (0,
|
|
5343
|
-
const [more, setMore] = (0,
|
|
5411
|
+
const [email, setEmail] = (0, import_react26.useState)("");
|
|
5412
|
+
const [level, setLevel] = (0, import_react26.useState)("use");
|
|
5413
|
+
const [more, setMore] = (0, import_react26.useState)(false);
|
|
5344
5414
|
const isOrg = item.owner.kind === "organization" && item.owner.organizationId !== null;
|
|
5345
5415
|
const orgName = item.owner.label;
|
|
5346
5416
|
const people = (grants ?? []).filter((g) => g.kind === "person");
|
|
@@ -5462,8 +5532,8 @@ function SharePanel({ item, port, organizations, onClose, onChanged }) {
|
|
|
5462
5532
|
function IntoOrganization({ item, port, organizations, grants, onShared }) {
|
|
5463
5533
|
const { busy, error, notice, run } = useAction();
|
|
5464
5534
|
const open = organizations.filter((o) => !grants.some((g) => g.organizationId === o.id));
|
|
5465
|
-
const [target, setTarget] = (0,
|
|
5466
|
-
const [level, setLevel] = (0,
|
|
5535
|
+
const [target, setTarget] = (0, import_react26.useState)("");
|
|
5536
|
+
const [level, setLevel] = (0, import_react26.useState)("use");
|
|
5467
5537
|
const chosen = open.find((o) => o.id === target);
|
|
5468
5538
|
if (item.owner.kind !== "me") return null;
|
|
5469
5539
|
return /* @__PURE__ */ (0, import_jsx_runtime25.jsx)(Section, { title: "Share into organization", children: open.length > 0 ? /* @__PURE__ */ (0, import_jsx_runtime25.jsxs)(import_jsx_runtime25.Fragment, { children: [
|
|
@@ -5498,10 +5568,10 @@ var CHOICES = [
|
|
|
5498
5568
|
{ value: "editor", label: "Can edit", meta: "See and change" }
|
|
5499
5569
|
];
|
|
5500
5570
|
function MemberAccess({ port, organizationId, organizationName }) {
|
|
5501
|
-
const [list, setList] = (0,
|
|
5502
|
-
const [loadError, setLoadError] = (0,
|
|
5571
|
+
const [list, setList] = (0, import_react26.useState)(null);
|
|
5572
|
+
const [loadError, setLoadError] = (0, import_react26.useState)(null);
|
|
5503
5573
|
const { busy, error, run } = useAction();
|
|
5504
|
-
(0,
|
|
5574
|
+
(0, import_react26.useEffect)(() => {
|
|
5505
5575
|
let live = true;
|
|
5506
5576
|
port.sharing.memberAccess(organizationId).then(
|
|
5507
5577
|
(l) => live && setList(l),
|
|
@@ -5533,9 +5603,9 @@ function MemberAccess({ port, organizationId, organizationName }) {
|
|
|
5533
5603
|
] });
|
|
5534
5604
|
}
|
|
5535
5605
|
function SharingSummary({ item, port, className }) {
|
|
5536
|
-
const [text, setText] = (0,
|
|
5606
|
+
const [text, setText] = (0, import_react26.useState)("");
|
|
5537
5607
|
const allowed = item.capabilities.canManage;
|
|
5538
|
-
(0,
|
|
5608
|
+
(0, import_react26.useEffect)(() => {
|
|
5539
5609
|
if (!allowed) return;
|
|
5540
5610
|
let live = true;
|
|
5541
5611
|
port.sharing.grants(item).then(
|
|
@@ -5560,8 +5630,8 @@ function ItemPane(props) {
|
|
|
5560
5630
|
const editing = mode !== "view";
|
|
5561
5631
|
const seedName = seed?.name ?? "";
|
|
5562
5632
|
const seedUrl = seed?.url ?? "";
|
|
5563
|
-
const [loaded, setLoaded] = (0,
|
|
5564
|
-
const base = (0,
|
|
5633
|
+
const [loaded, setLoaded] = (0, import_react27.useState)({});
|
|
5634
|
+
const base = (0, import_react27.useMemo)(() => {
|
|
5565
5635
|
const b = draftOf(item);
|
|
5566
5636
|
if (!item) {
|
|
5567
5637
|
b.name = seedName;
|
|
@@ -5570,22 +5640,22 @@ function ItemPane(props) {
|
|
|
5570
5640
|
b.values = { ...loaded };
|
|
5571
5641
|
return b;
|
|
5572
5642
|
}, [item, seedName, seedUrl, loaded]);
|
|
5573
|
-
const [draft, setDraft] = (0,
|
|
5574
|
-
const [tagsText, setTagsText] = (0,
|
|
5575
|
-
const [showTags, setShowTags] = (0,
|
|
5576
|
-
const [showDescription, setShowDescription] = (0,
|
|
5577
|
-
const [owner, setOwner] = (0,
|
|
5578
|
-
const [recipient, setRecipient] = (0,
|
|
5579
|
-
const [generatePrivately, setGeneratePrivately] = (0,
|
|
5580
|
-
const [busy, setBusy] = (0,
|
|
5581
|
-
const [error, setError] = (0,
|
|
5582
|
-
const [destinations, setDestinations] = (0,
|
|
5643
|
+
const [draft, setDraft] = (0, import_react27.useState)(base);
|
|
5644
|
+
const [tagsText, setTagsText] = (0, import_react27.useState)(base.tags.join(", "));
|
|
5645
|
+
const [showTags, setShowTags] = (0, import_react27.useState)(false);
|
|
5646
|
+
const [showDescription, setShowDescription] = (0, import_react27.useState)(false);
|
|
5647
|
+
const [owner, setOwner] = (0, import_react27.useState)(defaultOwner ?? "me");
|
|
5648
|
+
const [recipient, setRecipient] = (0, import_react27.useState)("");
|
|
5649
|
+
const [generatePrivately, setGeneratePrivately] = (0, import_react27.useState)(false);
|
|
5650
|
+
const [busy, setBusy] = (0, import_react27.useState)(false);
|
|
5651
|
+
const [error, setError] = (0, import_react27.useState)(null);
|
|
5652
|
+
const [destinations, setDestinations] = (0, import_react27.useState)({});
|
|
5583
5653
|
const dirty = editing && isDirty(base, draft);
|
|
5584
5654
|
const declared = definition?.fields ?? [];
|
|
5585
|
-
const prev = (0,
|
|
5586
|
-
const paneRef = (0,
|
|
5655
|
+
const prev = (0, import_react27.useRef)(null);
|
|
5656
|
+
const paneRef = (0, import_react27.useRef)(null);
|
|
5587
5657
|
const room = useRoomOf(paneRef);
|
|
5588
|
-
(0,
|
|
5658
|
+
(0, import_react27.useEffect)(() => {
|
|
5589
5659
|
const was = prev.current;
|
|
5590
5660
|
const id = item?.id ?? null;
|
|
5591
5661
|
if (was && was.id === id && was.mode === mode && editing) {
|
|
@@ -5598,18 +5668,18 @@ function ItemPane(props) {
|
|
|
5598
5668
|
}
|
|
5599
5669
|
prev.current = { base, id, mode };
|
|
5600
5670
|
}, [base, mode, item?.id, editing]);
|
|
5601
|
-
(0,
|
|
5671
|
+
(0, import_react27.useEffect)(() => {
|
|
5602
5672
|
setLoaded({});
|
|
5603
5673
|
setShowTags(false);
|
|
5604
5674
|
setShowDescription(false);
|
|
5605
5675
|
}, [item?.id, mode]);
|
|
5606
|
-
(0,
|
|
5676
|
+
(0, import_react27.useEffect)(() => onDirty(dirty), [dirty, onDirty]);
|
|
5607
5677
|
const keepKey = draftKey(item?.id ?? null, definition?.key ?? item?.definitionKey ?? null);
|
|
5608
|
-
(0,
|
|
5678
|
+
(0, import_react27.useEffect)(() => {
|
|
5609
5679
|
if (editing && dirty) keepDraft(keepKey, item?.updatedAt ?? "new", draft);
|
|
5610
5680
|
else if (!editing) dropKeptDraft(keepKey);
|
|
5611
5681
|
}, [editing, dirty, draft, keepKey, item?.updatedAt]);
|
|
5612
|
-
(0,
|
|
5682
|
+
(0, import_react27.useEffect)(() => {
|
|
5613
5683
|
if (!editing || !item) return;
|
|
5614
5684
|
let live = true;
|
|
5615
5685
|
for (const f of item.fields) {
|
|
@@ -5955,8 +6025,8 @@ function ItemList({ title, items, definitions, port, selectedId, onSelect, query
|
|
|
5955
6025
|
const pinned = matchingIds ? items.filter((i) => matchingIds.has(i.id)) : [];
|
|
5956
6026
|
const rest = matchingIds ? items.filter((i) => !matchingIds.has(i.id)) : items;
|
|
5957
6027
|
const ordered = [...pinned, ...rest];
|
|
5958
|
-
const listRef = (0,
|
|
5959
|
-
(0,
|
|
6028
|
+
const listRef = (0, import_react28.useRef)(null);
|
|
6029
|
+
(0, import_react28.useEffect)(() => {
|
|
5960
6030
|
if (selectedId) listRef.current?.querySelector(`[data-item="${selectedId}"]`)?.scrollIntoView({ block: "nearest" });
|
|
5961
6031
|
}, [selectedId, items.length]);
|
|
5962
6032
|
const familyOf2 = (key) => definitions.find((d) => d.key === key)?.family ?? "generic";
|
|
@@ -6007,14 +6077,14 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
|
|
|
6007
6077
|
const confirmed = useConfirmed();
|
|
6008
6078
|
const copy = useCopy();
|
|
6009
6079
|
const notify = useNotify();
|
|
6010
|
-
const [busy, setBusy] = (0,
|
|
6080
|
+
const [busy, setBusy] = (0, import_react28.useState)(false);
|
|
6011
6081
|
const user = item.fields.find((f) => USERNAME_KEYS.test(f.key) && f.handling !== "sealed");
|
|
6012
6082
|
const secret = item.fields.find((f) => f.key === "password" && f.handling === "revealable");
|
|
6013
6083
|
const quick = async (key, label) => {
|
|
6014
6084
|
setBusy(true);
|
|
6015
6085
|
try {
|
|
6016
6086
|
const v = await confirmed(() => port.reveal(item, key));
|
|
6017
|
-
await copy(v, label);
|
|
6087
|
+
await copy(v, label, { secret: key !== user?.key || user.handling !== "visible" });
|
|
6018
6088
|
} catch (e) {
|
|
6019
6089
|
if (!wasCancelled(e)) notify(e instanceof Error ? e.message : `${label} could not be read`, "error");
|
|
6020
6090
|
} finally {
|
|
@@ -6047,7 +6117,7 @@ function ListRow({ item, family, port, on, onSelect, withOwner }) {
|
|
|
6047
6117
|
}
|
|
6048
6118
|
|
|
6049
6119
|
// src/lists/TrashView.tsx
|
|
6050
|
-
var
|
|
6120
|
+
var import_react30 = require("react");
|
|
6051
6121
|
var import_controls24 = require("@ai-matrx/design-system/controls");
|
|
6052
6122
|
|
|
6053
6123
|
// src/lists/logic.ts
|
|
@@ -6120,16 +6190,16 @@ function refusalText(reason) {
|
|
|
6120
6190
|
}
|
|
6121
6191
|
|
|
6122
6192
|
// src/lists/RestorePanel.tsx
|
|
6123
|
-
var
|
|
6193
|
+
var import_react29 = require("react");
|
|
6124
6194
|
var import_controls23 = require("@ai-matrx/design-system/controls");
|
|
6125
6195
|
var import_jsx_runtime28 = require("react/jsx-runtime");
|
|
6126
6196
|
var count = (n, one) => `${n} ${one}${n === 1 ? "" : "s"}`;
|
|
6127
6197
|
function RestorePanel({ lists, item, restore, onClose }) {
|
|
6128
|
-
const [preview, setPreview] = (0,
|
|
6129
|
-
const [error, setError] = (0,
|
|
6130
|
-
const [busy, setBusy] = (0,
|
|
6131
|
-
const [loading, setLoading] = (0,
|
|
6132
|
-
(0,
|
|
6198
|
+
const [preview, setPreview] = (0, import_react29.useState)(null);
|
|
6199
|
+
const [error, setError] = (0, import_react29.useState)(null);
|
|
6200
|
+
const [busy, setBusy] = (0, import_react29.useState)(false);
|
|
6201
|
+
const [loading, setLoading] = (0, import_react29.useState)(Boolean(lists.preview));
|
|
6202
|
+
(0, import_react29.useEffect)(() => {
|
|
6133
6203
|
if (!lists.preview) return;
|
|
6134
6204
|
let live = true;
|
|
6135
6205
|
lists.preview(item).then(
|
|
@@ -6189,10 +6259,10 @@ function RestorePanel({ lists, item, restore, onClose }) {
|
|
|
6189
6259
|
var import_jsx_runtime29 = require("react/jsx-runtime");
|
|
6190
6260
|
function TrashView({ port, deleted, query, header, onChanged }) {
|
|
6191
6261
|
const confirmed = useConfirmed();
|
|
6192
|
-
const [busyId, setBusyId] = (0,
|
|
6193
|
-
const [message2, setMessage] = (0,
|
|
6262
|
+
const [busyId, setBusyId] = (0, import_react30.useState)(null);
|
|
6263
|
+
const [message2, setMessage] = (0, import_react30.useState)(null);
|
|
6194
6264
|
const shown = deleted.filter((i) => matchesQuery2(i, query));
|
|
6195
|
-
const [restoring, setRestoring] = (0,
|
|
6265
|
+
const [restoring, setRestoring] = (0, import_react30.useState)(null);
|
|
6196
6266
|
const restore = async (item, deletionId) => {
|
|
6197
6267
|
setBusyId(item.id);
|
|
6198
6268
|
setMessage(null);
|
|
@@ -6227,15 +6297,15 @@ function TrashView({ port, deleted, query, header, onChanged }) {
|
|
|
6227
6297
|
}
|
|
6228
6298
|
|
|
6229
6299
|
// src/NewItemFlow.tsx
|
|
6230
|
-
var
|
|
6300
|
+
var import_react31 = require("react");
|
|
6231
6301
|
var import_design_system20 = require("@ai-matrx/design-system");
|
|
6232
6302
|
var import_controls25 = require("@ai-matrx/design-system/controls");
|
|
6233
6303
|
var import_jsx_runtime30 = require("react/jsx-runtime");
|
|
6234
6304
|
function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
6235
|
-
const [search, setSearch] = (0,
|
|
6236
|
-
const guess = (0,
|
|
6305
|
+
const [search, setSearch] = (0, import_react31.useState)("");
|
|
6306
|
+
const guess = (0, import_react31.useMemo)(() => inferFromUrl(url, definitions), [url, definitions]);
|
|
6237
6307
|
const common = COMMON_DEFINITION_KEYS.map((k) => definitions.find((d) => d.key === k)).filter((d) => d !== void 0);
|
|
6238
|
-
const matches = (0,
|
|
6308
|
+
const matches = (0, import_react31.useMemo)(() => {
|
|
6239
6309
|
const q = search.trim().toLowerCase();
|
|
6240
6310
|
if (!q) return [];
|
|
6241
6311
|
return definitions.filter((d) => `${d.label} ${d.key} ${d.providerKey ?? ""} ${FAMILY_LABELS[d.family] ?? ""}`.toLowerCase().includes(q)).slice(0, 60);
|
|
@@ -6299,7 +6369,7 @@ function NewItemFlow({ definitions, url, onUrl, onChoose, onCancel }) {
|
|
|
6299
6369
|
}
|
|
6300
6370
|
|
|
6301
6371
|
// src/sharing/SecureLinkPanel.tsx
|
|
6302
|
-
var
|
|
6372
|
+
var import_react32 = require("react");
|
|
6303
6373
|
var import_confirm_opener10 = require("@ai-matrx/kit/confirm-opener");
|
|
6304
6374
|
var import_design_system21 = require("@ai-matrx/design-system");
|
|
6305
6375
|
var import_controls26 = require("@ai-matrx/design-system/controls");
|
|
@@ -6381,20 +6451,20 @@ var import_jsx_runtime31 = require("react/jsx-runtime");
|
|
|
6381
6451
|
function SecureLinkPanel({ item, port, onClose }) {
|
|
6382
6452
|
const sharing = port.sharing;
|
|
6383
6453
|
const { busy, error, notice, run, setNotice } = useAction();
|
|
6384
|
-
const [remedy, setRemedy] = (0,
|
|
6385
|
-
const [options, setOptions] = (0,
|
|
6386
|
-
const [optionsError, setOptionsError] = (0,
|
|
6387
|
-
const [sent, setSent] = (0,
|
|
6388
|
-
const [sentError, setSentError] = (0,
|
|
6389
|
-
const [nonce, setNonce] = (0,
|
|
6390
|
-
const [email, setEmail] = (0,
|
|
6391
|
-
const [phone, setPhone] = (0,
|
|
6392
|
-
const [name, setName] = (0,
|
|
6393
|
-
const [linkBy, setLinkBy] = (0,
|
|
6394
|
-
const [fields, setFields] = (0,
|
|
6395
|
-
const [note, setNote] = (0,
|
|
6396
|
-
const [sameChannelSent, setSameChannelSent] = (0,
|
|
6397
|
-
(0,
|
|
6454
|
+
const [remedy, setRemedy] = (0, import_react32.useState)(null);
|
|
6455
|
+
const [options, setOptions] = (0, import_react32.useState)(null);
|
|
6456
|
+
const [optionsError, setOptionsError] = (0, import_react32.useState)(null);
|
|
6457
|
+
const [sent, setSent] = (0, import_react32.useState)(null);
|
|
6458
|
+
const [sentError, setSentError] = (0, import_react32.useState)(null);
|
|
6459
|
+
const [nonce, setNonce] = (0, import_react32.useState)(0);
|
|
6460
|
+
const [email, setEmail] = (0, import_react32.useState)("");
|
|
6461
|
+
const [phone, setPhone] = (0, import_react32.useState)("");
|
|
6462
|
+
const [name, setName] = (0, import_react32.useState)("");
|
|
6463
|
+
const [linkBy, setLinkBy] = (0, import_react32.useState)("email");
|
|
6464
|
+
const [fields, setFields] = (0, import_react32.useState)([]);
|
|
6465
|
+
const [note, setNote] = (0, import_react32.useState)("");
|
|
6466
|
+
const [sameChannelSent, setSameChannelSent] = (0, import_react32.useState)(false);
|
|
6467
|
+
(0, import_react32.useEffect)(() => {
|
|
6398
6468
|
let live = true;
|
|
6399
6469
|
setOptionsError(null);
|
|
6400
6470
|
sharing.secureLinkOptions(item).then(
|
|
@@ -6409,7 +6479,7 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6409
6479
|
live = false;
|
|
6410
6480
|
};
|
|
6411
6481
|
}, [sharing, item]);
|
|
6412
|
-
(0,
|
|
6482
|
+
(0, import_react32.useEffect)(() => {
|
|
6413
6483
|
const list = sharing.sentSecureLinks;
|
|
6414
6484
|
if (!list) return;
|
|
6415
6485
|
let live = true;
|
|
@@ -6422,9 +6492,9 @@ function SecureLinkPanel({ item, port, onClose }) {
|
|
|
6422
6492
|
live = false;
|
|
6423
6493
|
};
|
|
6424
6494
|
}, [sharing, item, nonce]);
|
|
6425
|
-
const [phoneTyped, setPhoneTyped] = (0,
|
|
6426
|
-
const prefilled = (0,
|
|
6427
|
-
(0,
|
|
6495
|
+
const [phoneTyped, setPhoneTyped] = (0, import_react32.useState)(false);
|
|
6496
|
+
const prefilled = (0, import_react32.useRef)(false);
|
|
6497
|
+
(0, import_react32.useEffect)(() => {
|
|
6428
6498
|
const lookup = sharing.phoneOnFile;
|
|
6429
6499
|
if (!lookup || phoneTyped) return;
|
|
6430
6500
|
const clear = () => {
|
|
@@ -6578,7 +6648,7 @@ function sentMeta(row, options) {
|
|
|
6578
6648
|
}
|
|
6579
6649
|
|
|
6580
6650
|
// src/devices/DevicesPanel.tsx
|
|
6581
|
-
var
|
|
6651
|
+
var import_react33 = require("react");
|
|
6582
6652
|
var import_confirm_opener11 = require("@ai-matrx/kit/confirm-opener");
|
|
6583
6653
|
var import_controls27 = require("@ai-matrx/design-system/controls");
|
|
6584
6654
|
|
|
@@ -6668,10 +6738,10 @@ function ErrorLine2({ text }) {
|
|
|
6668
6738
|
function DevicesPanel({ port, onClose }) {
|
|
6669
6739
|
const confirmed = useConfirmed();
|
|
6670
6740
|
const notify = useNotify();
|
|
6671
|
-
const [devices, setDevices] = (0,
|
|
6672
|
-
const [error, setError] = (0,
|
|
6673
|
-
const [busyId, setBusyId] = (0,
|
|
6674
|
-
const load = (0,
|
|
6741
|
+
const [devices, setDevices] = (0, import_react33.useState)(null);
|
|
6742
|
+
const [error, setError] = (0, import_react33.useState)(null);
|
|
6743
|
+
const [busyId, setBusyId] = (0, import_react33.useState)(null);
|
|
6744
|
+
const load = (0, import_react33.useCallback)(async () => {
|
|
6675
6745
|
setError(null);
|
|
6676
6746
|
try {
|
|
6677
6747
|
setDevices(await port.devices.list());
|
|
@@ -6679,7 +6749,7 @@ function DevicesPanel({ port, onClose }) {
|
|
|
6679
6749
|
setError(messageOf3(e, "Your browsers could not be read."));
|
|
6680
6750
|
}
|
|
6681
6751
|
}, [port]);
|
|
6682
|
-
(0,
|
|
6752
|
+
(0, import_react33.useEffect)(() => {
|
|
6683
6753
|
void load();
|
|
6684
6754
|
}, [load]);
|
|
6685
6755
|
const revoke = async (device) => {
|
|
@@ -6737,11 +6807,11 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6737
6807
|
const where = isMac ? "the Mac app" : "the extension";
|
|
6738
6808
|
const passkeys = port.devices.passkeys;
|
|
6739
6809
|
const here = passkeys?.available() ?? false;
|
|
6740
|
-
const [methods, setMethods] = (0,
|
|
6741
|
-
const [busy, setBusy] = (0,
|
|
6742
|
-
const [error, setError] = (0,
|
|
6743
|
-
const [approvedUntil, setApprovedUntil] = (0,
|
|
6744
|
-
const load = (0,
|
|
6810
|
+
const [methods, setMethods] = (0, import_react33.useState)(null);
|
|
6811
|
+
const [busy, setBusy] = (0, import_react33.useState)(null);
|
|
6812
|
+
const [error, setError] = (0, import_react33.useState)(null);
|
|
6813
|
+
const [approvedUntil, setApprovedUntil] = (0, import_react33.useState)(null);
|
|
6814
|
+
const load = (0, import_react33.useCallback)(async () => {
|
|
6745
6815
|
setError(null);
|
|
6746
6816
|
try {
|
|
6747
6817
|
setMethods(await port.devices.stepUpMethods());
|
|
@@ -6749,7 +6819,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6749
6819
|
setError(messageOf3(e, "Your account could not be checked."));
|
|
6750
6820
|
}
|
|
6751
6821
|
}, [port]);
|
|
6752
|
-
(0,
|
|
6822
|
+
(0, import_react33.useEffect)(() => {
|
|
6753
6823
|
if (key && here) void load();
|
|
6754
6824
|
}, [key, here, load]);
|
|
6755
6825
|
const approve = async () => {
|
|
@@ -6837,7 +6907,7 @@ function ApprovePanel({ port, host, onClose, approvalKey, label, kind = "browser
|
|
|
6837
6907
|
}
|
|
6838
6908
|
|
|
6839
6909
|
// src/native/NativeImportPanel.tsx
|
|
6840
|
-
var
|
|
6910
|
+
var import_react35 = require("react");
|
|
6841
6911
|
var import_confirm_opener12 = require("@ai-matrx/kit/confirm-opener");
|
|
6842
6912
|
var import_controls28 = require("@ai-matrx/design-system/controls");
|
|
6843
6913
|
|
|
@@ -6900,19 +6970,19 @@ async function loadFullPreview(bridge, operationId, current) {
|
|
|
6900
6970
|
}
|
|
6901
6971
|
|
|
6902
6972
|
// src/native/use-native-import.ts
|
|
6903
|
-
var
|
|
6973
|
+
var import_react34 = require("react");
|
|
6904
6974
|
var fail = (e, fallback) => e instanceof Error && e.message ? e.message : fallback;
|
|
6905
6975
|
var RESTART = "Your account changed. The import was stopped; start it again.";
|
|
6906
6976
|
function useNativeImport(bridge, stillAllowed, onImported) {
|
|
6907
|
-
const [screen, setScreen] = (0,
|
|
6908
|
-
const [busy, setBusy] = (0,
|
|
6909
|
-
const generation = (0,
|
|
6910
|
-
const mounted = (0,
|
|
6911
|
-
const op = (0,
|
|
6912
|
-
const last = (0,
|
|
6913
|
-
const timer2 = (0,
|
|
6914
|
-
const polls = (0,
|
|
6915
|
-
const refreshRef = (0,
|
|
6977
|
+
const [screen, setScreen] = (0, import_react34.useState)({ kind: "idle", message: null });
|
|
6978
|
+
const [busy, setBusy] = (0, import_react34.useState)(false);
|
|
6979
|
+
const generation = (0, import_react34.useRef)(0);
|
|
6980
|
+
const mounted = (0, import_react34.useRef)(false);
|
|
6981
|
+
const op = (0, import_react34.useRef)(null);
|
|
6982
|
+
const last = (0, import_react34.useRef)(null);
|
|
6983
|
+
const timer2 = (0, import_react34.useRef)(null);
|
|
6984
|
+
const polls = (0, import_react34.useRef)(0);
|
|
6985
|
+
const refreshRef = (0, import_react34.useRef)(async () => void 0);
|
|
6916
6986
|
const current = (g) => mounted.current && g === generation.current;
|
|
6917
6987
|
const stopPolling = () => {
|
|
6918
6988
|
if (timer2.current !== null) clearTimeout(timer2.current);
|
|
@@ -7081,9 +7151,9 @@ function useNativeImport(bridge, stillAllowed, onImported) {
|
|
|
7081
7151
|
setBusy(false);
|
|
7082
7152
|
setScreen({ kind: "idle", message: null });
|
|
7083
7153
|
};
|
|
7084
|
-
const invalidateRef = (0,
|
|
7154
|
+
const invalidateRef = (0, import_react34.useRef)(invalidate);
|
|
7085
7155
|
invalidateRef.current = invalidate;
|
|
7086
|
-
(0,
|
|
7156
|
+
(0, import_react34.useEffect)(() => {
|
|
7087
7157
|
mounted.current = true;
|
|
7088
7158
|
const off = bridge.subscribe?.(() => {
|
|
7089
7159
|
if (op.current) invalidateRef.current(RESTART);
|
|
@@ -7115,14 +7185,14 @@ function NativeImportPanel({ bridge, readLimits, activeOrganizationId, organizat
|
|
|
7115
7185
|
return /* @__PURE__ */ (0, import_jsx_runtime33.jsx)(Importer, { bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged });
|
|
7116
7186
|
}
|
|
7117
7187
|
function Importer({ bridge, readLimits, activeOrganizationId, organizations, onClose, onChanged }) {
|
|
7118
|
-
const options = (0,
|
|
7119
|
-
const [organizationId, setOrganizationId] = (0,
|
|
7120
|
-
const [limits, setLimits] = (0,
|
|
7121
|
-
const [limitError, setLimitError] = (0,
|
|
7188
|
+
const options = (0, import_react35.useMemo)(() => organizations.map((o) => ({ value: o.id, label: o.name })), [organizations]);
|
|
7189
|
+
const [organizationId, setOrganizationId] = (0, import_react35.useState)(() => organizations.some((o) => o.id === activeOrganizationId) ? activeOrganizationId : organizations[0]?.id ?? "");
|
|
7190
|
+
const [limits, setLimits] = (0, import_react35.useState)(null);
|
|
7191
|
+
const [limitError, setLimitError] = (0, import_react35.useState)(null);
|
|
7122
7192
|
const flow = useNativeImport(bridge, (id) => organizations.some((o) => o.id === id), onChanged);
|
|
7123
7193
|
const { screen, busy } = flow;
|
|
7124
7194
|
const orgName = organizations.find((o) => o.id === organizationId)?.name ?? "this organization";
|
|
7125
|
-
(0,
|
|
7195
|
+
(0, import_react35.useEffect)(() => {
|
|
7126
7196
|
if (!readLimits || !organizationId) return;
|
|
7127
7197
|
let live = true;
|
|
7128
7198
|
setLimits(null);
|
|
@@ -7183,20 +7253,20 @@ function Importer({ bridge, readLimits, activeOrganizationId, organizations, onC
|
|
|
7183
7253
|
}
|
|
7184
7254
|
|
|
7185
7255
|
// src/extension/PageView.tsx
|
|
7186
|
-
var
|
|
7256
|
+
var import_react39 = require("react");
|
|
7187
7257
|
var import_design_system23 = require("@ai-matrx/design-system");
|
|
7188
7258
|
var import_controls32 = require("@ai-matrx/design-system/controls");
|
|
7189
7259
|
|
|
7190
7260
|
// src/extension/CaptureCard.tsx
|
|
7191
|
-
var
|
|
7261
|
+
var import_react36 = require("react");
|
|
7192
7262
|
var import_controls29 = require("@ai-matrx/design-system/controls");
|
|
7193
7263
|
var import_jsx_runtime34 = require("react/jsx-runtime");
|
|
7194
7264
|
var SEARCH_FROM = 4;
|
|
7195
7265
|
function CaptureCard({ capture, onChanged }) {
|
|
7196
|
-
const prompt = (0,
|
|
7266
|
+
const prompt = (0, import_react36.useSyncExternalStore)(capture.subscribe, capture.get, capture.get);
|
|
7197
7267
|
const notify = useNotify();
|
|
7198
|
-
const [busy, setBusy] = (0,
|
|
7199
|
-
const [q, setQ] = (0,
|
|
7268
|
+
const [busy, setBusy] = (0, import_react36.useState)(false);
|
|
7269
|
+
const [q, setQ] = (0, import_react36.useState)("");
|
|
7200
7270
|
if (!prompt) return null;
|
|
7201
7271
|
const decide = async (d) => {
|
|
7202
7272
|
setBusy(true);
|
|
@@ -7252,15 +7322,15 @@ function CaptureCard({ capture, onChanged }) {
|
|
|
7252
7322
|
}
|
|
7253
7323
|
|
|
7254
7324
|
// src/extension/FillSetupCard.tsx
|
|
7255
|
-
var
|
|
7325
|
+
var import_react37 = require("react");
|
|
7256
7326
|
var import_controls30 = require("@ai-matrx/design-system/controls");
|
|
7257
7327
|
var import_jsx_runtime35 = require("react/jsx-runtime");
|
|
7258
7328
|
function FillSetupCard({ fillSetup }) {
|
|
7259
7329
|
const notify = useNotify();
|
|
7260
|
-
const state = (0,
|
|
7261
|
-
const box = (0,
|
|
7262
|
-
const [busy, setBusy] = (0,
|
|
7263
|
-
const [error, setError] = (0,
|
|
7330
|
+
const state = (0, import_react37.useSyncExternalStore)(fillSetup.subscribe, fillSetup.get, fillSetup.get);
|
|
7331
|
+
const box = (0, import_react37.useRef)(null);
|
|
7332
|
+
const [busy, setBusy] = (0, import_react37.useState)(false);
|
|
7333
|
+
const [error, setError] = (0, import_react37.useState)(null);
|
|
7264
7334
|
if (state.status !== "off") return null;
|
|
7265
7335
|
const finish = async (run) => {
|
|
7266
7336
|
setBusy(true);
|
|
@@ -7325,7 +7395,7 @@ function FillSetupCard({ fillSetup }) {
|
|
|
7325
7395
|
}
|
|
7326
7396
|
|
|
7327
7397
|
// src/extension/PageGenerator.tsx
|
|
7328
|
-
var
|
|
7398
|
+
var import_react38 = require("react");
|
|
7329
7399
|
var import_design_system22 = require("@ai-matrx/design-system");
|
|
7330
7400
|
var import_controls31 = require("@ai-matrx/design-system/controls");
|
|
7331
7401
|
var import_jsx_runtime36 = require("react/jsx-runtime");
|
|
@@ -7334,10 +7404,10 @@ function PageGenerator({ fields }) {
|
|
|
7334
7404
|
const limits = useGeneratorLimitsSource();
|
|
7335
7405
|
const copy = useCopy();
|
|
7336
7406
|
const held = useTransientSecret(HOLD_MS);
|
|
7337
|
-
const [open, setOpen] = (0,
|
|
7338
|
-
const [busy, setBusy] = (0,
|
|
7339
|
-
const [targets, setTargets] = (0,
|
|
7340
|
-
const [said, setSaid] = (0,
|
|
7407
|
+
const [open, setOpen] = (0, import_react38.useState)(false);
|
|
7408
|
+
const [busy, setBusy] = (0, import_react38.useState)(false);
|
|
7409
|
+
const [targets, setTargets] = (0, import_react38.useState)([]);
|
|
7410
|
+
const [said, setSaid] = (0, import_react38.useState)(null);
|
|
7341
7411
|
if (!limits) return null;
|
|
7342
7412
|
const say3 = setSaid;
|
|
7343
7413
|
const put = async (targetId, value2) => {
|
|
@@ -7401,8 +7471,8 @@ function PageGenerator({ fields }) {
|
|
|
7401
7471
|
// src/extension/PageView.tsx
|
|
7402
7472
|
var import_jsx_runtime37 = require("react/jsx-runtime");
|
|
7403
7473
|
function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, items, definitions, onOpen, onNewForPage, onBrowse, onChanged, header }) {
|
|
7404
|
-
const [running, setRunning] = (0,
|
|
7405
|
-
const [said, setSaid] = (0,
|
|
7474
|
+
const [running, setRunning] = (0, import_react39.useState)(null);
|
|
7475
|
+
const [said, setSaid] = (0, import_react39.useState)(null);
|
|
7406
7476
|
const site = pageSite(page.url);
|
|
7407
7477
|
const state = page.matchState ?? { status: "ready" };
|
|
7408
7478
|
const fillable = new Set(page.fillableItemIds ?? page.matchingItemIds);
|
|
@@ -7456,7 +7526,7 @@ function PageView({ port, page, fill, capture, fillSetup, newPasswordFields, ite
|
|
|
7456
7526
|
return /* @__PURE__ */ (0, import_jsx_runtime37.jsx)("div", { className: "flex h-full min-h-0 flex-col overflow-y-auto bg-background text-foreground", children: /* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex flex-col gap-3 px-3 pb-4 pt-3", children: [
|
|
7457
7527
|
header,
|
|
7458
7528
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsxs)("div", { className: "flex min-h-7 items-center gap-2 px-1", children: [
|
|
7459
|
-
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(
|
|
7529
|
+
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_design_system23.SiteIcon, { site: page.url, fallback: GlobeGlyph, className: "size-4" }),
|
|
7460
7530
|
/* @__PURE__ */ (0, import_jsx_runtime37.jsx)("span", { className: "min-w-0 flex-1 truncate text-sm font-medium", title: page.url, children: site || "No page open" }),
|
|
7461
7531
|
page.refresh ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(RefreshGlyph, {}), "aria-label": "Check again", onClick: page.refresh }) : null,
|
|
7462
7532
|
onBrowse ? /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(import_controls32.Button, { variant: "quiet", icon: /* @__PURE__ */ (0, import_jsx_runtime37.jsx)(ListGlyph, {}), onClick: onBrowse, children: "All items" }) : null
|
|
@@ -7486,7 +7556,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7486
7556
|
const confirmed = useConfirmed();
|
|
7487
7557
|
const copy = useCopy();
|
|
7488
7558
|
const notify = useNotify();
|
|
7489
|
-
const [reading, setReading] = (0,
|
|
7559
|
+
const [reading, setReading] = (0, import_react39.useState)(false);
|
|
7490
7560
|
const usable = item?.capabilities.canUse ?? false;
|
|
7491
7561
|
const user = usable ? item?.fields.find((f) => USERNAME_KEYS.test(f.key) && f.handling !== "sealed" && f.active) : void 0;
|
|
7492
7562
|
const secret = usable && item?.capabilities.canReveal ? item?.fields.find((f) => f.key === "password" && f.handling === "revealable" && f.active) : void 0;
|
|
@@ -7531,7 +7601,7 @@ function MatchRow({ itemId, item, tag, family, port, busy, running, onOpen, onFi
|
|
|
7531
7601
|
}
|
|
7532
7602
|
|
|
7533
7603
|
// src/Sidebar.tsx
|
|
7534
|
-
var
|
|
7604
|
+
var import_react40 = require("react");
|
|
7535
7605
|
var import_design_system24 = require("@ai-matrx/design-system");
|
|
7536
7606
|
var import_controls33 = require("@ai-matrx/design-system/controls");
|
|
7537
7607
|
var import_jsx_runtime38 = require("react/jsx-runtime");
|
|
@@ -7614,7 +7684,7 @@ function Group({ title, children }) {
|
|
|
7614
7684
|
] });
|
|
7615
7685
|
}
|
|
7616
7686
|
function Sidebar({ vault, choices, onVault, view, allCount, deletedCount, views, hasFavorites, hasRecents, onView, onPanel, nativeProvider, hasNativeImport = false, hasPage = false }) {
|
|
7617
|
-
const [tagsOpen, setTagsOpen] = (0,
|
|
7687
|
+
const [tagsOpen, setTagsOpen] = (0, import_react40.useState)(view.startsWith("tag:"));
|
|
7618
7688
|
return /* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("nav", { "aria-label": "Vault", className: "flex h-full min-h-0 flex-col border-r border-sidebar-border bg-sidebar-background text-sidebar-foreground", children: [
|
|
7619
7689
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsxs)("div", { className: "flex items-center gap-2 px-3 pb-2 pt-3", children: [
|
|
7620
7690
|
/* @__PURE__ */ (0, import_jsx_runtime38.jsx)(SafeGlyph, { className: "size-5 shrink-0 text-primary" }),
|
|
@@ -7674,8 +7744,8 @@ var generatorLimitsFrom = (knobs) => knobs ? async () => {
|
|
|
7674
7744
|
} : void 0;
|
|
7675
7745
|
function ImportWithLimits(props) {
|
|
7676
7746
|
const { knobs, ...rest } = props;
|
|
7677
|
-
const [state, setState] = (0,
|
|
7678
|
-
(0,
|
|
7747
|
+
const [state, setState] = (0, import_react41.useState)(null);
|
|
7748
|
+
(0, import_react41.useEffect)(() => {
|
|
7679
7749
|
if (!knobs) return setState({ error: "Import is not set up for this organization yet." });
|
|
7680
7750
|
knobs().then(
|
|
7681
7751
|
(r) => {
|
|
@@ -7692,31 +7762,55 @@ function ImportWithLimits(props) {
|
|
|
7692
7762
|
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Panel, { title: "Import", onClose: rest.onClose, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Empty, { children: state ? state.error : "Reading this organization\u2019s import settings\u2026" }) });
|
|
7693
7763
|
}
|
|
7694
7764
|
function VaultApp(props) {
|
|
7695
|
-
|
|
7765
|
+
const lock = props.host?.lock;
|
|
7766
|
+
const locked = useLocked(lock);
|
|
7767
|
+
const port = (0, import_react41.useMemo)(() => lock ? guardPort(props.port, () => lock.locked()) : props.port, [props.port, lock]);
|
|
7768
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "relative h-full min-h-0 w-full", children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(NoticeProvider, { notify: props.notify, children: lock && locked ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LockedScreen, { lock }) : /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ClipboardProvider, { clipboard: props.host?.clipboard, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(RevealSecondsProvider, { seconds: props.host?.revealSeconds, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(IdentityGate, { identity: props.host?.identity, children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(GeneratorLimitsProvider, { resolve: generatorLimitsFrom(props.host?.knobs), children: /* @__PURE__ */ (0, import_jsx_runtime39.jsx)(Workspace, { ...props, port }) }) }) }) }) }) });
|
|
7769
|
+
}
|
|
7770
|
+
function LockedScreen({ lock }) {
|
|
7771
|
+
const [busy, setBusy] = (0, import_react41.useState)(false);
|
|
7772
|
+
const [error, setError] = (0, import_react41.useState)(null);
|
|
7773
|
+
const unlock = async () => {
|
|
7774
|
+
setBusy(true);
|
|
7775
|
+
setError(null);
|
|
7776
|
+
try {
|
|
7777
|
+
await lock.unlock();
|
|
7778
|
+
} catch (e) {
|
|
7779
|
+
setError(e instanceof Error && e.message ? e.message : "The vault stayed locked.");
|
|
7780
|
+
} finally {
|
|
7781
|
+
setBusy(false);
|
|
7782
|
+
}
|
|
7783
|
+
};
|
|
7784
|
+
return /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)("div", { role: "region", "aria-label": "Vault locked", className: "flex h-full min-h-0 flex-col items-center justify-center gap-3 p-6 text-center", children: [
|
|
7785
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LockGlyph, { className: "size-8 text-muted-foreground" }),
|
|
7786
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { className: "text-base font-medium text-foreground", children: "Vault locked" }),
|
|
7787
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(import_controls34.Button, { variant: "primary", disabled: busy, onClick: () => void unlock(), children: lock.unlockLabel ?? "Unlock" }),
|
|
7788
|
+
error ? /* @__PURE__ */ (0, import_jsx_runtime39.jsx)("div", { role: "alert", className: "max-w-sm text-sm text-destructive", children: error }) : null
|
|
7789
|
+
] });
|
|
7696
7790
|
}
|
|
7697
7791
|
function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocationChange }) {
|
|
7698
|
-
const rootRef = (0,
|
|
7792
|
+
const rootRef = (0, import_react41.useRef)(null);
|
|
7699
7793
|
const width = useElementWidth(rootRef);
|
|
7700
7794
|
const mode = layout !== "auto" ? layout : width >= FULL_AT ? "full" : width >= SPLIT_AT ? "split" : "stack";
|
|
7701
7795
|
const notify = useNotify();
|
|
7702
|
-
const [snap, setSnap] = (0,
|
|
7703
|
-
const [items, setItems] = (0,
|
|
7704
|
-
const [deleted, setDeleted] = (0,
|
|
7705
|
-
const [favorites, setFavorites] = (0,
|
|
7706
|
-
const [recents, setRecents] = (0,
|
|
7707
|
-
const [error, setError] = (0,
|
|
7708
|
-
const [inner, setInner] = (0,
|
|
7796
|
+
const [snap, setSnap] = (0, import_react41.useState)(null);
|
|
7797
|
+
const [items, setItems] = (0, import_react41.useState)([]);
|
|
7798
|
+
const [deleted, setDeleted] = (0, import_react41.useState)([]);
|
|
7799
|
+
const [favorites, setFavorites] = (0, import_react41.useState)(null);
|
|
7800
|
+
const [recents, setRecents] = (0, import_react41.useState)(null);
|
|
7801
|
+
const [error, setError] = (0, import_react41.useState)(null);
|
|
7802
|
+
const [inner, setInner] = (0, import_react41.useState)(DEFAULT_LOCATION);
|
|
7709
7803
|
const loc = location ?? inner;
|
|
7710
|
-
const dirty = (0,
|
|
7711
|
-
const [notice, setNotice] = (0,
|
|
7712
|
-
const move = (0,
|
|
7804
|
+
const dirty = (0, import_react41.useRef)(false);
|
|
7805
|
+
const [notice, setNotice] = (0, import_react41.useState)(null);
|
|
7806
|
+
const move = (0, import_react41.useCallback)(
|
|
7713
7807
|
(next, how) => {
|
|
7714
7808
|
if (!location) setInner(next);
|
|
7715
7809
|
onLocationChange?.(next, how);
|
|
7716
7810
|
},
|
|
7717
7811
|
[location, onLocationChange]
|
|
7718
7812
|
);
|
|
7719
|
-
const go = (0,
|
|
7813
|
+
const go = (0, import_react41.useCallback)(
|
|
7720
7814
|
(patch, how = "push") => {
|
|
7721
7815
|
const leaving = patch.itemId !== void 0 || patch.mode !== void 0 || patch.vault !== void 0 || patch.view !== void 0;
|
|
7722
7816
|
const next = { ...loc, ...patch };
|
|
@@ -7735,9 +7829,9 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
7735
7829
|
},
|
|
7736
7830
|
[loc, move]
|
|
7737
7831
|
);
|
|
7738
|
-
const knobsRef = (0,
|
|
7832
|
+
const knobsRef = (0, import_react41.useRef)(host.knobs);
|
|
7739
7833
|
knobsRef.current = host.knobs;
|
|
7740
|
-
const load = (0,
|
|
7834
|
+
const load = (0, import_react41.useCallback)(() => {
|
|
7741
7835
|
setError(null);
|
|
7742
7836
|
port.load().then((s) => {
|
|
7743
7837
|
setSnap(s);
|
|
@@ -7752,17 +7846,17 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
7752
7846
|
knobsRef.current?.().catch(() => void 0);
|
|
7753
7847
|
port.lists.recents?.list().then(setRecents, () => void 0);
|
|
7754
7848
|
}, [port]);
|
|
7755
|
-
(0,
|
|
7756
|
-
(0,
|
|
7849
|
+
(0, import_react41.useEffect)(load, [load]);
|
|
7850
|
+
(0, import_react41.useEffect)(() => {
|
|
7757
7851
|
if (!loc.itemId || !port.lists.recents) return;
|
|
7758
7852
|
const id = loc.itemId;
|
|
7759
7853
|
port.lists.recents.record(id).then(() => setRecents((r) => [id, ...(r ?? []).filter((x) => x !== id)]), () => void 0);
|
|
7760
7854
|
}, [loc.itemId, port]);
|
|
7761
7855
|
const orgs = snap?.organizations ?? [];
|
|
7762
7856
|
const definitions = snap?.definitions ?? [];
|
|
7763
|
-
const inThisVault = (0,
|
|
7764
|
-
const views = (0,
|
|
7765
|
-
const visible = (0,
|
|
7857
|
+
const inThisVault = (0, import_react41.useMemo)(() => items.filter((i) => inVault(i, loc.vault)), [items, loc.vault]);
|
|
7858
|
+
const views = (0, import_react41.useMemo)(() => buildViews(inThisVault, definitions, favorites, recents), [inThisVault, definitions, favorites, recents]);
|
|
7859
|
+
const visible = (0, import_react41.useMemo)(() => {
|
|
7766
7860
|
const filtered = inThisVault.filter((i) => {
|
|
7767
7861
|
if (!matchesQuery(i, loc.q)) return false;
|
|
7768
7862
|
if (loc.view === "favorites") return favorites?.has(i.id) ?? false;
|
|
@@ -7773,8 +7867,8 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
7773
7867
|
if (loc.view === "recent" && recents) return [...filtered].sort((a, b) => recents.indexOf(a.id) - recents.indexOf(b.id));
|
|
7774
7868
|
return sortItems(filtered, loc.sort);
|
|
7775
7869
|
}, [inThisVault, loc.view, loc.q, loc.sort, favorites, recents, definitions]);
|
|
7776
|
-
const choices = (0,
|
|
7777
|
-
const matchingIds = (0,
|
|
7870
|
+
const choices = (0, import_react41.useMemo)(() => vaultChoices(items, orgs, loc.vault), [items, orgs, loc.vault]);
|
|
7871
|
+
const matchingIds = (0, import_react41.useMemo)(() => host.page ? new Set(host.page.matchingItemIds) : void 0, [host.page]);
|
|
7778
7872
|
const selected = loc.itemId ? items.find((i) => i.id === loc.itemId) ?? null : null;
|
|
7779
7873
|
const replaceItem = (next) => setItems((cur) => cur.some((i) => i.id === next.id) ? cur.map((i) => i.id === next.id ? next : i) : [...cur, next]);
|
|
7780
7874
|
const toggleFavorite = (id) => {
|
|
@@ -7845,6 +7939,10 @@ function Workspace({ port, host = NO_HOST, layout = "auto", location, onLocation
|
|
|
7845
7939
|
host.nativeProvider && host.nativeProvider.status !== "unavailable" ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_design_system25.DropdownMenuItem, { onSelect: host.nativeProvider.openSetup, children: [
|
|
7846
7940
|
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(ShieldGlyph, { className: "size-4" }),
|
|
7847
7941
|
"System AutoFill"
|
|
7942
|
+
] }) : null,
|
|
7943
|
+
host.lock?.lock ? /* @__PURE__ */ (0, import_jsx_runtime39.jsxs)(import_design_system25.DropdownMenuItem, { onSelect: () => void host.lock?.lock?.(), children: [
|
|
7944
|
+
/* @__PURE__ */ (0, import_jsx_runtime39.jsx)(LockGlyph, { className: "size-4" }),
|
|
7945
|
+
"Lock"
|
|
7848
7946
|
] }) : null
|
|
7849
7947
|
] })
|
|
7850
7948
|
] })
|