@peers-app/peers-ui 0.25.2 → 0.25.3

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.
Files changed (177) hide show
  1. package/README.md +2 -1
  2. package/dist/components/markdown-editor/mention-node.d.ts +4 -0
  3. package/dist/components/markdown-editor/mention-node.js +4 -1
  4. package/dist/components/responsive-section-nav.d.ts +34 -0
  5. package/dist/components/responsive-section-nav.js +19 -0
  6. package/dist/components/responsive-section-nav.test.d.ts +1 -0
  7. package/dist/components/responsive-section-nav.test.js +45 -0
  8. package/dist/components/router.d.ts +2 -3
  9. package/dist/components/router.js +6 -9
  10. package/dist/globals-hash.test.d.ts +1 -0
  11. package/dist/globals-hash.test.js +16 -0
  12. package/dist/globals.d.ts +19 -0
  13. package/dist/globals.js +51 -12
  14. package/dist/hooks/use-host-contract.d.ts +18 -0
  15. package/dist/hooks/use-host-contract.js +53 -0
  16. package/dist/index.d.ts +1 -0
  17. package/dist/index.js +1 -0
  18. package/dist/peers-services-registration.d.ts +1 -5
  19. package/dist/peers-services-registration.js +6 -16
  20. package/dist/root-layout/root-layout-host.js +7 -4
  21. package/dist/root-layout/root-layout-host.test.js +3 -6
  22. package/dist/screens/account/account-screen.d.ts +1 -0
  23. package/dist/screens/account/account-screen.js +29 -53
  24. package/dist/screens/account/account-screen.test.d.ts +1 -0
  25. package/dist/screens/account/account-screen.test.js +47 -0
  26. package/dist/screens/contacts/contact-details.js +2 -23
  27. package/dist/screens/contacts/contact-list.d.ts +24 -1
  28. package/dist/screens/contacts/contact-list.js +128 -143
  29. package/dist/screens/contacts/contact-list.test.d.ts +1 -0
  30. package/dist/screens/contacts/contact-list.test.js +48 -0
  31. package/dist/screens/contacts/index.d.ts +0 -2
  32. package/dist/screens/contacts/index.js +0 -3
  33. package/dist/screens/device-pairing/device-pairing.js +17 -16
  34. package/dist/screens/device-pairing/device-pairing.test.js +4 -9
  35. package/dist/screens/device-pairing/identity-ipc.d.ts +11 -0
  36. package/dist/screens/device-pairing/identity-ipc.js +20 -0
  37. package/dist/screens/device-pairing/use-device-pairing-state.d.ts +2 -2
  38. package/dist/screens/device-pairing/use-device-pairing-state.js +7 -25
  39. package/dist/screens/devices/devices-list.d.ts +18 -0
  40. package/dist/screens/devices/devices-list.js +173 -0
  41. package/dist/screens/devices/devices-list.test.d.ts +1 -0
  42. package/dist/screens/devices/devices-list.test.js +53 -0
  43. package/dist/screens/devices/index.d.ts +1 -0
  44. package/dist/screens/devices/index.js +5 -0
  45. package/dist/screens/groups/group-details.d.ts +1 -0
  46. package/dist/screens/groups/group-details.js +4 -63
  47. package/dist/screens/groups/group-invite-panel.js +2 -2
  48. package/dist/screens/groups/group-list.d.ts +18 -1
  49. package/dist/screens/groups/group-list.js +107 -136
  50. package/dist/screens/groups/group-list.test.d.ts +1 -0
  51. package/dist/screens/groups/group-list.test.js +38 -0
  52. package/dist/screens/groups/group-members.d.ts +1 -0
  53. package/dist/screens/groups/group-members.js +2 -1
  54. package/dist/screens/groups/index.d.ts +0 -3
  55. package/dist/screens/groups/index.js +0 -4
  56. package/dist/screens/identity/identity-routes.d.ts +107 -0
  57. package/dist/screens/identity/identity-routes.js +245 -0
  58. package/dist/screens/identity/identity-routes.test.d.ts +1 -0
  59. package/dist/screens/identity/identity-routes.test.js +51 -0
  60. package/dist/screens/identity/identity-screen.d.ts +9 -0
  61. package/dist/screens/identity/identity-screen.js +143 -0
  62. package/dist/screens/identity/identity-screen.test.d.ts +1 -0
  63. package/dist/screens/identity/identity-screen.test.js +103 -0
  64. package/dist/screens/identity/index.d.ts +2 -0
  65. package/dist/screens/identity/index.js +6 -0
  66. package/dist/screens/identity/invite-contact-panel.d.ts +4 -0
  67. package/dist/screens/identity/invite-contact-panel.js +30 -0
  68. package/dist/screens/identity/profile-invite.d.ts +7 -0
  69. package/dist/screens/identity/profile-invite.js +62 -0
  70. package/dist/screens/invites/accept-invite.js +1 -1
  71. package/dist/screens/invites/activity-view.d.ts +24 -0
  72. package/dist/screens/invites/activity-view.js +64 -0
  73. package/dist/screens/invites/activity-view.test.d.ts +1 -0
  74. package/dist/screens/invites/activity-view.test.js +108 -0
  75. package/dist/screens/invites/index.d.ts +1 -2
  76. package/dist/screens/invites/index.js +1 -3
  77. package/dist/screens/invites/invite-capture.d.ts +0 -2
  78. package/dist/screens/invites/invite-capture.js +1 -3
  79. package/dist/screens/invites/invite-classify.test.d.ts +1 -0
  80. package/dist/screens/invites/invite-classify.test.js +98 -0
  81. package/dist/screens/invites/invites-ipc.d.ts +1 -1
  82. package/dist/screens/invites/invites-ipc.js +5 -45
  83. package/dist/screens/invites/pending-invites-list.d.ts +35 -16
  84. package/dist/screens/invites/pending-invites-list.js +69 -30
  85. package/dist/screens/network-viewer/network-viewer-ipc.js +4 -59
  86. package/dist/screens/search/global-search.d.ts +1 -0
  87. package/dist/screens/search/global-search.js +2 -1
  88. package/dist/screens/settings/settings-page.js +25 -58
  89. package/dist/screens/setup-user.js +5 -5
  90. package/dist/screens/tools/tool-access-ipc.d.ts +2 -0
  91. package/dist/screens/tools/tool-access-ipc.js +8 -55
  92. package/dist/screens/welcome-modal.js +3 -2
  93. package/dist/system-apps/identity.app.d.ts +3 -0
  94. package/dist/system-apps/identity.app.js +10 -0
  95. package/dist/system-apps/index.d.ts +1 -4
  96. package/dist/system-apps/index.js +5 -17
  97. package/dist/tabs-layout/network-status-indicator.js +10 -3
  98. package/dist/tabs-layout/network-status-indicator.test.js +15 -0
  99. package/dist/tabs-layout/tabs-layout.js +3 -1
  100. package/dist/tabs-layout/tabs-state.d.ts +79 -1
  101. package/dist/tabs-layout/tabs-state.js +256 -79
  102. package/dist/tabs-layout/tabs-state.test.d.ts +1 -0
  103. package/dist/tabs-layout/tabs-state.test.js +110 -0
  104. package/package.json +3 -3
  105. package/src/components/markdown-editor/mention-node.ts +5 -1
  106. package/src/components/responsive-section-nav.test.tsx +88 -0
  107. package/src/components/responsive-section-nav.tsx +92 -0
  108. package/src/components/router.tsx +6 -9
  109. package/src/globals-hash.test.ts +19 -0
  110. package/src/globals.tsx +53 -13
  111. package/src/hooks/use-host-contract.ts +75 -0
  112. package/src/index.tsx +1 -0
  113. package/src/peers-services-registration.ts +6 -17
  114. package/src/root-layout/root-layout-host.test.tsx +4 -7
  115. package/src/root-layout/root-layout-host.tsx +9 -11
  116. package/src/screens/account/account-screen.test.tsx +61 -0
  117. package/src/screens/account/account-screen.tsx +116 -95
  118. package/src/screens/contacts/contact-details.tsx +4 -26
  119. package/src/screens/contacts/contact-list.test.tsx +59 -0
  120. package/src/screens/contacts/contact-list.tsx +246 -260
  121. package/src/screens/contacts/index.ts +0 -4
  122. package/src/screens/device-pairing/device-pairing.test.tsx +7 -9
  123. package/src/screens/device-pairing/device-pairing.tsx +19 -23
  124. package/src/screens/device-pairing/identity-ipc.ts +25 -0
  125. package/src/screens/device-pairing/use-device-pairing-state.ts +10 -33
  126. package/src/screens/devices/devices-list.test.tsx +68 -0
  127. package/src/screens/devices/devices-list.tsx +361 -0
  128. package/src/screens/devices/index.ts +1 -0
  129. package/src/screens/groups/group-details.tsx +8 -142
  130. package/src/screens/groups/group-invite-panel.tsx +2 -7
  131. package/src/screens/groups/group-list.test.tsx +44 -0
  132. package/src/screens/groups/group-list.tsx +227 -288
  133. package/src/screens/groups/group-members.tsx +3 -2
  134. package/src/screens/groups/index.ts +0 -5
  135. package/src/screens/identity/identity-routes.test.ts +70 -0
  136. package/src/screens/identity/identity-routes.ts +301 -0
  137. package/src/screens/identity/identity-screen.test.tsx +138 -0
  138. package/src/screens/identity/identity-screen.tsx +282 -0
  139. package/src/screens/identity/index.ts +2 -0
  140. package/src/screens/identity/invite-contact-panel.tsx +45 -0
  141. package/src/screens/identity/profile-invite.tsx +93 -0
  142. package/src/screens/invites/accept-invite.tsx +1 -1
  143. package/src/screens/invites/activity-view.test.tsx +127 -0
  144. package/src/screens/invites/activity-view.tsx +162 -0
  145. package/src/screens/invites/index.ts +1 -4
  146. package/src/screens/invites/invite-capture.ts +0 -3
  147. package/src/screens/invites/invite-classify.test.ts +110 -0
  148. package/src/screens/invites/invites-ipc.ts +6 -55
  149. package/src/screens/invites/pending-invites-list.tsx +85 -61
  150. package/src/screens/network-viewer/network-viewer-ipc.ts +8 -82
  151. package/src/screens/search/global-search.tsx +2 -1
  152. package/src/screens/settings/settings-page.tsx +53 -126
  153. package/src/screens/setup-user.tsx +5 -6
  154. package/src/screens/tools/tool-access-ipc.ts +13 -74
  155. package/src/screens/welcome-modal.tsx +3 -3
  156. package/src/system-apps/identity.app.ts +9 -0
  157. package/src/system-apps/index.ts +3 -12
  158. package/src/tabs-layout/network-status-indicator.test.tsx +22 -0
  159. package/src/tabs-layout/network-status-indicator.tsx +31 -0
  160. package/src/tabs-layout/tabs-layout.tsx +7 -1
  161. package/src/tabs-layout/tabs-state.test.ts +152 -0
  162. package/src/tabs-layout/tabs-state.ts +300 -83
  163. package/dist/screens/invites/invites-screen.d.ts +0 -9
  164. package/dist/screens/invites/invites-screen.js +0 -36
  165. package/dist/system-apps/account.app.d.ts +0 -2
  166. package/dist/system-apps/account.app.js +0 -8
  167. package/dist/system-apps/contacts.app.d.ts +0 -2
  168. package/dist/system-apps/contacts.app.js +0 -9
  169. package/dist/system-apps/groups.app.d.ts +0 -2
  170. package/dist/system-apps/groups.app.js +0 -9
  171. package/dist/system-apps/invites.app.d.ts +0 -2
  172. package/dist/system-apps/invites.app.js +0 -9
  173. package/src/screens/invites/invites-screen.tsx +0 -78
  174. package/src/system-apps/account.app.ts +0 -7
  175. package/src/system-apps/contacts.app.ts +0 -8
  176. package/src/system-apps/groups.app.ts +0 -8
  177. package/src/system-apps/invites.app.ts +0 -8
