@peers-app/peers-ui 0.27.3 → 0.27.5

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 (311) hide show
  1. package/dist/screens/network-viewer/group-details-modal.d.ts +4 -0
  2. package/dist/screens/network-viewer/group-details-modal.js +6 -46
  3. package/dist/screens/network-viewer/network-viewer-ipc.d.ts +3 -2
  4. package/dist/screens/network-viewer/network-viewer-ipc.js +6 -0
  5. package/dist/screens/network-viewer/sync-recovery.js +103 -1
  6. package/dist/screens/variables/variable-details.js +2 -1
  7. package/dist/tabs-layout/network-status-indicator.js +26 -12
  8. package/dist/tabs-layout/use-network-status.d.ts +6 -1
  9. package/dist/tabs-layout/use-network-status.js +27 -4
  10. package/package.json +9 -3
  11. package/.claude/settings.local.json +0 -34
  12. package/.github/README.md +0 -52
  13. package/.github/workflows/delete-all-artifacts.yml +0 -49
  14. package/.github/workflows/publish.yml +0 -51
  15. package/babel.config.js +0 -7
  16. package/biome.json +0 -198
  17. package/dist/app-updates/app-updates-consumer.test.d.ts +0 -1
  18. package/dist/app-updates/app-updates-consumer.test.js +0 -56
  19. package/dist/app-updates/app-updates-settings.test.d.ts +0 -1
  20. package/dist/app-updates/app-updates-settings.test.js +0 -93
  21. package/dist/app-updates/remote-app-update-panel.test.d.ts +0 -1
  22. package/dist/app-updates/remote-app-update-panel.test.js +0 -165
  23. package/dist/components/access-level-field.test.d.ts +0 -1
  24. package/dist/components/access-level-field.test.js +0 -28
  25. package/dist/components/message-logs/tool-access-approval-card.test.d.ts +0 -1
  26. package/dist/components/message-logs/tool-access-approval-card.test.js +0 -102
  27. package/dist/components/responsive-section-nav.test.d.ts +0 -1
  28. package/dist/components/responsive-section-nav.test.js +0 -45
  29. package/dist/globals-hash.test.d.ts +0 -1
  30. package/dist/globals-hash.test.js +0 -16
  31. package/dist/hooks/use-observable-state.test.d.ts +0 -1
  32. package/dist/hooks/use-observable-state.test.js +0 -64
  33. package/dist/hooks/use-observable.test.d.ts +0 -1
  34. package/dist/hooks/use-observable.test.js +0 -191
  35. package/dist/hooks/use-rows.test.d.ts +0 -1
  36. package/dist/hooks/use-rows.test.js +0 -175
  37. package/dist/hooks/use-tool.test.d.ts +0 -1
  38. package/dist/hooks/use-tool.test.js +0 -190
  39. package/dist/host-shell/host-shell-consumer.test.d.ts +0 -1
  40. package/dist/host-shell/host-shell-consumer.test.js +0 -28
  41. package/dist/root-layout/root-layout-host.test.d.ts +0 -1
  42. package/dist/root-layout/root-layout-host.test.js +0 -86
  43. package/dist/screens/account/account-screen.test.d.ts +0 -1
  44. package/dist/screens/account/account-screen.test.js +0 -51
  45. package/dist/screens/assistants/assistant-config.test.d.ts +0 -1
  46. package/dist/screens/assistants/assistant-config.test.js +0 -57
  47. package/dist/screens/contacts/contact-list.test.d.ts +0 -1
  48. package/dist/screens/contacts/contact-list.test.js +0 -48
  49. package/dist/screens/device-pairing/device-pairing.test.d.ts +0 -1
  50. package/dist/screens/device-pairing/device-pairing.test.js +0 -119
  51. package/dist/screens/devices/devices-list.test.d.ts +0 -1
  52. package/dist/screens/devices/devices-list.test.js +0 -53
  53. package/dist/screens/groups/group-list.test.d.ts +0 -1
  54. package/dist/screens/groups/group-list.test.js +0 -38
  55. package/dist/screens/identity/identity-routes.test.d.ts +0 -1
  56. package/dist/screens/identity/identity-routes.test.js +0 -51
  57. package/dist/screens/identity/identity-screen.test.d.ts +0 -1
  58. package/dist/screens/identity/identity-screen.test.js +0 -103
  59. package/dist/screens/invites/accept-invite.test.d.ts +0 -1
  60. package/dist/screens/invites/accept-invite.test.js +0 -103
  61. package/dist/screens/invites/activity-view.test.d.ts +0 -1
  62. package/dist/screens/invites/activity-view.test.js +0 -108
  63. package/dist/screens/invites/invite-classify.test.d.ts +0 -1
  64. package/dist/screens/invites/invite-classify.test.js +0 -115
  65. package/dist/screens/network-viewer/network-viewer-ipc.test.d.ts +0 -1
  66. package/dist/screens/network-viewer/network-viewer-ipc.test.js +0 -61
  67. package/dist/screens/network-viewer/network-viewer.section.test.d.ts +0 -1
  68. package/dist/screens/network-viewer/network-viewer.section.test.js +0 -63
  69. package/dist/screens/network-viewer/sync-recovery.test.d.ts +0 -1
  70. package/dist/screens/network-viewer/sync-recovery.test.js +0 -104
  71. package/dist/screens/packages/package-helpers.test.d.ts +0 -1
  72. package/dist/screens/packages/package-helpers.test.js +0 -53
  73. package/dist/screens/packages/package-runtime-status.test.d.ts +0 -1
  74. package/dist/screens/packages/package-runtime-status.test.js +0 -50
  75. package/dist/screens/packages/packages-ipc.test.d.ts +0 -1
  76. package/dist/screens/packages/packages-ipc.test.js +0 -43
  77. package/dist/screens/settings/settings-page.test.d.ts +0 -1
  78. package/dist/screens/settings/settings-page.test.js +0 -19
  79. package/dist/screens/tools/tool-access-ipc.test.d.ts +0 -1
  80. package/dist/screens/tools/tool-access-ipc.test.js +0 -40
  81. package/dist/screens/tools/tool-catalog-ipc.test.d.ts +0 -1
  82. package/dist/screens/tools/tool-catalog-ipc.test.js +0 -52
  83. package/dist/tabs-layout/network-status-indicator.test.d.ts +0 -1
  84. package/dist/tabs-layout/network-status-indicator.test.js +0 -665
  85. package/dist/tabs-layout/tabs-state.test.d.ts +0 -1
  86. package/dist/tabs-layout/tabs-state.test.js +0 -110
  87. package/dist/tabs-layout/use-network-status.test.d.ts +0 -1
  88. package/dist/tabs-layout/use-network-status.test.js +0 -45
  89. package/dist/ui-router/ui-loader.test.d.ts +0 -1
  90. package/dist/ui-router/ui-loader.test.js +0 -91
  91. package/jest.config.js +0 -25
  92. package/release-guard.js +0 -10
  93. package/src/app-updates/app-update-controls.tsx +0 -73
  94. package/src/app-updates/app-updates-consumer.test.ts +0 -83
  95. package/src/app-updates/app-updates-consumer.ts +0 -121
  96. package/src/app-updates/app-updates-settings.test.tsx +0 -109
  97. package/src/app-updates/app-updates-settings.tsx +0 -136
  98. package/src/app-updates/remote-app-update-panel.test.tsx +0 -205
  99. package/src/app-updates/remote-app-update-panel.tsx +0 -210
  100. package/src/app-updates/use-app-update-status.ts +0 -16
  101. package/src/command-palette/command-palette-ui.tsx +0 -564
  102. package/src/command-palette/command-palette.ts +0 -242
  103. package/src/components/access-level-field.test.tsx +0 -32
  104. package/src/components/access-level-field.tsx +0 -68
  105. package/src/components/checkbox.tsx +0 -25
  106. package/src/components/group-switcher.tsx +0 -526
  107. package/src/components/input-date.tsx +0 -29
  108. package/src/components/input-number.tsx +0 -83
  109. package/src/components/input.tsx +0 -25
  110. package/src/components/inverse-lazy-list.tsx +0 -107
  111. package/src/components/io-schema-values.tsx +0 -103
  112. package/src/components/io-schema.tsx +0 -259
  113. package/src/components/lazy-list.tsx +0 -115
  114. package/src/components/list-screen.tsx +0 -126
  115. package/src/components/loading-indicator.tsx +0 -7
  116. package/src/components/markdown-editor/autolink-plugin.tsx +0 -29
  117. package/src/components/markdown-editor/editor-inline.tsx +0 -9
  118. package/src/components/markdown-editor/editor.tsx +0 -158
  119. package/src/components/markdown-editor/markdown-plugin.tsx +0 -202
  120. package/src/components/markdown-editor/mention-node.ts +0 -204
  121. package/src/components/markdown-editor/mentions-plugin.tsx +0 -354
  122. package/src/components/markdown-editor/move-line-plugin.tsx +0 -186
  123. package/src/components/markdown-editor/select-line-boundary-plugin.tsx +0 -95
  124. package/src/components/markdown-editor/theme.ts +0 -46
  125. package/src/components/markdown-editor/toolbar.tsx +0 -269
  126. package/src/components/markdown-with-mentions.tsx +0 -198
  127. package/src/components/message-logs/message-logs.tsx +0 -523
  128. package/src/components/message-logs/tool-access-approval-card.test.tsx +0 -127
  129. package/src/components/message-logs/tool-access-approval-card.tsx +0 -178
  130. package/src/components/messages/avatar.tsx +0 -171
  131. package/src/components/messages/channel-message-list.tsx +0 -189
  132. package/src/components/messages/channel-view.tsx +0 -92
  133. package/src/components/messages/message-compose.tsx +0 -192
  134. package/src/components/messages/message-display.tsx +0 -231
  135. package/src/components/messages/thread-message-list.tsx +0 -135
  136. package/src/components/qr-scanner.tsx +0 -180
  137. package/src/components/responsive-section-nav.test.tsx +0 -88
  138. package/src/components/responsive-section-nav.tsx +0 -92
  139. package/src/components/router.tsx +0 -175
  140. package/src/components/save-button.tsx +0 -134
  141. package/src/components/sortable-list.tsx +0 -130
  142. package/src/components/tabs.tsx +0 -76
  143. package/src/components/tooltip.tsx +0 -43
  144. package/src/components/trust-level-badge.tsx +0 -44
  145. package/src/components/trust-level-dropdown.tsx +0 -136
  146. package/src/components/typeahead.tsx +0 -357
  147. package/src/globals-hash.test.ts +0 -19
  148. package/src/globals.tsx +0 -226
  149. package/src/hooks/index.ts +0 -8
  150. package/src/hooks/use-host-contract.ts +0 -75
  151. package/src/hooks/use-observable-state.test.tsx +0 -101
  152. package/src/hooks/use-observable-state.ts +0 -29
  153. package/src/hooks/use-observable.test.tsx +0 -258
  154. package/src/hooks/use-observable.ts +0 -67
  155. package/src/hooks/use-on-screen.ts +0 -24
  156. package/src/hooks/use-promise.ts +0 -34
  157. package/src/hooks/use-rows.test.tsx +0 -196
  158. package/src/hooks/use-rows.ts +0 -120
  159. package/src/hooks/use-subscription.ts +0 -24
  160. package/src/hooks/use-tool.test.tsx +0 -225
  161. package/src/hooks/use-tool.ts +0 -116
  162. package/src/host-shell/host-shell-consumer.test.ts +0 -32
  163. package/src/host-shell/host-shell-consumer.ts +0 -53
  164. package/src/index.tsx +0 -42
  165. package/src/mention-configs.ts +0 -185
  166. package/src/operator-console/operator-console-state.ts +0 -119
  167. package/src/operator-console/operator-console.tsx +0 -233
  168. package/src/peers-services-registration.ts +0 -6
  169. package/src/root-layout/global-overlays.ts +0 -50
  170. package/src/root-layout/layout-picker.tsx +0 -47
  171. package/src/root-layout/layouts/full-screen-layout.tsx +0 -144
  172. package/src/root-layout/layouts/tabs-with-console-layout.tsx +0 -260
  173. package/src/root-layout/root-layout-host.test.tsx +0 -108
  174. package/src/root-layout/root-layout-host.tsx +0 -147
  175. package/src/root-layout/root-layout-registry.ts +0 -51
  176. package/src/root-layout/root-layout-state.ts +0 -55
  177. package/src/root-layout/root-layout.ts +0 -32
  178. package/src/screens/account/account-screen.test.tsx +0 -65
  179. package/src/screens/account/account-screen.tsx +0 -942
  180. package/src/screens/assistants/assistant-config.test.tsx +0 -54
  181. package/src/screens/assistants/assistant-config.tsx +0 -121
  182. package/src/screens/assistants/assistant-details.tsx +0 -89
  183. package/src/screens/assistants/assistant-info.tsx +0 -66
  184. package/src/screens/assistants/assistant-list.tsx +0 -145
  185. package/src/screens/assistants/assistant-tools.tsx +0 -82
  186. package/src/screens/console-logs/console-logs-list.tsx +0 -374
  187. package/src/screens/console-logs/log-display.tsx +0 -137
  188. package/src/screens/console-logs/log-filters.tsx +0 -64
  189. package/src/screens/console-logs/mobile-log-card.tsx +0 -161
  190. package/src/screens/console-logs/resizable-table-header.tsx +0 -110
  191. package/src/screens/contacts/contact-details.tsx +0 -123
  192. package/src/screens/contacts/contact-list.test.tsx +0 -59
  193. package/src/screens/contacts/contact-list.tsx +0 -286
  194. package/src/screens/contacts/index.ts +0 -2
  195. package/src/screens/data-explorer/data-explorer.tsx +0 -633
  196. package/src/screens/data-explorer/index.ts +0 -6
  197. package/src/screens/data-explorer/query-executor.tsx +0 -520
  198. package/src/screens/device-pairing/device-pairing.test.tsx +0 -143
  199. package/src/screens/device-pairing/device-pairing.tsx +0 -461
  200. package/src/screens/device-pairing/identity-ipc.ts +0 -25
  201. package/src/screens/device-pairing/index.ts +0 -2
  202. package/src/screens/device-pairing/use-device-pairing-state.ts +0 -15
  203. package/src/screens/devices/devices-list.test.tsx +0 -68
  204. package/src/screens/devices/devices-list.tsx +0 -365
  205. package/src/screens/devices/index.ts +0 -1
  206. package/src/screens/groups/group-details.tsx +0 -160
  207. package/src/screens/groups/group-invite-panel.tsx +0 -311
  208. package/src/screens/groups/group-list.test.tsx +0 -44
  209. package/src/screens/groups/group-list.tsx +0 -317
  210. package/src/screens/groups/group-members.tsx +0 -343
  211. package/src/screens/groups/index.ts +0 -3
  212. package/src/screens/identity/identity-routes.test.ts +0 -70
  213. package/src/screens/identity/identity-routes.ts +0 -301
  214. package/src/screens/identity/identity-screen.test.tsx +0 -138
  215. package/src/screens/identity/identity-screen.tsx +0 -282
  216. package/src/screens/identity/index.ts +0 -2
  217. package/src/screens/identity/invite-contact-panel.tsx +0 -45
  218. package/src/screens/identity/profile-invite.tsx +0 -93
  219. package/src/screens/invites/accept-invite.test.tsx +0 -115
  220. package/src/screens/invites/accept-invite.tsx +0 -318
  221. package/src/screens/invites/activity-view.test.tsx +0 -127
  222. package/src/screens/invites/activity-view.tsx +0 -162
  223. package/src/screens/invites/index.ts +0 -6
  224. package/src/screens/invites/invite-capture.ts +0 -104
  225. package/src/screens/invites/invite-classify.test.ts +0 -129
  226. package/src/screens/invites/invite-share.tsx +0 -104
  227. package/src/screens/invites/invites-ipc.ts +0 -25
  228. package/src/screens/invites/pending-invites-list.tsx +0 -256
  229. package/src/screens/network-viewer/connection-troubleshooter.tsx +0 -395
  230. package/src/screens/network-viewer/cpu-usage-graph.tsx +0 -294
  231. package/src/screens/network-viewer/device-details-modal.tsx +0 -339
  232. package/src/screens/network-viewer/group-details-modal.tsx +0 -421
  233. package/src/screens/network-viewer/index.ts +0 -8
  234. package/src/screens/network-viewer/network-viewer-ipc.test.ts +0 -72
  235. package/src/screens/network-viewer/network-viewer-ipc.ts +0 -39
  236. package/src/screens/network-viewer/network-viewer-section.ts +0 -12
  237. package/src/screens/network-viewer/network-viewer.section.test.tsx +0 -68
  238. package/src/screens/network-viewer/network-viewer.tsx +0 -708
  239. package/src/screens/network-viewer/remote-logs-panel.tsx +0 -190
  240. package/src/screens/network-viewer/sync-recovery.test.tsx +0 -114
  241. package/src/screens/network-viewer/sync-recovery.tsx +0 -461
  242. package/src/screens/network-viewer/usage-graph.tsx +0 -455
  243. package/src/screens/packages/local-folder-grants-panel.tsx +0 -290
  244. package/src/screens/packages/local-folders-ipc.ts +0 -28
  245. package/src/screens/packages/package-details.tsx +0 -166
  246. package/src/screens/packages/package-helpers.test.ts +0 -57
  247. package/src/screens/packages/package-helpers.ts +0 -137
  248. package/src/screens/packages/package-info.tsx +0 -354
  249. package/src/screens/packages/package-list.tsx +0 -519
  250. package/src/screens/packages/package-network-panel.tsx +0 -82
  251. package/src/screens/packages/package-new-local.tsx +0 -100
  252. package/src/screens/packages/package-runtime-status.test.tsx +0 -58
  253. package/src/screens/packages/package-runtime-status.tsx +0 -68
  254. package/src/screens/packages/package-versions.tsx +0 -298
  255. package/src/screens/packages/packages-ipc.test.ts +0 -47
  256. package/src/screens/packages/packages-ipc.ts +0 -125
  257. package/src/screens/peer-types/peer-type-details.tsx +0 -172
  258. package/src/screens/peer-types/peer-type-list.tsx +0 -64
  259. package/src/screens/search/global-search.tsx +0 -406
  260. package/src/screens/settings/color-mode-dropdown.tsx +0 -82
  261. package/src/screens/settings/settings-page.test.tsx +0 -24
  262. package/src/screens/settings/settings-page.tsx +0 -426
  263. package/src/screens/setup-user.tsx +0 -355
  264. package/src/screens/tools/tool-access-ipc.test.ts +0 -55
  265. package/src/screens/tools/tool-access-ipc.ts +0 -27
  266. package/src/screens/tools/tool-catalog-ipc.test.ts +0 -52
  267. package/src/screens/tools/tool-catalog-ipc.ts +0 -51
  268. package/src/screens/tools/tool-details.tsx +0 -52
  269. package/src/screens/tools/tool-info.tsx +0 -45
  270. package/src/screens/tools/tool-list.tsx +0 -106
  271. package/src/screens/tools/tool-schema.tsx +0 -44
  272. package/src/screens/tools/tool-test-details.tsx +0 -89
  273. package/src/screens/tools/tool-test-list.tsx +0 -73
  274. package/src/screens/variables/variable-details.tsx +0 -289
  275. package/src/screens/variables/variable-list.tsx +0 -110
  276. package/src/screens/welcome-modal.tsx +0 -294
  277. package/src/screens/workflows/workflow-details.tsx +0 -115
  278. package/src/screens/workflows/workflow-info.tsx +0 -22
  279. package/src/screens/workflows/workflow-instructions.tsx +0 -134
  280. package/src/screens/workflows/workflow-list.tsx +0 -117
  281. package/src/setupTests.ts +0 -38
  282. package/src/system-apps/assistants.app.ts +0 -7
  283. package/src/system-apps/console-logs.app.ts +0 -7
  284. package/src/system-apps/data-explorer.app.ts +0 -8
  285. package/src/system-apps/identity.app.ts +0 -9
  286. package/src/system-apps/index.ts +0 -77
  287. package/src/system-apps/mobile-settings.app.ts +0 -7
  288. package/src/system-apps/network-viewer.app.ts +0 -8
  289. package/src/system-apps/packages.app.ts +0 -7
  290. package/src/system-apps/search.app.ts +0 -8
  291. package/src/system-apps/settings.app.ts +0 -7
  292. package/src/system-apps/threads.app.ts +0 -7
  293. package/src/system-apps/tools.app.ts +0 -7
  294. package/src/system-apps/types.app.ts +0 -7
  295. package/src/system-apps/variables.app.ts +0 -7
  296. package/src/system-apps/workflows.app.ts +0 -7
  297. package/src/tabs-layout/network-status-indicator.test.tsx +0 -799
  298. package/src/tabs-layout/network-status-indicator.tsx +0 -756
  299. package/src/tabs-layout/tabs-layout.tsx +0 -857
  300. package/src/tabs-layout/tabs-state.test.ts +0 -152
  301. package/src/tabs-layout/tabs-state.ts +0 -587
  302. package/src/tabs-layout/use-network-status.test.tsx +0 -58
  303. package/src/tabs-layout/use-network-status.ts +0 -68
  304. package/src/ui-defaults/index.ts +0 -2
  305. package/src/ui-defaults/list-screen.tsx +0 -94
  306. package/src/ui-defaults/markdown-field.tsx +0 -87
  307. package/src/ui-router/routes-loader.ts +0 -193
  308. package/src/ui-router/ui-loader.test.tsx +0 -108
  309. package/src/ui-router/ui-loader.tsx +0 -606
  310. package/src/utils.ts +0 -95
  311. package/tsconfig.json +0 -18
