@ai-matrx/vault 0.1.38 → 0.1.40

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 CHANGED
@@ -1,28 +1,25 @@
1
1
  # Changelog
2
2
 
3
+ ## 0.1.40
4
+
5
+ UNVERIFIED: this release has no Unreleased entry and the source comparison could not be made (the caller supplied no source comparison). Whether source changed is unknown; consumer action is unknown.
6
+ Check the package's gitHead on npm against this version's gitHead: `git diff <previous gitHead> <this gitHead> -- apps/shared/vault/src`.
7
+
8
+ ## 0.1.39
9
+
10
+ - **Organization vaults never read as empty by mistake** (2026-10-23): a 404 from `GET /vault/organization-items` still falls back to one read per organization, but now says so once per port (new `ApiVaultPortOptions.onHostProblem(message, detail)`; without it, `console.warn`); an organization the server refused, names unavailable or leaves out is listed under `unavailable`, never shown as an empty vault; the camera note in Add authenticator is one line of 60 characters or fewer ("No camera. Paste the key or choose a QR image."). Proof: `src/organization-items-load.test.ts`, `src/first-code-closes.test.tsx`, `src/review-0-1-36.test.tsx`, `src/review-0-1-37.test.tsx`. Consumer action: needs `@ai-matrx/design-system` with the Select hint that never truncates (the release train publishes both); a host may pass `onHostProblem` to forward it to its error capture; nothing else.
11
+
12
+ ## 0.1.38
13
+
14
+ - **Organization vaults never read as empty by mistake** (2026-10-23): a 404 from `GET /vault/organization-items` still falls back to one read per organization, but now says so once per port (new `ApiVaultPortOptions.onHostProblem(message, detail)`; without it, `console.warn`); an organization the server refused, names unavailable or leaves out is listed under `unavailable`, never shown as an empty vault; the camera note in Add authenticator is one line of 60 characters or fewer ("No camera. Paste the key or choose a QR image."). Proof: `src/organization-items-load.test.ts`, `src/first-code-closes.test.tsx`, `src/review-0-1-36.test.tsx`, `src/review-0-1-37.test.tsx`. Consumer action: needs `@ai-matrx/design-system` with the Select hint that never truncates (the release train publishes both); a host may pass `onHostProblem` to forward it to its error capture; nothing else.
15
+
3
16
  ## 0.1.38
4
17
 
5
18
  - **Website vault walk fixes** (2026-10-23): a row with an authenticator copies its one-time code from the hover quick actions ("One-time code copied"); "Add authenticator" shows the setup-key box first and starts the camera by itself only when the device has one, with the preview and any camera failure UNDER the box as a small note (no window over it; `hasCameraDevice()` in `authenticator/qr.ts`, `QrScanInline` replaces `QrScanPanel`); the first-code window closes when the person moves to another view, item, edit or panel (`useShownUntilMove`); the Vault switcher, Move to and Copy to list organizations recently used and non-empty first, then by name (`orderOrganizations`), tell same-named ones apart by short id (`organizationHints`) and show a search from `vault.organization_search_at` (new knob, default 8, read through `host.knobs`; `host.organizationSearchAt` overrides); after "Copy made in …" the panel offers Open copy (`ItemPanelProps.onOpenItem`); the load reads every organization vault in ONE request (`GET /vault/organization-items`) instead of one per organization, own items still first. Proof: `src/review-0-1-37.test.tsx`. Consumer action: needs `@ai-matrx/api` with `account.organizationItems` and `@ai-matrx/design-system` with Select `hint`/`searchAt` (the release train publishes all three); nothing else.
6
19
 
7
20
  ## 0.1.37
8
21
 
9
- SOURCE CHANGED WITH NO RELEASE NOTE. This release shipped source changes that nobody described in an Unreleased entry,
10
- so they may include breaking API changes. Consumer action is UNKNOWN: read the diff before upgrading.
11
- Diff: `git diff de2b958734 f00b99c3df -- apps/shared/vault/src`
12
-
13
- Changed shipped source files (12):
14
- - `apps/shared/vault/src/ItemList.tsx`
15
- - `apps/shared/vault/src/Sidebar.tsx`
16
- - `apps/shared/vault/src/VaultApp.tsx`
17
- - `apps/shared/vault/src/area-props.ts`
18
- - `apps/shared/vault/src/authenticator/Setup.tsx`
19
- - `apps/shared/vault/src/authenticator/qr.ts`
20
- - `apps/shared/vault/src/knobs.ts`
21
- - `apps/shared/vault/src/organizations.ts`
22
- - `apps/shared/vault/src/port.ts`
23
- - `apps/shared/vault/src/sharing/MovePanel.tsx`
24
- - `apps/shared/vault/src/sharing/logic.ts`
25
- - `apps/shared/vault/src/shown-until-move.ts`
22
+ - **Website vault walk fixes, items 7-11** (2026-10-23): a row with an authenticator copies its one-time code from the hover quick actions; "Add authenticator" shows the setup-key box first and starts the camera only when the device has one (`hasCameraDevice()`); the first-code window closes when the person moves to another view, item, edit or panel (`useShownUntilMove`); the Vault switcher, Move to and Copy to list recently used and non-empty organizations first, then by name, with short ids for same-named ones and a search from `vault.organization_search_at` (`orderOrganizations`, `organizationHints`, `ORGANIZATION_SEARCH_AT_KNOB`); after "Copy made in ..." the panel offers Open copy (`ItemPanelProps.onOpenItem`). Proof: `src/review-0-1-37.test.tsx`. Consumer action: none.
26
23
 