@@ -2,14 +2,21 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.useInviteRows = useInviteRows;
4
4
  exports.describeInviteRow = describeInviteRow;
5
- exports.PendingInvitesList = PendingInvitesList;
5
+ exports.classifyInvite = classifyInvite;
6
+ exports.actionsForInvite = actionsForInvite;
7
+ exports.InviteRow = InviteRow;
6
8
  const jsx_runtime_1 = require("react/jsx-runtime");
7
9
  const peers_sdk_1 = require("@peers-app/peers-sdk");
8
10
  const react_1 = require("react");
9
11
  const invites_ipc_1 = require("./invites-ipc");
10
- /** Subscribe to the personal `Invites` table and return rows matching the filter, newest first. */
12
+ /**
13
+ * Subscribe to the personal `Invites` table.
14
+ *
15
+ * @param filter Type, group, and statuses to include. Statuses default to pending.
16
+ * @returns Matching rows and whether any non-pending row exists, or `undefined` while loading.
17
+ */
11
18
  function useInviteRows(filter) {
12
- const [rows, setRows] = (0, react_1.useState)(undefined);
19
+ const [query, setQuery] = (0, react_1.useState)(undefined);
13
20
  const statuses = filter.statuses ?? ["pending"];
14
21
  const statusKey = statuses.join(",");
15
22
  const refresh = (0, react_1.useCallback)(async () => {
@@ -20,9 +27,12 @@ function useInviteRows(filter) {
20
27
  ...(filter.groupId ? { groupId: filter.groupId } : {}),
21
28
  });
22
29
  const wanted = new Set(statusKey.split(","));
23
- setRows(all
24
- .filter((row) => wanted.has(row.status))
25
- .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()));
30
+ setQuery({
31
+ rows: all
32
+ .filter((row) => wanted.has(row.status))
33
+ .sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime()),
34
+ hasHistory: all.some((row) => row.status !== "pending"),
35
+ });
26
36
  }, [filter.type, filter.groupId, statusKey]);