@@ -1,190 +0,0 @@
1
- import type { IConsoleLog, INetworkRemoteLogsResult } from "@peers-app/peers-sdk";
2
- import { useCallback, useState } from "react";
3
- import { getNetworkDiagnosticsConsumer } from "./network-viewer-ipc";
4
-
5
- interface RemoteLogsPanelProps {
6
- deviceId: string;
7
- }
8
-
9
- function RemoteLogRow({ log }: { log: IConsoleLog }) {
10
- return (
11
- <div className="border-bottom py-2">
12
- <div className="d-flex flex-wrap gap-2 align-items-center small">
13
- <code>{new Date(log.timestamp).toLocaleTimeString()}</code>
14
- <span className={`badge ${log.level === "error" ? "bg-danger" : "bg-secondary"}`}>
15
- {log.level}
16
- </span>
17
- <span className="badge bg-info text-dark">{log.process}</span>
18
- {log.source && <span className="text-muted">{log.source}</span>}
19
- </div>
20
- <div className="mt-1" style={{ whiteSpace: "pre-wrap", overflowWrap: "anywhere" }}>
21
- {log.message}
22
- </div>
23
- {(log.context || log.stackTrace) && (
24
- <details className="mt-1">
25
- <summary className="small text-muted">Details</summary>
26
- <pre className="small bg-body-tertiary rounded p-2 mt-1" style={{ maxHeight: "240px" }}>
27
- {JSON.stringify({ context: log.context, stackTrace: log.stackTrace }, null, 2)}
28
- </pre>
29
- </details>
30
- )}
31
- </div>
32
- );
33
- }
34
-
35
- /** Read-only System Logs contract panel for a directly connected, provider-authorized device. */
36
- export function RemoteLogsPanel({ deviceId }: RemoteLogsPanelProps) {
37
- const [result, setResult] = useState<INetworkRemoteLogsResult | null>(null);
38
- const [loading, setLoading] = useState(false);
39
- const [error, setError] = useState<string>();
40
- const [processName, setProcessName] = useState("");
41
- const [level, setLevel] = useState("");
42
- const [search, setSearch] = useState("");
43
- const [minutes, setMinutes] = useState("60");
44
-
45
- const loadLogs = useCallback(async () => {
46
- setLoading(true);
47
- setError(undefined);
48
- try {
49
- const minutesNumber = Number(minutes);
50
- const sinceTimestamp =
51
- Number.isFinite(minutesNumber) && minutesNumber > 0
52
- ? Date.now() - minutesNumber * 60_000
53
- : undefined;
54
- const diagnostics = await getNetworkDiagnosticsConsumer();
55
- const response = await diagnostics.tools.queryRemoteLogs({
56
- deviceId,
57
- query: {
58
- sinceTimestamp,
59
- level: level ? (level as IConsoleLog["level"]) : undefined,
60
- process: processName || undefined,
61
- search: search || undefined,
62
- pageSize: 100,
63
- timeoutMs: 10_000,
64
- },
65
- });
66
- setResult(response);
67
- } catch (cause) {
68
- setError(cause instanceof Error ? cause.message : String(cause));
69
- } finally {
70
- setLoading(false);
71
- }
72
- }, [deviceId, level, minutes, processName, search]);
73
-
74
- const exportLogs = useCallback(() => {
75
- if (!result) return;
76
- const blob = new Blob([JSON.stringify(result, null, 2)], { type: "application/json" });
77
- const url = URL.createObjectURL(blob);
78
- const anchor = document.createElement("a");
79
- anchor.href = url;
80
- anchor.download = `remote-logs-${deviceId}-${result.queriedAt}.json`;
81
- anchor.click();
82
- URL.revokeObjectURL(url);
83
- }, [deviceId, result]);
84
-
85
- return (
86
- <div className="mb-4">
87
- <div className="d-flex justify-content-between align-items-center border-bottom pb-2 mb-3">
88
- <h6 className="mb-0">Remote Console Logs</h6>
89
- <div className="d-flex gap-2">
90
- <button
91
- type="button"
92
- className="btn btn-sm btn-outline-secondary"
93
- onClick={exportLogs}
94
- disabled={!result}
95
- >
96
- Export JSON
97
- </button>
98
- <button
99
- type="button"
100
- className="btn btn-sm btn-primary"
101
- onClick={() => void loadLogs()}
102
- disabled={loading}
103
- >
104
- {loading ? "Loading..." : result ? "Refresh" : "Load logs"}
105
- </button>
106
- </div>
107
- </div>
108
-
109
- <div className="row g-2 mb-3">
110
- <div className="col-md-3">
111
- <label className="form-label small" htmlFor="remote-logs-process">
112
- Process
113
- </label>
114
- <input
115
- id="remote-logs-process"
116
- className="form-control form-control-sm"
117
- value={processName}
118
- onChange={(event) => setProcessName(event.target.value)}
119
- placeholder="All processes"
120
- />
121
- </div>
122
- <div className="col-md-2">
123
- <label className="form-label small" htmlFor="remote-logs-level">
124
- Level
125
- </label>
126
- <select
127
- id="remote-logs-level"
128
- className="form-select form-select-sm"
129
- value={level}
130
- onChange={(event) => setLevel(event.target.value)}
131
- >
132
- <option value="">All</option>
133
- <option value="debug">Debug</option>
134
- <option value="info">Info</option>
135
- <option value="log">Log</option>
136
- <option value="warn">Warn</option>
137
- <option value="error">Error</option>
138
- </select>
139
- </div>
140
- <div className="col-md-2">
141
- <label className="form-label small" htmlFor="remote-logs-minutes">
142
- Time range
143
- </label>
144
- <select
145
- id="remote-logs-minutes"
146
- className="form-select form-select-sm"
147
- value={minutes}
148
- onChange={(event) => setMinutes(event.target.value)}
149
- >
150
- <option value="15">15 minutes</option>
151
- <option value="60">1 hour</option>
152
- <option value="360">6 hours</option>
153
- <option value="0">All retained</option>
154
- </select>
155
- </div>
156
- <div className="col-md-5">
157
- <label className="form-label small" htmlFor="remote-logs-search">
158
- Message words
159
- </label>
160
- <input
161
- id="remote-logs-search"
162
- className="form-control form-control-sm"
163
- value={search}
164
- onChange={(event) => setSearch(event.target.value)}
165
- placeholder="BrowserWebRTC"
166
- />
167
- </div>
168
- </div>
169
-
170
- {error && <div className="alert alert-danger py-2">{error}</div>}
171
- {result && (
172
- <>
173
- <div className="small text-muted mb-2">
174
- Showing {result.logs.length}
175
- {result.truncated ? " newest" : ""} matching logs
176
- {result.truncated ? "; narrow the filters to see a different slice" : ""}; queried{" "}
177
- {new Date(result.queriedAt).toLocaleString()}.
178
- </div>
179
- <div className="border rounded px-2" style={{ maxHeight: "420px", overflowY: "auto" }}>
180
- {result.logs.length ? (
181
- result.logs.map((log) => <RemoteLogRow key={log.logId} log={log} />)
182
- ) : (
183
- <div className="text-muted py-3 text-center">No matching remote logs.</div>
184
- )}
185
- </div>
186
- </>
187
- )}
188
- </div>
189
- );
190
- }
@@ -1,114 +0,0 @@
1
- import { fireEvent, render, screen } from "@testing-library/react";
2
- import { SyncRecoveryScreen } from "./sync-recovery";
3
-
4
- const mockResolveSyncRecovery = jest.fn(async () => ({
5
- success: false,
6
- message: "Permission denied for Shared Group: requires Owner",
7
- }));
8
-
9
- jest.mock("./network-viewer-ipc", () => ({
10
- getNetworkDiagnosticsConsumer: async () => ({
11
- tools: {
12
- getSyncRecoveryEntries: async () => ({
13
- entries: [
14
- {
15
- dataContextId: "personal",
16
- dataContextName: "Personal",
17
- syncRecoveryId: "queue-1",
18
- tableName: "Messages",
19
- recordId: "00mflddy2sbk393s47smn4tgl",
20
- firstFailedAt: Date.parse("2026-09-10T17:16:02Z"),
21
- lastFailedAt: Date.parse("2026-09-10T17:16:02Z"),
22
- attemptCount: 3,
23
- latestError:
24
- 'Validation on insert failed for Messages: [{"code":"custom","message":"assistant id was empty","path":["assistantId"]}]',
25
- status: "parked",
26
- parkedReason: "schema",
27
- stuck: true,
28
- localRowExists: false,
29
- recordSummary: "hello from the stored message",
30
- queuedRecordPreview: '{\n "message": "hello from the stored message"\n}',
31
- recordPreview: '{\n "message": "hello from the stored message"\n}',
32
- changeCreatedAt: Date.parse("2026-09-10T17:16:02Z"),
33
- },
34
- {
35
- dataContextId: "personal",
36
- dataContextName: "Personal",
37
- syncRecoveryId: "queue-2",
38
- tableName: "UniqueNames",
39
- recordId: "00mflddy2sbk393s47smn4tgm",
40
- firstFailedAt: Date.parse("2026-09-10T17:16:02Z"),
41
- lastFailedAt: Date.parse("2026-09-10T17:16:02Z"),
42
- attemptCount: 1,
43
- latestError: "UNIQUE constraint failed: UniqueNames.name",
44
- status: "parked",
45
- parkedReason: "unique-conflict",
46
- stuck: true,
47
- localRowExists: true,
48
- conflictingRecordId: "00mflddy2sbk393s47smn4tgn",
49
- tombstoneRecordId: "00mflddy2sbk393s47smn4tgm",
50
- recordSummary: "shared",
51
- keptRecordPreview: '{\n "name": "shared",\n "value": "local"\n}',
52
- queuedRecordPreview: '{\n "name": "shared",\n "value": "rejected"\n}',
53
- recordPreview: '{\n "name": "shared",\n "value": "local"\n}',
54
- },
55
- ],
56
- }),
57
- },
58
- observables: {
59
- status: {
60
- subscribe: () => ({ dispose() {} }),
61
- },
62
- },
63
- }),
64
- getNetworkControlConsumer: async () => ({
65
- tools: {
66
- resolveSyncRecovery: () => mockResolveSyncRecovery(),
67
- },
68
- }),
69
- }));
70
-
71
- describe("SyncRecoveryScreen", () => {
72
- it("shows the full error, status help, action help, and stored record", async () => {
73
- render(<SyncRecoveryScreen onBack={() => undefined} />);
74
-
75
- expect(await screen.findByText("hello from the stored message")).toBeTruthy();
76
- expect(screen.getByText(/Validation on insert failed/)).toBeTruthy();
77
- expect(screen.queryByText(/assistant id was empty/)).toBeNull();
78
-
79
- fireEvent.click(screen.getAllByRole("button", { name: "Show error details" })[0]);
80
- const error = screen.getByText(/assistant id was empty/);
81
- expect(error.tagName).toBe("PRE");
82
-
83
- fireEvent.click(screen.getByRole("button", { name: "About status Parked, schema" }));
84
- expect(screen.getByText(/does not match this device's rules/)).toBeTruthy();
85
-
86
- fireEvent.click(screen.getByRole("button", { name: "About these actions" }));
87
- expect(screen.getByText(/only the other row is stored/)).toBeTruthy();
88
-
89
- fireEvent.click(screen.getAllByRole("button", { name: "Show record details" })[0]);
90
- expect(screen.getByText(/Change written/)).toBeTruthy();
91
- expect(screen.getByText("Queued change")).toBeTruthy();
92
- expect(screen.getByText(/"message": "hello from the stored message"/)).toBeTruthy();
93
- });
94
-
95
- it("labels the row Keep will snapshot separately from a different queued change", async () => {
96
- render(<SyncRecoveryScreen onBack={() => undefined} />);
97
- fireEvent.click((await screen.findAllByRole("button", { name: "Show record details" }))[1]);
98
- expect(screen.getByText("This device's version")).toBeTruthy();
99
- expect(screen.getByText(/"value": "local"/)).toBeTruthy();
100
- expect(screen.getByText("Queued change")).toBeTruthy();
101
- expect(screen.getByText(/"value": "rejected"/)).toBeTruthy();
102
- expect(screen.getByText(/tombstones this queued id/)).toBeTruthy();
103
- expect(screen.queryByText(/Keep deletes/)).toBeNull();
104
- });
105
-
106
- it("keeps a failed action message after the list reloads", async () => {
107
- render(<SyncRecoveryScreen onBack={() => undefined} />);
108
- fireEvent.click((await screen.findAllByRole("button", { name: "Ignore on this device" }))[0]);
109
- expect(
110
- await screen.findByText("Permission denied for Shared Group: requires Owner"),
111
- ).toBeTruthy();
112
- expect(screen.getByText("hello from the stored message")).toBeTruthy();
113
- });
114
- });