27
24
  ## 0.1.36
28
25
 
package/dist/index.cjs CHANGED
@@ -1928,6 +1928,11 @@ function useCanScan() {
1928
1928
  }, []);
1929
1929
  return ok;
1930
1930
  }
1931
+ var CAMERA_NOTES = {
1932
+ blocked: "Camera blocked. Paste the key or choose a QR image.",
1933
+ missing: "No camera. Paste the key or choose a QR image.",
1934
+ failed: "Camera did not start. Paste the key or choose a QR image."
1935
+ };
1931
1936
  function QrScanInline({ onResult, onClose }) {
1932
1937
  const video = (0, import_react10.useRef)(null);
1933
1938
  const [error, setError] = (0, import_react10.useState)(null);
@@ -1973,7 +1978,7 @@ function QrScanInline({ onResult, onClose }) {
1973
1978
  }).catch((e) => {
1974
1979
  if (!live) return;
1975
1980
  const name = e?.name;
1976
- setError(name === "NotAllowedError" ? "Camera access was not allowed." : name === "NotFoundError" ? "No camera found." : "The camera could not start.");
1981
+ setError(name === "NotAllowedError" ? CAMERA_NOTES.blocked : name === "NotFoundError" ? CAMERA_NOTES.missing : CAMERA_NOTES.failed);
1977
1982
  });
1978
1983
  return () => {
1979
1984
  live = false;
@@ -1983,10 +1988,7 @@ function QrScanInline({ onResult, onClose }) {
1983
1988
  if (error) {
1984
1989
  return /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("p", { className: "flex items-center gap-2 px-1 pt-1 text-xs text-muted-foreground", role: "status", "data-camera-note": "", children: [
1985
1990
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(CameraGlyph, { className: "size-3.5 shrink-0", "aria-hidden": true }),
1986
- /* @__PURE__ */ (0, import_jsx_runtime10.jsxs)("span", { className: "min-w-0 flex-1 truncate", children: [
1987
- error,
1988
- " Paste the setup key or choose a QR image."
1989
- ] }),
1991
+ /* @__PURE__ */ (0, import_jsx_runtime10.jsx)("span", { className: "min-w-0 flex-1 truncate", children: error }),
1990
1992
  /* @__PURE__ */ (0, import_jsx_runtime10.jsx)(import_controls6.Button, { variant: "quiet", onClick: onClose, children: "Dismiss" })
1991
1993
  ] });
1992
1994
  }
@@ -10025,6 +10027,13 @@ async function retrying(run, tries = 3) {
10025
10027
  }
10026
10028
  function createApiVaultPort(hostApi, options = {}) {
10027
10029
  const api = withServerReasons(hostApi);
10030
+ let problemTold = false;
10031
+ const hostProblem = (message2, detail) => {
10032
+ if (problemTold) return;
10033
+ problemTold = true;
10034
+ if (options.onHostProblem) options.onHostProblem(message2, detail);
10035
+ else console.warn(`[vault] ${message2}`, detail);
10036
+ };
10028
10037
  let defs = /* @__PURE__ */ new Map();
10029
10038
  let auth = /* @__PURE__ */ new Map();
10030
10039
  let orgs = [];
@@ -10124,7 +10133,10 @@ function createApiVaultPort(hostApi, options = {}) {
10124
10133
  const one = await orgItemsP.then(
10125
10134
  (r) => r,
10126
10135
  (e) => {
10127
- if (e?.status === 404) return null;
10136
+ if (e?.status === 404) {
10137
+ hostProblem("GET /vault/organization-items answered 404; reading each organization vault separately", e);
10138
+ return null;
10139
+ }
10128
10140
  return "failed";
10129
10141
  }
10130
10142
  );
@@ -10132,8 +10144,8 @@ function createApiVaultPort(hostApi, options = {}) {
10132
10144
  const byOrg = one === "failed" ? /* @__PURE__ */ new Map() : new Map(one.views.map((v) => [v.organization_id, v.items]));
10133
10145
  const failed = one === "failed" ? new Set(orgs.map((o) => o.id)) : new Set(one.unavailable);
10134
10146
  const settled = orgs.map((o, i) => {
10135
- if (failed.has(o.id)) return Promise.reject(new Error(`${o.name} is unavailable`));
10136
- const items = byOrg.get(o.id) ?? [];
10147
+ const items = byOrg.get(o.id);
10148
+ if (failed.has(o.id) || items === void 0) return Promise.reject(new Error(`${o.name} is unavailable`));
10137
10149
  raw.orgLists[i] = { items, count: items.length };
10138
10150
  return Promise.resolve(raw.orgLists[i]);
10139
10151
  });