27
37
  (0, react_1.useEffect)(() => {
28
38
  let disposed = false;
@@ -42,7 +52,7 @@ function useInviteRows(filter) {
42
52
  dispose?.();
43
53
  };
44
54
  }, [refresh]);
45
- return rows;
55
+ return query;
46
56
  }
47
57
  function counterpartLabel(row) {
48
58
  return row.counterpart?.displayName || row.counterpart?.userId || "Someone";
@@ -52,8 +62,20 @@ function describeInviteRow(row) {
52
62
  const who = counterpartLabel(row);
53
63
  const role = row.role !== undefined ? (0, peers_sdk_1.getRoleLabel)(row.role) : undefined;
54
64
  const group = row.groupName ?? "a group";
65
+ if (row.type === "device") {
66
+ return {
67
+ title: row.direction === "in" ? `Device request from ${who}` : `Device invite for ${who}`,
68
+ detail: "Device admission actions are not available yet.",
69
+ };
70
+ }
55
71
  if (row.type === "contact") {
56
72
  if (row.direction === "in") {
73
+ if (row.recipientUserId) {
74
+ return {
75
+ title: `Connection request to ${who}`,
76
+ detail: "Waiting for them to confirm.",
77
+ };
78
+ }
57
79
  return { title: `${who} wants to connect`, detail: "Accept to add them as a contact." };
58
80
  }
59
81
  if (row.counterpart) {
@@ -65,13 +87,19 @@ function describeInviteRow(row) {
65
87
  };
66
88
  }
67
89
  if (row.direction === "in") {
90
+ if (row.recipientUserId) {
91
+ return { title: `Request to join ${group}`, detail: `Waiting for ${who} to approve.` };
92
+ }
68
93
  if (row.mode === "direct") {
69
94
  return {
70
95
  title: `${who} invited you to ${group}`,
71
96
  detail: role ? `You would join as ${role}.` : "",
72
97
  };
73
98
  }
74
- return { title: `Joining ${group}`, detail: `Waiting for ${who} to approve.` };
99
+ return {
100
+ title: `${who} wants to join ${group}`,
101
+ detail: role ? `Requested as ${role}. Approve or deny.` : "Approve or deny.",
102
+ };
75
103
  }
76
104
  if (row.mode === "direct") {
77
105
  return { title: `Invited ${who} to ${group}`, detail: "Waiting for them to accept." };
@@ -87,21 +115,45 @@ function describeInviteRow(row) {
87
115
  detail: `${row.mode === "open" ? "Open" : "Approval required"}${role ? ` · ${role}` : ""}`,
88
116
  };
89
117
  }
90
- function actionsFor(row) {
118
+ /**
119
+ * Group an invite by what the signed-in user can do with it.
120
+ *
121
+ * Pending rows that need a decision are `attention`. Pending rows waiting on
122
+ * someone else, including links the user issued, are `waiting`.
123
+ *
124
+ * @param row - Invite row from the personal Invites table.
125
+ */
126
+ function classifyInvite(row) {
91
127
  if (row.status !== "pending") {
128
+ return "history";
129
+ }
130
+ return actionsForInvite(row).some((action) => action !== "revoke") ? "attention" : "waiting";
131
+ }
132
+ /**
133
+ * Return actions that are valid from the local user's perspective.
134
+ *
135
+ * Inbound rows with `recipientUserId` were initiated locally and are waiting
136
+ * for that recipient. Actionable profile requests and join requests omit it.
137
+ */
138
+ function actionsForInvite(row) {
139
+ if (row.status !== "pending" || row.type === "device") {
140
+ return [];
141
+ }
142
+ if (row.direction === "out") {
143
+ return ["revoke"];
144
+ }
145
+ if (row.recipientUserId) {
92
146
  return [];
93
147
  }
94
148
  if (row.direction === "in") {
95
- // Inbound rows I can act on: contact requests and direct group invites.
96
149
  if (row.type === "contact" || row.mode === "direct") {
97
150
  return ["accept", "decline"];
98
151
  }
99
- return []; // my own outstanding join request; nothing to do but wait
100
- }
101
- if (row.counterpart && row.type === "group" && row.mode !== "direct") {
102
- return ["approve", "deny"];
152
+ if (row.type === "group" && row.mode === "approve" && row.counterpart) {
153
+ return ["approve", "deny"];
154
+ }
103
155
  }
104
- return ["revoke"];
156
+ return [];
105
157
  }
106
158
  const ACTION_LABELS = {
107
159
  accept: { text: "Accept", className: "btn-primary" },
@@ -110,6 +162,7 @@ const ACTION_LABELS = {
110
162
  deny: { text: "Deny", className: "btn-outline-secondary" },
111
163
  revoke: { text: "Revoke", className: "btn-outline-danger" },
112
164
  };
165
+ /** One invite row and the actions its direction and status allow. */
113
166
  function InviteRow({ row }) {
114
167
  const [busy, setBusy] = (0, react_1.useState)(undefined);
115
168
  const [error, setError] = (0, react_1.useState)("");
@@ -138,19 +191,5 @@ function InviteRow({ row }) {
138
191
  setBusy(undefined);
139
192
  }
140
193
  };
141
- return ((0, jsx_runtime_1.jsxs)("div", { className: "list-group-item", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex justify-content-between align-items-center gap-2 flex-wrap", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-grow-1", children: [(0, jsx_runtime_1.jsx)("div", { className: "fw-semibold", children: title }), detail ? (0, jsx_runtime_1.jsx)("small", { className: "text-muted d-block", children: detail }) : null, row.deliveryState === "queued" ? ((0, jsx_runtime_1.jsx)("small", { className: "text-warning d-block", children: "Queued until they are reachable" })) : null, row.status !== "pending" ? ((0, jsx_runtime_1.jsx)("small", { className: "text-muted d-block text-capitalize", children: row.status })) : null] }), (0, jsx_runtime_1.jsx)("div", { className: "d-flex gap-1", children: actionsFor(row).map((action) => ((0, jsx_runtime_1.jsx)("button", { type: "button", className: `btn btn-sm ${ACTION_LABELS[action].className}`, disabled: busy !== undefined, onClick: () => void run(action), children: busy === action ? "…" : ACTION_LABELS[action].text }, action))) })] }), error ? (0, jsx_runtime_1.jsx)("div", { className: "alert alert-danger py-1 px-2 small mt-2 mb-0", children: error }) : null] }));
142
- }
143
- /**
144
- * Live list of invite rows with the actions each one supports. Subscribes to the `Invites`
145
- * table directly, so it updates when replies arrive on any of the user's devices.
146
- */
147
- function PendingInvitesList(props) {
148
- const rows = useInviteRows(props);
149
- if (!rows) {
150
- return null;
151
- }
152
- if (rows.length === 0 && props.hideWhenEmpty) {
153
- return null;
154
- }
155
- return ((0, jsx_runtime_1.jsxs)("section", { className: "mb-3", children: [props.title ? (0, jsx_runtime_1.jsx)("h6", { className: "mb-2", children: props.title }) : null, rows.length === 0 ? ((0, jsx_runtime_1.jsx)("p", { className: "text-muted small mb-0", children: "No pending invites." })) : ((0, jsx_runtime_1.jsx)("div", { className: "list-group", children: rows.map((row) => ((0, jsx_runtime_1.jsx)(InviteRow, { row: row }, row.inviteId))) }))] }));
194
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "list-group-item", children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex justify-content-between align-items-center gap-2 flex-wrap", children: [(0, jsx_runtime_1.jsxs)("div", { className: "flex-grow-1", children: [(0, jsx_runtime_1.jsxs)("div", { className: "fw-semibold", children: [(0, jsx_runtime_1.jsx)("span", { className: "badge text-bg-light border me-2 text-capitalize", children: row.type }), title] }), detail ? (0, jsx_runtime_1.jsx)("small", { className: "text-muted d-block", children: detail }) : null, row.deliveryState === "queued" ? ((0, jsx_runtime_1.jsx)("small", { className: "text-warning d-block", children: "Queued until they are reachable" })) : null, row.status !== "pending" ? ((0, jsx_runtime_1.jsx)("small", { className: "text-muted d-block text-capitalize", children: row.status })) : null] }), (0, jsx_runtime_1.jsx)("div", { className: "d-flex gap-1", children: actionsForInvite(row).map((action) => ((0, jsx_runtime_1.jsx)("button", { type: "button", className: `btn btn-sm ${ACTION_LABELS[action].className}`, disabled: busy !== undefined, onClick: () => void run(action), children: busy === action ? "…" : ACTION_LABELS[action].text }, action))) })] }), error ? (0, jsx_runtime_1.jsx)("div", { className: "alert alert-danger py-1 px-2 small mt-2 mb-0", children: error }) : null] }));
156
195
  }
@@ -4,70 +4,15 @@ exports.getNetworkDiagnosticsConsumer = getNetworkDiagnosticsConsumer;
4
4
  exports.getNetworkControlConsumer = getNetworkControlConsumer;
5
5
  exports.getNetworkViewerPlatformApi = getNetworkViewerPlatformApi;
6
6
  const peers_sdk_1 = require("@peers-app/peers-sdk");
7
- /** Default wait for the host transport before treating diagnostics as unavailable. */
8
- const HOST_TRANSPORT_TIMEOUT_MS = 10_000;
9
- let cachedConsumers;
10
- let pendingConsumers;
11
- function disposeCachedConsumers() {
12
- cachedConsumers?.diagnostics.dispose();
13
- cachedConsumers?.control.dispose();
14
- cachedConsumers = undefined;
15
- }
16
- (0, peers_sdk_1.subscribeHostContractTransport)((transport) => {
17
- if (cachedConsumers && cachedConsumers.transport !== transport) {
18
- disposeCachedConsumers();
19
- }
20
- }, { emitCurrent: false });
21
- async function loadConsumers(transport) {
22
- disposeCachedConsumers();
23
- const diagnostics = (0, peers_sdk_1.createContractConsumer)((0, peers_sdk_1.getNetworkDiagnosticsContractDefinition)(), transport);
24
- const control = (0, peers_sdk_1.createContractConsumer)((0, peers_sdk_1.getNetworkControlContractDefinition)(), transport);
25
- try {
26
- await diagnostics.loadingPromise;
27
- if ((0, peers_sdk_1.getHostContractTransport)() !== transport) {
28
- diagnostics.dispose();
29
- control.dispose();
30
- // Clear before recursing so getConsumers can start a fresh in-flight memo for the
31
- // current transport, and so this promise's finally does not wipe that newer memo.
32
- pendingConsumers = undefined;
33
- return getConsumers();
34
- }
35
- cachedConsumers = { transport, diagnostics, control };
36
- return cachedConsumers;
37
- }
38
- catch (error) {
39
- diagnostics.dispose();
40
- control.dispose();
41
- throw error;
42
- }
43
- }
44
- async function getConsumers() {
45
- const transport = (0, peers_sdk_1.getHostContractTransport)() ??
46
- (await (0, peers_sdk_1.waitForHostContractTransport)({ timeoutMs: HOST_TRANSPORT_TIMEOUT_MS }));
47
- if (cachedConsumers?.transport === transport) {
48
- return cachedConsumers;
49
- }
50
- if (pendingConsumers) {
51
- return pendingConsumers;
52
- }
53
- const loadPromise = loadConsumers(transport);
54
- pendingConsumers = loadPromise;
55
- try {
56
- return await loadPromise;
57
- }
58
- finally {
59
- if (pendingConsumers === loadPromise) {
60
- pendingConsumers = undefined;
61
- }
62
- }
63
- }
7
+ const diagnostics = (0, peers_sdk_1.hostContractConsumer)((0, peers_sdk_1.getNetworkDiagnosticsContractDefinition)());
8
+ const control = (0, peers_sdk_1.hostContractConsumer)((0, peers_sdk_1.getNetworkControlContractDefinition)());
64
9
  /** Return a typed diagnostics consumer bound to the current local host transport. */
65
10
  async function getNetworkDiagnosticsConsumer() {
66
- return (await getConsumers()).diagnostics;
11
+ return diagnostics.get();
67
12
  }
68
13
  /** Return a typed control consumer bound to the current local host transport. */
69
14
  async function getNetworkControlConsumer() {
70
- return (await getConsumers()).control;
15
+ return control.get();
71
16
  }
72
17
  /** Return the context-isolated desktop-only capability bridge, when available. */
73
18
  function getNetworkViewerPlatformApi() {
@@ -1 +1,2 @@
1
+ /** Search system apps and known entities, then navigate to their canonical routes. */
1
2
  export declare function GlobalSearch(): import("react/jsx-runtime").JSX.Element;
@@ -14,8 +14,9 @@ const searchConfigs = [
14
14
  { config: mention_configs_1.assistantMentionConfig, category: "Assistants", navigationPath: "assistants" },
15
15
  { config: mention_configs_1.workflowMentionConfig, category: "Workflows", navigationPath: "workflows" },
16
16
  { config: mention_configs_1.valueTypeMentionConfig, category: "Types", navigationPath: "peer-types" },
17
- { config: mention_configs_1.userMentionConfig, category: "Users", navigationPath: "contacts" },
17
+ { config: mention_configs_1.userMentionConfig, category: "People", navigationPath: "identity/people" },
18
18
  ];
19
+ /** Search system apps and known entities, then navigate to their canonical routes. */
19
20
  function GlobalSearch() {
20
21
  const [_colorMode] = (0, hooks_1.useObservable)(color_mode_dropdown_1.colorMode);
21
22
  const [packages] = (0, hooks_1.useObservable)(routes_loader_1.allPackages);
@@ -43,7 +43,8 @@ const tooltip_1 = require("../../components/tooltip");
43
43
  const globals = __importStar(require("../../globals"));
44
44
  const hooks_1 = require("../../hooks");
45
45
  const layout_picker_1 = require("../../root-layout/layout-picker");
46
- const device_pairing_1 = require("../device-pairing");
46
+ const identity_ipc_1 = require("../device-pairing/identity-ipc");
47
+ const identity_routes_1 = require("../identity/identity-routes");
47
48
  const color_mode_dropdown_1 = require("./color-mode-dropdown");
48
49
  const isBrowserPwaHost = typeof window !== "undefined" &&
49
50
  !window.electronAPI &&
@@ -53,25 +54,25 @@ function getAppVersion() {
53
54
  }
54
55
  /** Application settings organized by user, system, and developer concerns. */
55
56
  const SettingsPage = () => {
56
- return ((0, jsx_runtime_1.jsx)("div", { className: "container-fluid", children: (0, jsx_runtime_1.jsx)(tabs_1.Tabs, { tabs: [
57
- {
58
- name: "User",
59
- content: (0, jsx_runtime_1.jsx)(UserSettingsTab, {}),
60
- active: true,
61
- },
62
- {
63
- name: "Appearance",
64
- content: (0, jsx_runtime_1.jsx)(AppearanceSettingsTab, {}),
65
- },
66
- {
67
- name: "Advanced",
68
- content: (0, jsx_runtime_1.jsx)(AdvancedSettingsTab, {}),
69
- },
70
- ] }) }));
57
+ return ((0, jsx_runtime_1.jsxs)("div", { className: "d-flex flex-column h-100 overflow-hidden", style: { minHeight: 0 }, children: [(0, jsx_runtime_1.jsx)("div", { className: "container-fluid flex-grow-1 overflow-auto", style: { minHeight: 0 }, children: (0, jsx_runtime_1.jsx)(tabs_1.Tabs, { tabs: [
58
+ {
59
+ name: "User",
60
+ content: (0, jsx_runtime_1.jsx)(UserSettingsTab, {}),
61
+ active: true,
62
+ },
63
+ {
64
+ name: "Appearance",
65
+ content: (0, jsx_runtime_1.jsx)(AppearanceSettingsTab, {}),
66
+ },
67
+ {
68
+ name: "Advanced",
69
+ content: (0, jsx_runtime_1.jsx)(AdvancedSettingsTab, {}),
70
+ },
71
+ ] }) }), (0, jsx_runtime_1.jsxs)("footer", { className: "flex-shrink-0 border-top px-3 py-2 small text-muted", children: ["Peers ", getAppVersion()] })] }));
71
72
  };
72
73
  exports.SettingsPage = SettingsPage;
73
74
  const UserSettingsTab = () => {
74
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ProfileSection, {}), (0, jsx_runtime_1.jsx)(AddDeviceSection, {}), (0, jsx_runtime_1.jsx)(LogoutSection, {})] }));
75
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)(ProfileSection, {}), (0, jsx_runtime_1.jsx)(IdentityAccountSection, {}), (0, jsx_runtime_1.jsx)(AddDeviceSection, {}), (0, jsx_runtime_1.jsx)(LogoutSection, {})] }));
75
76
  };
76
77
  const AppearanceSettingsTab = () => {
77
78
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("h5", { className: "mb-3", children: "Appearance" }), (0, jsx_runtime_1.jsx)("div", { className: "mb-3", children: (0, jsx_runtime_1.jsx)(color_mode_dropdown_1.ColorModeDropdown, {}) }), (0, jsx_runtime_1.jsx)("div", { className: "mb-3", children: (0, jsx_runtime_1.jsx)(layout_picker_1.LayoutPicker, {}) })] }));
@@ -80,30 +81,10 @@ const AdvancedSettingsTab = () => {
80
81
  return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("h5", { className: "mb-3", children: "Advanced Settings" }), (0, jsx_runtime_1.jsx)(PackagesRootDirectory, {}), (0, jsx_runtime_1.jsx)(ReloadPackagesOnPageRefresh, {}), (0, jsx_runtime_1.jsx)(AutoUpdatePeersCore, {}), (0, jsx_runtime_1.jsx)(ResetDeviceSyncInfos, {}), (0, jsx_runtime_1.jsx)(DeleteLocalDatabase, {}), (0, jsx_runtime_1.jsx)(CleanupOldDataDir, {}), (0, jsx_runtime_1.jsx)(ImportOldPeersData, {}), (0, jsx_runtime_1.jsx)(ResetChangeTracking, {})] }));
81
82
  };
82
83
  const ProfileSection = () => {
83
- const [deviceId] = (0, hooks_1.useObservable)(peers_sdk_1.thisDeviceId);
84
- const deviceName = (0, hooks_1.useObservableState)("");
85
- const savedDeviceName = (0, hooks_1.useObservableState)("");
86
84
  const me = (0, hooks_1.usePromise)(async () => {
87
85
  const userContext = await (0, peers_sdk_1.getUserContext)();
88
86
  return (0, peers_sdk_1.Users)(userContext.userDataContext).initDoc(globals.me);
89
87
  });
90
- // Load device name
91
- (0, react_1.useEffect)(() => {
92
- const loadDevice = async () => {
93
- if (!deviceId)
94
- return;
95
- try {
96
- const userContext = await (0, peers_sdk_1.getUserContext)();
97
- const device = await (0, peers_sdk_1.Devices)(userContext.userDataContext).get(deviceId);
98
- deviceName((device?.name || "").slice(0, peers_sdk_1.DISPLAY_NAME_MAX_LENGTH));
99
- savedDeviceName(device?.name || "");
100
- }
101
- catch (err) {
102
- console.error("Error loading device name:", err);
103
- }
104
- };
105
- loadDevice();
106
- }, [deviceId, deviceName, savedDeviceName]);
107
88
  const handleSave = async () => {
108
89
  try {
109
90
  // Save user profile (only when it actually changed). Pass me.toJS() — the
@@ -117,21 +98,6 @@ const ProfileSection = () => {
117
98
  me.qs.name(updatedUser.name);
118
99
  me.q(0); // Reset change counter
119
100
  }
120
- // Save device name if changed
121
- if (deviceId && deviceName() !== savedDeviceName()) {
122
- const userContext = await (0, peers_sdk_1.getUserContext)();
123
- const devicesTable = (0, peers_sdk_1.Devices)(userContext.userDataContext);
124
- const device = (await devicesTable.get(deviceId)) || {
125
- deviceId,
126
- userId: userContext.userId,
127
- firstSeen: new Date(),
128
- lastSeen: new Date(),
129
- trustLevel: peers_sdk_1.TrustLevel.NewDevice,
130
- };
131
- device.name = deviceName() || undefined;
132
- await devicesTable.save(device);
133
- savedDeviceName(deviceName());
134
- }
135
101
  }
136
102
  catch (err) {
137
103
  console.error("Error saving profile:", err);
@@ -140,16 +106,17 @@ const ProfileSection = () => {
140
106
  };
141
107
  // Subscribe to changes
142
108
  (0, hooks_1.useObservable)(me?.q);
143
- (0, hooks_1.useObservable)(deviceName);
144
109
  if (!me) {
145
110
  return null;
146
111
  }
147
- const hasChanges = !!me.q() || deviceName() !== savedDeviceName();
148
- return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mb-3", children: [(0, jsx_runtime_1.jsx)("h5", { className: "mb-0 me-auto", children: "Settings" }), (0, jsx_runtime_1.jsx)("button", { className: "btn btn-primary btn-sm", onClick: handleSave, disabled: !hasChanges, children: "Save" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsx)("small", { className: "form-label", children: "Display Name:" }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: me.qs.name, className: "form-control", maxLength: peers_sdk_1.DISPLAY_NAME_MAX_LENGTH, placeholder: "Enter your name" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsxs)("small", { className: "form-label", children: ["Device Name:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "Give this device a friendly name to identify it in your network." })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: deviceName, className: "form-control", maxLength: peers_sdk_1.DISPLAY_NAME_MAX_LENGTH, placeholder: "e.g., My Laptop" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsxs)("small", { className: "form-label", children: ["User ID:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "This uniquely identifies you to all other users." })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: me.userId, className: "form-control", disabled: true })] }), (0, jsx_runtime_1.jsxs)("div", { className: "row", children: [(0, jsx_runtime_1.jsxs)("div", { className: "col-md-6 mb-3", children: [(0, jsx_runtime_1.jsxs)("small", { className: "form-label", children: ["Public Key:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "This is your public key that other users will use to verify your signatures." })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: me.publicKey, className: "form-control form-control-sm", disabled: true })] }), (0, jsx_runtime_1.jsxs)("div", { className: "col-md-6 mb-3", children: [(0, jsx_runtime_1.jsxs)("small", { className: "form-label", children: ["Public Box Key:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "This is the public key that other users can use to encrypt data so that only you can open it." })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: me.publicBoxKey, className: "form-control form-control-sm", disabled: true })] })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsxs)("small", { className: "form-label", children: ["Device ID:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: "This uniquely identifies this device on Peers networks." })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: deviceId || "", className: "form-control form-control-sm", disabled: true })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsx)("small", { className: "form-label", children: "App Version:" }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: getAppVersion(), className: "form-control form-control-sm", disabled: true })] })] }));
112
+ const hasChanges = !!me.q();
113
+ return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsxs)("div", { className: "d-flex align-items-center mb-3", children: [(0, jsx_runtime_1.jsx)("h5", { className: "mb-0 me-auto", children: "Profile" }), (0, jsx_runtime_1.jsx)("button", { className: "btn btn-primary btn-sm", onClick: handleSave, disabled: !hasChanges, children: "Save" })] }), (0, jsx_runtime_1.jsxs)("div", { className: "mb-3", children: [(0, jsx_runtime_1.jsx)("label", { className: "form-label small", htmlFor: "settings-display-name", children: "Display name" }), (0, jsx_runtime_1.jsx)(input_1.Input, { id: "settings-display-name", value: me.qs.name, className: "form-control", maxLength: peers_sdk_1.DISPLAY_NAME_MAX_LENGTH, placeholder: "Enter your name" })] })] }));
114
+ };
115
+ const IdentityAccountSection = () => {
116
+ return ((0, jsx_runtime_1.jsxs)("section", { className: "mt-4 pt-3 border-top", children: [(0, jsx_runtime_1.jsx)("h6", { children: "Identity account" }), (0, jsx_runtime_1.jsx)("p", { className: "small text-muted", children: "View account identifiers, security keys, this device\u2019s ID, and Peers Services registration." }), (0, jsx_runtime_1.jsx)("a", { href: `#${identity_routes_1.IDENTITY_ACCOUNT_PATH}`, className: "btn btn-outline-primary", children: "View Identity account" })] }));
149
117
  };
150
118
  const AddDeviceSection = () => {
151
- const [open, setOpen] = (0, react_1.useState)(false);
152
- return ((0, jsx_runtime_1.jsxs)("section", { className: "mt-4 pt-3 border-top", children: [(0, jsx_runtime_1.jsx)("h6", { children: "Add another device" }), (0, jsx_runtime_1.jsx)("p", { className: "small text-muted", children: "On the new device choose \u201CSign in from another device\u201D, then type the code it shows here and approve. Account access is transferred only after you approve." }), open ? ((0, jsx_runtime_1.jsx)(device_pairing_1.SourceDevicePairing, { onClose: () => setOpen(false) })) : ((0, jsx_runtime_1.jsx)("button", { type: "button", className: "btn btn-outline-primary", onClick: () => setOpen(true), children: "Add another device" }))] }));
119
+ return ((0, jsx_runtime_1.jsxs)("section", { className: "mt-4 pt-3 border-top", children: [(0, jsx_runtime_1.jsx)("h6", { children: "Add another device" }), (0, jsx_runtime_1.jsx)("p", { className: "small text-muted", children: "On the new device choose \u201CSign in from another device\u201D, then type the code it shows on Identity \u2192 Devices and approve. Account access is transferred only after you approve." }), (0, jsx_runtime_1.jsx)("a", { href: `#${identity_routes_1.IDENTITY_PAIR_PATH}`, className: "btn btn-outline-primary", children: "Add another device" })] }));
153
120
  };
154
121
  const PackagesRootDirectory = () => {
155
122
  return ((0, jsx_runtime_1.jsxs)("div", { className: "mt-3", children: [(0, jsx_runtime_1.jsxs)("small", { children: ["Packages Directory:", (0, jsx_runtime_1.jsx)(tooltip_1.Tooltip, { markdownContent: `Changing this will not effect existing packages.` })] }), (0, jsx_runtime_1.jsx)(input_1.Input, { value: peers_sdk_1.packagesRootDir, className: "form-control" })] }));
@@ -317,6 +284,6 @@ const LogoutSection = () => {
317
284
  "Make sure you have your User ID and Secret Key saved securely, or you will lose access to your account.");
318
285
  if (!confirmed)
319
286
  return;
320
- await peers_sdk_1.rpcServerCalls.logout();
287
+ await (await (0, identity_ipc_1.identityTools)()).signOut();
321
288
  }, children: "Logout" }) }));
322
289
  };
@@ -6,6 +6,7 @@ const peers_sdk_1 = require("@peers-app/peers-sdk");
6
6
  const react_1 = require("react");
7
7
  const hooks_1 = require("../hooks");
8
8
  const device_pairing_1 = require("./device-pairing");
9
+ const identity_ipc_1 = require("./device-pairing/identity-ipc");
9
10
  const color_mode_dropdown_1 = require("./settings/color-mode-dropdown");
10
11
  const SetupUser = () => {
11
12
  const [_colorMode] = (0, hooks_1.useObservable)(color_mode_dropdown_1.colorMode);
@@ -25,9 +26,9 @@ const SetupUser = () => {
25
26
  // Generate new user credentials
26
27
  const keys = (0, peers_sdk_1.newKeys)();
27
28
  const _userId = (0, peers_sdk_1.newid)();
28
- // Call setUserIdAndSecretKey. This triggers device init, which installs
29
- // peers-core into the personal context (S3-first, bundle fallback).
30
- await peers_sdk_1.rpcServerCalls.setUserIdAndSecretKey(_userId, keys.secretKey);
29
+ // signIn triggers device init, which installs peers-core into the personal
30
+ // context (S3-first, bundle fallback).
31
+ await (await (0, identity_ipc_1.identityTools)()).signIn({ userId: _userId, secretKey: keys.secretKey });
31
32
  // Success - reload the app (peers-services registration runs after Welcome modal)
32
33
  window.location.reload();
33
34
  }
@@ -57,8 +58,7 @@ const SetupUser = () => {
57
58
  if (msg !== msgOpened) {
58
59
  throw new Error("Secret key validation failed");
59
60
  }
60
- // Call setUserIdAndSecretKey
61
- await peers_sdk_1.rpcServerCalls.setUserIdAndSecretKey(userId, keys.secretKey);
61
+ await (await (0, identity_ipc_1.identityTools)()).signIn({ userId, secretKey: keys.secretKey });
62
62
  // Success - reload the app
63
63
  window.location.reload();
64
64
  }
@@ -1,5 +1,7 @@
1
1
  import { type IToolAccessControlConsumer } from "@peers-app/peers-sdk";
2
2
  /**
3
3
  * Return a typed local-host consumer for Tool Access Control in `dataContextId`.
4
+ *
5
+ * One consumer is cached per data context and rebuilt when the host transport changes.
4
6
  */
5
7
  export declare function getToolAccessControlConsumer(dataContextId: string): Promise<IToolAccessControlConsumer>;
@@ -2,64 +2,17 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.getToolAccessControlConsumer = getToolAccessControlConsumer;
4
4
  const peers_sdk_1 = require("@peers-app/peers-sdk");
5
- const HOST_TRANSPORT_TIMEOUT_MS = 10_000;
6
- const cachedByContext = new Map();
7
- const pendingByContext = new Map();
8
- function disposeCachedConsumers() {
9
- for (const cached of cachedByContext.values()) {
10
- cached.consumer.dispose();
11
- }
12
- cachedByContext.clear();
13
- }
14
- (0, peers_sdk_1.subscribeHostContractTransport)((transport) => {
15
- if ([...cachedByContext.values()].some((cached) => cached.transport !== transport)) {
16
- disposeCachedConsumers();
17
- pendingByContext.clear();
18
- }
19
- }, { emitCurrent: false });
20
- async function loadConsumer(transport, dataContextId) {
21
- cachedByContext.get(dataContextId)?.consumer.dispose();
22
- cachedByContext.delete(dataContextId);
23
- const consumer = (0, peers_sdk_1.createContractConsumer)((0, peers_sdk_1.getToolAccessControlContractDefinition)(), transport, {
24
- dataContextId,
25
- });
26
- try {
27
- await consumer.loadingPromise;
28
- if ((0, peers_sdk_1.getHostContractTransport)() !== transport) {
29
- consumer.dispose();
30
- pendingByContext.delete(dataContextId);
31
- return getToolAccessControlConsumer(dataContextId);
32
- }
33
- cachedByContext.set(dataContextId, { transport, consumer });
34
- return consumer;
35
- }
36
- catch (error) {
37
- consumer.dispose();
38
- throw error;
39
- }
40
- }
5
+ const consumers = new Map();
41
6
  /**
42
7
  * Return a typed local-host consumer for Tool Access Control in `dataContextId`.
8
+ *
9
+ * One consumer is cached per data context and rebuilt when the host transport changes.
43
10
  */
44
11
  async function getToolAccessControlConsumer(dataContextId) {
45
- const transport = (0, peers_sdk_1.getHostContractTransport)() ??
46
- (await (0, peers_sdk_1.waitForHostContractTransport)({ timeoutMs: HOST_TRANSPORT_TIMEOUT_MS }));
47
- const cached = cachedByContext.get(dataContextId);
48
- if (cached?.transport === transport) {
49
- return cached.consumer;
50
- }
51
- const pending = pendingByContext.get(dataContextId);
52
- if (pending) {
53
- return pending;
54
- }
55
- const loadPromise = loadConsumer(transport, dataContextId);
56
- pendingByContext.set(dataContextId, loadPromise);
57
- try {
58
- return await loadPromise;
59
- }
60
- finally {
61
- if (pendingByContext.get(dataContextId) === loadPromise) {
62
- pendingByContext.delete(dataContextId);
63
- }
12
+ let handle = consumers.get(dataContextId);
13
+ if (!handle) {
14
+ handle = (0, peers_sdk_1.hostContractConsumer)((0, peers_sdk_1.getToolAccessControlContractDefinition)(), { dataContextId: async () => dataContextId });
15
+ consumers.set(dataContextId, handle);
64
16
  }
17
+ return handle.get();
65
18
  }
@@ -6,10 +6,11 @@ const peers_sdk_1 = require("@peers-app/peers-sdk");
6
6
  const react_1 = require("react");
7
7
  const hooks_1 = require("../hooks");
8
8
  const peers_services_registration_1 = require("../peers-services-registration");
9
+ const identity_ipc_1 = require("./device-pairing/identity-ipc");
9
10
  async function tryRegisterPeersServicesAfterWelcome() {
10
11
  try {
11
- const token = await peers_sdk_1.rpcServerCalls.registerWithPeersServices();
12
- (0, peers_services_registration_1.persistPeersServicesRegistration)(token);
12
+ const { token } = await (await (0, identity_ipc_1.identityTools)()).registerWithPeersServices();
13
+ await (0, peers_services_registration_1.persistPeersServicesRegistration)(token);
13
14
  }
14
15
  catch (err) {
15
16
  console.warn("Peers services registration after welcome modal:", err);
@@ -0,0 +1,3 @@
1
+ import type { IAppNav } from "@peers-app/peers-sdk";
2
+ /** Identity system app: activity, people, groups, devices, and account. */
3
+ export declare const identityApp: IAppNav;
@@ -0,0 +1,10 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.identityApp = void 0;
4
+ /** Identity system app: activity, people, groups, devices, and account. */
5
+ exports.identityApp = {
6
+ name: "Identity",
7
+ displayName: "Identity",
8
+ iconClassName: "bi-person-badge",
9
+ navigationPath: "identity",
10
+ };
@@ -1,12 +1,9 @@
1
1
  import type { IAppNav } from "@peers-app/peers-sdk";
2
2
  import type { IPackageWithNavs } from "../ui-router/routes-loader";
3
- export { accountApp } from "./account.app";
4
3
  export { assistantsApp } from "./assistants.app";
5
4
  export { consoleLogsApp } from "./console-logs.app";
6
- export { contactsApp } from "./contacts.app";
7
5
  export { dataExplorerApp } from "./data-explorer.app";
8
- export { groupsApp } from "./groups.app";
9
- export { invitesApp } from "./invites.app";
6
+ export { identityApp } from "./identity.app";
10
7
  export { mobileSettingsApp } from "./mobile-settings.app";
11
8
  export { networkViewerApp } from "./network-viewer.app";
12
9
  export { packagesApp } from "./packages.app";
@@ -1,20 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.systemPackage = exports.systemApps = exports.workflowsApp = exports.variablesApp = exports.typesApp = exports.toolsApp = exports.threadsApp = exports.settingsApp = exports.searchApp = exports.packagesApp = exports.networkViewerApp = exports.mobileSettingsApp = exports.invitesApp = exports.groupsApp = exports.dataExplorerApp = exports.contactsApp = exports.consoleLogsApp = exports.assistantsApp = exports.accountApp = void 0;
4
- var account_app_1 = require("./account.app");
5
- Object.defineProperty(exports, "accountApp", { enumerable: true, get: function () { return account_app_1.accountApp; } });
3
+ exports.systemPackage = exports.systemApps = exports.workflowsApp = exports.variablesApp = exports.typesApp = exports.toolsApp = exports.threadsApp = exports.settingsApp = exports.searchApp = exports.packagesApp = exports.networkViewerApp = exports.mobileSettingsApp = exports.identityApp = exports.dataExplorerApp = exports.consoleLogsApp = exports.assistantsApp = void 0;
6
4
  var assistants_app_1 = require("./assistants.app");
7
5
  Object.defineProperty(exports, "assistantsApp", { enumerable: true, get: function () { return assistants_app_1.assistantsApp; } });
8
6
  var console_logs_app_1 = require("./console-logs.app");
9
7
  Object.defineProperty(exports, "consoleLogsApp", { enumerable: true, get: function () { return console_logs_app_1.consoleLogsApp; } });
10
- var contacts_app_1 = require("./contacts.app");
11
- Object.defineProperty(exports, "contactsApp", { enumerable: true, get: function () { return contacts_app_1.contactsApp; } });
12
8
  var data_explorer_app_1 = require("./data-explorer.app");
13
9
  Object.defineProperty(exports, "dataExplorerApp", { enumerable: true, get: function () { return data_explorer_app_1.dataExplorerApp; } });
14
- var groups_app_1 = require("./groups.app");
15
- Object.defineProperty(exports, "groupsApp", { enumerable: true, get: function () { return groups_app_1.groupsApp; } });
16
- var invites_app_1 = require("./invites.app");
17
- Object.defineProperty(exports, "invitesApp", { enumerable: true, get: function () { return invites_app_1.invitesApp; } });
10
+ var identity_app_1 = require("./identity.app");
11
+ Object.defineProperty(exports, "identityApp", { enumerable: true, get: function () { return identity_app_1.identityApp; } });
18
12
  var mobile_settings_app_1 = require("./mobile-settings.app");
19
13
  Object.defineProperty(exports, "mobileSettingsApp", { enumerable: true, get: function () { return mobile_settings_app_1.mobileSettingsApp; } });
20
14
  var network_viewer_app_1 = require("./network-viewer.app");
@@ -36,13 +30,10 @@ var variables_app_1 = require("./variables.app");
36
30
  Object.defineProperty(exports, "variablesApp", { enumerable: true, get: function () { return variables_app_1.variablesApp; } });
37
31
  var workflows_app_1 = require("./workflows.app");
38
32
  Object.defineProperty(exports, "workflowsApp", { enumerable: true, get: function () { return workflows_app_1.workflowsApp; } });
39
- const account_app_2 = require("./account.app");
40
33
  const assistants_app_2 = require("./assistants.app");
41
34
  const console_logs_app_2 = require("./console-logs.app");
42
- const contacts_app_2 = require("./contacts.app");
43
35
  const data_explorer_app_2 = require("./data-explorer.app");
44
- const groups_app_2 = require("./groups.app");
45
- const invites_app_2 = require("./invites.app");
36
+ const identity_app_2 = require("./identity.app");
46
37
  const mobile_settings_app_2 = require("./mobile-settings.app");
47
38
  const network_viewer_app_2 = require("./network-viewer.app");
48
39
  const packages_app_2 = require("./packages.app");
@@ -74,11 +65,8 @@ exports.systemApps = [
74
65
  workflows_app_2.workflowsApp,
75
66
  assistants_app_2.assistantsApp,
76
67
  packages_app_2.packagesApp,
77
- contacts_app_2.contactsApp,
78
- groups_app_2.groupsApp,
79
- invites_app_2.invitesApp,
68
+ identity_app_2.identityApp,
80
69
  // User & Settings Apps
81
- account_app_2.accountApp,
82
70
  settings_app_2.settingsApp,
83
71
  // Mobile Settings (only in React Native)
84
72
  ...(isReactNative() ? [mobile_settings_app_2.mobileSettingsApp] : []),