@peers-app/peers-ui 0.14.0 → 0.15.0

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 (438) hide show
  1. package/.github/workflows/publish.yml +8 -5
  2. package/babel.config.js +4 -4
  3. package/biome.json +191 -0
  4. package/dist/command-palette/command-palette-ui.d.ts +1 -2
  5. package/dist/command-palette/command-palette-ui.js +175 -244
  6. package/dist/command-palette/command-palette.js +65 -64
  7. package/dist/components/chat-overlay.d.ts +2 -2
  8. package/dist/components/chat-overlay.js +160 -217
  9. package/dist/components/checkbox.d.ts +5 -4
  10. package/dist/components/checkbox.js +4 -7
  11. package/dist/components/group-switcher.d.ts +1 -2
  12. package/dist/components/group-switcher.js +119 -159
  13. package/dist/components/input-date.d.ts +3 -3
  14. package/dist/components/input-date.js +6 -6
  15. package/dist/components/input-number.d.ts +7 -6
  16. package/dist/components/input-number.js +25 -20
  17. package/dist/components/input.d.ts +5 -4
  18. package/dist/components/input.js +4 -7
  19. package/dist/components/inverse-lazy-list.d.ts +3 -3
  20. package/dist/components/inverse-lazy-list.js +13 -47
  21. package/dist/components/io-schema-values.d.ts +5 -6
  22. package/dist/components/io-schema-values.js +28 -65
  23. package/dist/components/io-schema.d.ts +4 -5
  24. package/dist/components/io-schema.js +42 -79
  25. package/dist/components/lazy-list.d.ts +3 -3
  26. package/dist/components/lazy-list.js +38 -58
  27. package/dist/components/list-screen.d.ts +3 -8
  28. package/dist/components/list-screen.js +28 -23
  29. package/dist/components/loading-indicator.d.ts +1 -2
  30. package/dist/components/loading-indicator.js +2 -6
  31. package/dist/components/markdown-editor/autolink-plugin.js +5 -8
  32. package/dist/components/markdown-editor/editor-inline.d.ts +2 -3
  33. package/dist/components/markdown-editor/editor-inline.js +2 -6
  34. package/dist/components/markdown-editor/editor.d.ts +6 -6
  35. package/dist/components/markdown-editor/editor.js +9 -19
  36. package/dist/components/markdown-editor/markdown-plugin.d.ts +1 -1
  37. package/dist/components/markdown-editor/markdown-plugin.js +20 -21
  38. package/dist/components/markdown-editor/mention-node.d.ts +2 -2
  39. package/dist/components/markdown-editor/mention-node.js +24 -24
  40. package/dist/components/markdown-editor/mentions-plugin.d.ts +2 -2
  41. package/dist/components/markdown-editor/mentions-plugin.js +61 -62
  42. package/dist/components/markdown-editor/theme.js +28 -28
  43. package/dist/components/markdown-editor/toolbar.d.ts +2 -3
  44. package/dist/components/markdown-editor/toolbar.js +32 -49
  45. package/dist/components/markdown-with-mentions.d.ts +1 -1
  46. package/dist/components/markdown-with-mentions.js +43 -43
  47. package/dist/components/message-logs/message-logs.d.ts +1 -2
  48. package/dist/components/message-logs/message-logs.js +91 -116
  49. package/dist/components/messages/avatar.d.ts +3 -4
  50. package/dist/components/messages/avatar.js +37 -46
  51. package/dist/components/messages/channel-message-list.d.ts +5 -6
  52. package/dist/components/messages/channel-message-list.js +34 -34
  53. package/dist/components/messages/channel-view.d.ts +1 -2
  54. package/dist/components/messages/channel-view.js +23 -57
  55. package/dist/components/messages/message-compose.d.ts +3 -4
  56. package/dist/components/messages/message-compose.js +27 -38
  57. package/dist/components/messages/message-display.d.ts +2 -3
  58. package/dist/components/messages/message-display.js +42 -95
  59. package/dist/components/messages/thread-message-list.d.ts +4 -5
  60. package/dist/components/messages/thread-message-list.js +29 -29
  61. package/dist/components/router.d.ts +1 -2
  62. package/dist/components/router.js +58 -66
  63. package/dist/components/save-button.d.ts +3 -3
  64. package/dist/components/save-button.js +23 -33
  65. package/dist/components/sortable-list.d.ts +11 -12
  66. package/dist/components/sortable-list.js +42 -22
  67. package/dist/components/tabs.d.ts +3 -3
  68. package/dist/components/tabs.js +16 -47
  69. package/dist/components/tooltip.d.ts +4 -4
  70. package/dist/components/tooltip.js +4 -9
  71. package/dist/components/trust-level-badge.d.ts +2 -3
  72. package/dist/components/trust-level-badge.js +16 -16
  73. package/dist/components/trust-level-dropdown.d.ts +3 -4
  74. package/dist/components/trust-level-dropdown.js +32 -55
  75. package/dist/components/typeahead.d.ts +3 -3
  76. package/dist/components/typeahead.js +48 -89
  77. package/dist/components/voice-indicator.d.ts +2 -2
  78. package/dist/components/voice-indicator.js +93 -106
  79. package/dist/components/voice-subscribe-events.d.ts +32 -0
  80. package/dist/components/voice-subscribe-events.js +2 -0
  81. package/dist/globals.d.ts +3 -5
  82. package/dist/globals.js +22 -33
  83. package/dist/hooks.d.ts +5 -5
  84. package/dist/hooks.js +22 -12
  85. package/dist/hooks.test.js +129 -145
  86. package/dist/index.d.ts +9 -8
  87. package/dist/index.js +13 -12
  88. package/dist/mention-configs.d.ts +2 -2
  89. package/dist/mention-configs.js +55 -42
  90. package/dist/screens/assistants/assistant-config.d.ts +2 -3
  91. package/dist/screens/assistants/assistant-config.js +9 -22
  92. package/dist/screens/assistants/assistant-details.d.ts +1 -2
  93. package/dist/screens/assistants/assistant-details.js +13 -28
  94. package/dist/screens/assistants/assistant-info.d.ts +2 -3
  95. package/dist/screens/assistants/assistant-info.js +3 -17
  96. package/dist/screens/assistants/assistant-list.d.ts +1 -2
  97. package/dist/screens/assistants/assistant-list.js +15 -56
  98. package/dist/screens/assistants/assistant-tools.d.ts +2 -3
  99. package/dist/screens/assistants/assistant-tools.js +10 -24
  100. package/dist/screens/console-logs/console-logs-list.d.ts +1 -2
  101. package/dist/screens/console-logs/console-logs-list.js +130 -134
  102. package/dist/screens/console-logs/log-display.d.ts +2 -3
  103. package/dist/screens/console-logs/log-display.js +40 -42
  104. package/dist/screens/console-logs/log-filters.d.ts +1 -2
  105. package/dist/screens/console-logs/log-filters.js +2 -24
  106. package/dist/screens/console-logs/mobile-log-card.d.ts +2 -3
  107. package/dist/screens/console-logs/mobile-log-card.js +64 -67
  108. package/dist/screens/console-logs/resizable-table-header.d.ts +1 -2
  109. package/dist/screens/console-logs/resizable-table-header.js +31 -67
  110. package/dist/screens/contacts/contact-details.d.ts +1 -2
  111. package/dist/screens/contacts/contact-details.js +16 -46
  112. package/dist/screens/contacts/contact-list.d.ts +1 -2
  113. package/dist/screens/contacts/contact-list.js +44 -103
  114. package/dist/screens/contacts/index.d.ts +4 -4
  115. package/dist/screens/contacts/index.js +1 -1
  116. package/dist/screens/contacts/user-connect.d.ts +1 -2
  117. package/dist/screens/contacts/user-connect.js +85 -186
  118. package/dist/screens/data-explorer/data-explorer.d.ts +1 -2
  119. package/dist/screens/data-explorer/data-explorer.js +61 -181
  120. package/dist/screens/data-explorer/index.d.ts +2 -2
  121. package/dist/screens/data-explorer/query-executor.d.ts +1 -2
  122. package/dist/screens/data-explorer/query-executor.js +56 -166
  123. package/dist/screens/groups/group-details.d.ts +1 -2
  124. package/dist/screens/groups/group-details.js +27 -122
  125. package/dist/screens/groups/group-invite-listener.d.ts +2 -3
  126. package/dist/screens/groups/group-invite-listener.js +8 -104
  127. package/dist/screens/groups/group-list.d.ts +1 -2
  128. package/dist/screens/groups/group-list.js +56 -133
  129. package/dist/screens/groups/group-members.d.ts +2 -3
  130. package/dist/screens/groups/group-members.js +62 -132
  131. package/dist/screens/groups/index.d.ts +4 -4
  132. package/dist/screens/groups/index.js +1 -1
  133. package/dist/screens/join-group/index.d.ts +2 -2
  134. package/dist/screens/join-group/join-group.d.ts +1 -2
  135. package/dist/screens/join-group/join-group.js +9 -109
  136. package/dist/screens/network-viewer/connection-troubleshooter.d.ts +2 -3
  137. package/dist/screens/network-viewer/connection-troubleshooter.js +89 -193
  138. package/dist/screens/network-viewer/cpu-usage-graph.d.ts +1 -2
  139. package/dist/screens/network-viewer/cpu-usage-graph.js +60 -99
  140. package/dist/screens/network-viewer/device-details-modal.d.ts +1 -2
  141. package/dist/screens/network-viewer/device-details-modal.js +25 -177
  142. package/dist/screens/network-viewer/group-details-modal.d.ts +1 -2
  143. package/dist/screens/network-viewer/group-details-modal.js +31 -142
  144. package/dist/screens/network-viewer/index.d.ts +4 -4
  145. package/dist/screens/network-viewer/index.js +3 -3
  146. package/dist/screens/network-viewer/network-viewer-ipc.d.ts +22 -0
  147. package/dist/screens/network-viewer/network-viewer-ipc.js +6 -0
  148. package/dist/screens/network-viewer/network-viewer.d.ts +1 -2
  149. package/dist/screens/network-viewer/network-viewer.js +91 -296
  150. package/dist/screens/network-viewer/usage-graph.d.ts +1 -2
  151. package/dist/screens/network-viewer/usage-graph.js +78 -110
  152. package/dist/screens/packages/package-details.d.ts +1 -2
  153. package/dist/screens/packages/package-details.js +35 -41
  154. package/dist/screens/packages/package-info.d.ts +2 -2
  155. package/dist/screens/packages/package-info.js +33 -86
  156. package/dist/screens/packages/package-list.d.ts +1 -2
  157. package/dist/screens/packages/package-list.js +42 -106
  158. package/dist/screens/packages/package-new-local.d.ts +1 -2
  159. package/dist/screens/packages/package-new-local.js +13 -19
  160. package/dist/screens/packages/package-versions.d.ts +2 -3
  161. package/dist/screens/packages/package-versions.js +29 -96
  162. package/dist/screens/peer-types/peer-type-details.d.ts +3 -4
  163. package/dist/screens/peer-types/peer-type-details.js +26 -78
  164. package/dist/screens/peer-types/peer-type-list.d.ts +1 -2
  165. package/dist/screens/peer-types/peer-type-list.js +13 -24
  166. package/dist/screens/search/global-search.d.ts +1 -2
  167. package/dist/screens/search/global-search.js +104 -182
  168. package/dist/screens/settings/color-mode-dropdown.d.ts +3 -4
  169. package/dist/screens/settings/color-mode-dropdown.js +18 -37
  170. package/dist/screens/settings/settings-page.d.ts +1 -1
  171. package/dist/screens/settings/settings-page.js +86 -213
  172. package/dist/screens/settings/voice-settings-agent.d.ts +1 -1
  173. package/dist/screens/settings/voice-settings-agent.js +7 -44
  174. package/dist/screens/settings/voice-settings-api-keys.d.ts +2 -2
  175. package/dist/screens/settings/voice-settings-api-keys.js +2 -29
  176. package/dist/screens/settings/voice-settings-output.d.ts +2 -2
  177. package/dist/screens/settings/voice-settings-output.js +2 -40
  178. package/dist/screens/settings/voice-settings-providers.d.ts +2 -2
  179. package/dist/screens/settings/voice-settings-providers.js +2 -19
  180. package/dist/screens/settings/voice-settings-types.d.ts +4 -4
  181. package/dist/screens/settings/voice-settings-types.js +31 -31
  182. package/dist/screens/settings/voice-settings-wake-word.d.ts +2 -2
  183. package/dist/screens/settings/voice-settings-wake-word.js +2 -33
  184. package/dist/screens/settings/voice-settings.d.ts +1 -1
  185. package/dist/screens/settings/voice-settings.js +35 -112
  186. package/dist/screens/setup-user.d.ts +1 -2
  187. package/dist/screens/setup-user.js +38 -116
  188. package/dist/screens/tools/tool-code.d.ts +2 -3
  189. package/dist/screens/tools/tool-code.js +9 -13
  190. package/dist/screens/tools/tool-details.d.ts +1 -2
  191. package/dist/screens/tools/tool-details.js +26 -39
  192. package/dist/screens/tools/tool-info.d.ts +2 -3
  193. package/dist/screens/tools/tool-info.js +9 -48
  194. package/dist/screens/tools/tool-list.d.ts +1 -2
  195. package/dist/screens/tools/tool-list.js +33 -65
  196. package/dist/screens/tools/tool-schema.d.ts +2 -3
  197. package/dist/screens/tools/tool-schema.js +2 -13
  198. package/dist/screens/tools/tool-test-details.d.ts +1 -2
  199. package/dist/screens/tools/tool-test-details.js +12 -28
  200. package/dist/screens/tools/tool-test-list.d.ts +1 -2
  201. package/dist/screens/tools/tool-test-list.js +17 -56
  202. package/dist/screens/variables/variable-details.d.ts +1 -2
  203. package/dist/screens/variables/variable-details.js +19 -86
  204. package/dist/screens/variables/variable-list.d.ts +1 -2
  205. package/dist/screens/variables/variable-list.js +16 -27
  206. package/dist/screens/welcome-modal.d.ts +1 -2
  207. package/dist/screens/welcome-modal.js +44 -111
  208. package/dist/screens/workflows/workflow-details.d.ts +1 -2
  209. package/dist/screens/workflows/workflow-details.js +17 -31
  210. package/dist/screens/workflows/workflow-info.d.ts +2 -3
  211. package/dist/screens/workflows/workflow-info.js +2 -9
  212. package/dist/screens/workflows/workflow-instructions.d.ts +2 -3
  213. package/dist/screens/workflows/workflow-instructions.js +23 -55
  214. package/dist/screens/workflows/workflow-list.d.ts +1 -2
  215. package/dist/screens/workflows/workflow-list.js +23 -62
  216. package/dist/setupTests.d.ts +1 -1
  217. package/dist/setupTests.js +10 -11
  218. package/dist/system-apps/assistants.app.d.ts +1 -1
  219. package/dist/system-apps/assistants.app.js +3 -3
  220. package/dist/system-apps/console-logs.app.d.ts +1 -1
  221. package/dist/system-apps/console-logs.app.js +3 -3
  222. package/dist/system-apps/contacts.app.d.ts +1 -1
  223. package/dist/system-apps/contacts.app.js +4 -4
  224. package/dist/system-apps/data-explorer.app.d.ts +1 -1
  225. package/dist/system-apps/data-explorer.app.js +4 -4
  226. package/dist/system-apps/groups.app.d.ts +1 -1
  227. package/dist/system-apps/groups.app.js +4 -4
  228. package/dist/system-apps/index.d.ts +17 -17
  229. package/dist/system-apps/index.js +52 -52
  230. package/dist/system-apps/join-group.app.d.ts +1 -1
  231. package/dist/system-apps/join-group.app.js +4 -4
  232. package/dist/system-apps/mobile-settings.app.d.ts +1 -1
  233. package/dist/system-apps/mobile-settings.app.js +3 -3
  234. package/dist/system-apps/network-viewer.app.d.ts +1 -1
  235. package/dist/system-apps/network-viewer.app.js +4 -4
  236. package/dist/system-apps/packages.app.d.ts +1 -1
  237. package/dist/system-apps/packages.app.js +3 -3
  238. package/dist/system-apps/search.app.d.ts +1 -1
  239. package/dist/system-apps/search.app.js +4 -4
  240. package/dist/system-apps/settings.app.d.ts +1 -1
  241. package/dist/system-apps/settings.app.js +3 -3
  242. package/dist/system-apps/threads.app.d.ts +1 -1
  243. package/dist/system-apps/threads.app.js +3 -3
  244. package/dist/system-apps/tools.app.d.ts +1 -1
  245. package/dist/system-apps/tools.app.js +3 -3
  246. package/dist/system-apps/types.app.d.ts +1 -1
  247. package/dist/system-apps/types.app.js +3 -3
  248. package/dist/system-apps/variables.app.d.ts +1 -1
  249. package/dist/system-apps/variables.app.js +3 -3
  250. package/dist/system-apps/workflows.app.d.ts +1 -1
  251. package/dist/system-apps/workflows.app.js +3 -3
  252. package/dist/tabs-layout/tabs-layout.d.ts +2 -3
  253. package/dist/tabs-layout/tabs-layout.js +215 -246
  254. package/dist/tabs-layout/tabs-state.d.ts +2 -2
  255. package/dist/tabs-layout/tabs-state.js +73 -61
  256. package/dist/ui-defaults/index.d.ts +2 -2
  257. package/dist/ui-defaults/list-screen.d.ts +2 -3
  258. package/dist/ui-defaults/list-screen.js +33 -37
  259. package/dist/ui-defaults/markdown-field.js +24 -56
  260. package/dist/ui-router/routes-loader.d.ts +1 -1
  261. package/dist/ui-router/routes-loader.js +17 -13
  262. package/dist/ui-router/ui-loader.d.ts +6 -6
  263. package/dist/ui-router/ui-loader.js +172 -268
  264. package/dist/utils.js +49 -39
  265. package/jest.config.js +16 -16
  266. package/package.json +16 -14
  267. package/src/command-palette/command-palette-ui.tsx +261 -237
  268. package/src/command-palette/command-palette.ts +81 -78
  269. package/src/components/chat-overlay.tsx +366 -261
  270. package/src/components/checkbox.tsx +15 -12
  271. package/src/components/group-switcher.tsx +150 -105
  272. package/src/components/input-date.tsx +17 -16
  273. package/src/components/input-number.tsx +47 -31
  274. package/src/components/input.tsx +15 -12
  275. package/src/components/inverse-lazy-list.tsx +14 -13
  276. package/src/components/io-schema-values.tsx +51 -69
  277. package/src/components/io-schema.tsx +94 -69
  278. package/src/components/lazy-list.tsx +51 -34
  279. package/src/components/list-screen.tsx +51 -35
  280. package/src/components/loading-indicator.tsx +2 -4
  281. package/src/components/markdown-editor/autolink-plugin.tsx +4 -11
  282. package/src/components/markdown-editor/editor-inline.tsx +3 -4
  283. package/src/components/markdown-editor/editor.tsx +53 -51
  284. package/src/components/markdown-editor/markdown-plugin.tsx +48 -40
  285. package/src/components/markdown-editor/mention-node.ts +39 -38
  286. package/src/components/markdown-editor/mentions-plugin.tsx +99 -101
  287. package/src/components/markdown-editor/theme.ts +28 -29
  288. package/src/components/markdown-editor/toolbar.tsx +53 -47
  289. package/src/components/markdown-with-mentions.tsx +56 -46
  290. package/src/components/message-logs/message-logs.tsx +225 -165
  291. package/src/components/messages/avatar.tsx +70 -52
  292. package/src/components/messages/channel-message-list.tsx +80 -68
  293. package/src/components/messages/channel-view.tsx +34 -33
  294. package/src/components/messages/message-compose.tsx +84 -67
  295. package/src/components/messages/message-display.tsx +103 -89
  296. package/src/components/messages/thread-message-list.tsx +53 -44
  297. package/src/components/router.tsx +42 -43
  298. package/src/components/save-button.tsx +43 -39
  299. package/src/components/sortable-list.tsx +77 -49
  300. package/src/components/tabs.tsx +31 -31
  301. package/src/components/tooltip.tsx +21 -28
  302. package/src/components/trust-level-badge.tsx +15 -11
  303. package/src/components/trust-level-dropdown.tsx +49 -19
  304. package/src/components/typeahead.tsx +57 -59
  305. package/src/components/voice-indicator.tsx +158 -141
  306. package/src/components/voice-subscribe-events.ts +20 -0
  307. package/src/globals.tsx +42 -40
  308. package/src/hooks.test.tsx +141 -134
  309. package/src/hooks.ts +80 -48
  310. package/src/index.tsx +17 -10
  311. package/src/mention-configs.ts +122 -68
  312. package/src/screens/assistants/assistant-config.tsx +28 -18
  313. package/src/screens/assistants/assistant-details.tsx +35 -36
  314. package/src/screens/assistants/assistant-info.tsx +16 -11
  315. package/src/screens/assistants/assistant-list.tsx +37 -34
  316. package/src/screens/assistants/assistant-tools.tsx +41 -20
  317. package/src/screens/console-logs/console-logs-list.tsx +173 -140
  318. package/src/screens/console-logs/log-display.tsx +65 -38
  319. package/src/screens/console-logs/log-filters.tsx +4 -3
  320. package/src/screens/console-logs/mobile-log-card.tsx +78 -71
  321. package/src/screens/console-logs/resizable-table-header.tsx +29 -21
  322. package/src/screens/contacts/contact-details.tsx +29 -30
  323. package/src/screens/contacts/contact-list.tsx +71 -60
  324. package/src/screens/contacts/index.ts +5 -5
  325. package/src/screens/contacts/user-connect.tsx +177 -171
  326. package/src/screens/data-explorer/data-explorer.tsx +134 -98
  327. package/src/screens/data-explorer/index.ts +2 -3
  328. package/src/screens/data-explorer/query-executor.tsx +90 -80
  329. package/src/screens/groups/group-details.tsx +120 -101
  330. package/src/screens/groups/group-invite-listener.tsx +34 -37
  331. package/src/screens/groups/group-list.tsx +119 -103
  332. package/src/screens/groups/group-members.tsx +225 -164
  333. package/src/screens/groups/index.ts +5 -6
  334. package/src/screens/join-group/index.ts +2 -2
  335. package/src/screens/join-group/join-group.tsx +41 -39
  336. package/src/screens/network-viewer/connection-troubleshooter.tsx +145 -104
  337. package/src/screens/network-viewer/cpu-usage-graph.tsx +39 -43
  338. package/src/screens/network-viewer/device-details-modal.tsx +46 -59
  339. package/src/screens/network-viewer/group-details-modal.tsx +68 -49
  340. package/src/screens/network-viewer/index.ts +4 -5
  341. package/src/screens/network-viewer/network-viewer-ipc.ts +23 -0
  342. package/src/screens/network-viewer/network-viewer.tsx +261 -236
  343. package/src/screens/network-viewer/usage-graph.tsx +57 -49
  344. package/src/screens/packages/package-details.tsx +43 -35
  345. package/src/screens/packages/package-info.tsx +107 -66
  346. package/src/screens/packages/package-list.tsx +175 -98
  347. package/src/screens/packages/package-new-local.tsx +28 -26
  348. package/src/screens/packages/package-versions.tsx +102 -77
  349. package/src/screens/peer-types/peer-type-details.tsx +60 -50
  350. package/src/screens/peer-types/peer-type-list.tsx +20 -30
  351. package/src/screens/search/global-search.tsx +153 -137
  352. package/src/screens/settings/color-mode-dropdown.tsx +52 -35
  353. package/src/screens/settings/settings-page.tsx +215 -141
  354. package/src/screens/settings/voice-settings-agent.tsx +13 -12
  355. package/src/screens/settings/voice-settings-api-keys.tsx +14 -12
  356. package/src/screens/settings/voice-settings-output.tsx +12 -11
  357. package/src/screens/settings/voice-settings-providers.tsx +7 -3
  358. package/src/screens/settings/voice-settings-types.ts +52 -49
  359. package/src/screens/settings/voice-settings-wake-word.tsx +25 -9
  360. package/src/screens/settings/voice-settings.tsx +66 -43
  361. package/src/screens/setup-user.tsx +88 -41
  362. package/src/screens/tools/tool-code.tsx +12 -17
  363. package/src/screens/tools/tool-details.tsx +28 -28
  364. package/src/screens/tools/tool-info.tsx +14 -19
  365. package/src/screens/tools/tool-list.tsx +58 -40
  366. package/src/screens/tools/tool-schema.tsx +16 -9
  367. package/src/screens/tools/tool-test-details.tsx +11 -22
  368. package/src/screens/tools/tool-test-list.tsx +29 -30
  369. package/src/screens/variables/variable-details.tsx +63 -51
  370. package/src/screens/variables/variable-list.tsx +29 -30
  371. package/src/screens/welcome-modal.tsx +68 -48
  372. package/src/screens/workflows/workflow-details.tsx +40 -30
  373. package/src/screens/workflows/workflow-info.tsx +4 -11
  374. package/src/screens/workflows/workflow-instructions.tsx +35 -28
  375. package/src/screens/workflows/workflow-list.tsx +50 -40
  376. package/src/setupTests.ts +14 -13
  377. package/src/system-apps/assistants.app.ts +5 -5
  378. package/src/system-apps/console-logs.app.ts +4 -4
  379. package/src/system-apps/contacts.app.ts +6 -6
  380. package/src/system-apps/data-explorer.app.ts +5 -5
  381. package/src/system-apps/groups.app.ts +6 -6
  382. package/src/system-apps/index.ts +49 -49
  383. package/src/system-apps/join-group.app.ts +5 -5
  384. package/src/system-apps/mobile-settings.app.ts +4 -5
  385. package/src/system-apps/network-viewer.app.ts +5 -5
  386. package/src/system-apps/packages.app.ts +5 -5
  387. package/src/system-apps/search.app.ts +6 -6
  388. package/src/system-apps/settings.app.ts +5 -5
  389. package/src/system-apps/threads.app.ts +5 -5
  390. package/src/system-apps/tools.app.ts +5 -5
  391. package/src/system-apps/types.app.ts +5 -5
  392. package/src/system-apps/variables.app.ts +5 -5
  393. package/src/system-apps/workflows.app.ts +5 -5
  394. package/src/tabs-layout/tabs-layout.tsx +345 -254
  395. package/src/tabs-layout/tabs-state.ts +100 -81
  396. package/src/ui-defaults/index.ts +2 -3
  397. package/src/ui-defaults/list-screen.tsx +45 -40
  398. package/src/ui-defaults/markdown-field.tsx +22 -26
  399. package/src/ui-router/routes-loader.ts +40 -24
  400. package/src/ui-router/ui-loader.tsx +312 -214
  401. package/src/utils.ts +68 -81
  402. package/tsconfig.json +5 -10
  403. package/dist/components/input-datetime.d.ts +0 -7
  404. package/dist/components/input-datetime.js +0 -35
  405. package/dist/components/lazy-sortable-list.d.ts +0 -29
  406. package/dist/components/lazy-sortable-list.js +0 -12
  407. package/dist/components/left-bar.d.ts +0 -5
  408. package/dist/components/left-bar.js +0 -207
  409. package/dist/components/main-content-container.d.ts +0 -2
  410. package/dist/components/main-content-container.js +0 -92
  411. package/dist/components/messages/thread-view.d.ts +0 -6
  412. package/dist/components/messages/thread-view.js +0 -174
  413. package/dist/components/off-canvas.d.ts +0 -13
  414. package/dist/components/off-canvas.js +0 -89
  415. package/dist/components/text-list-editor.tsx/text-list-editor.d.ts +0 -6
  416. package/dist/components/text-list-editor.tsx/text-list-editor.js +0 -13
  417. package/dist/components/top-bar.d.ts +0 -2
  418. package/dist/components/top-bar.js +0 -51
  419. package/dist/components/typeahead/mentions-plugin.d.ts +0 -7
  420. package/dist/components/typeahead/mentions-plugin.js +0 -203
  421. package/dist/components/typeahead/typeahead-editor.d.ts +0 -15
  422. package/dist/components/typeahead/typeahead-editor.js +0 -134
  423. package/dist/components/typeahead/typeahead.d.ts +0 -12
  424. package/dist/components/typeahead/typeahead.js +0 -94
  425. package/dist/screens/profile.d.ts +0 -2
  426. package/dist/screens/profile.js +0 -76
  427. package/src/components/input-datetime.tsx +0 -41
  428. package/src/components/lazy-sortable-list.tsx +0 -51
  429. package/src/components/left-bar.tsx +0 -322
  430. package/src/components/main-content-container.tsx +0 -79
  431. package/src/components/messages/thread-view.tsx +0 -214
  432. package/src/components/off-canvas.tsx +0 -83
  433. package/src/components/text-list-editor.tsx/text-list-editor.tsx +0 -13
  434. package/src/components/top-bar.tsx +0 -119
  435. package/src/components/typeahead/mentions-plugin.tsx +0 -265
  436. package/src/components/typeahead/typeahead-editor.tsx +0 -140
  437. package/src/components/typeahead/typeahead.tsx +0 -77
  438. package/src/screens/profile.tsx +0 -75
@@ -1,30 +1,31 @@
1
1
  /**
2
2
  * Join Group screen - allows users to join a group by entering an invitation password.
3
- *
3
+ *
4
4
  * Flow:
5
5
  * 1. User enters the invitation password
6
6
  * 2. System discovers all devices listening for that password
7
7
  * 3. User selects a group/device to join
8
8
  * 4. System sends join request and waits for approval
9
- *
9
+ *
10
10
  * Communicates with device layer through pvars (not direct imports).
11
11
  */
12
12
 
13
- import React, { useState, useCallback, useEffect } from "react";
14
13
  import {
15
14
  getUserContext,
16
- groupJoinStatus,
15
+ groupInviteDiscover,
17
16
  groupInviteDiscoveryResult,
18
17
  groupInviteJoinResult,
19
- groupInviteDiscover,
20
18
  groupInviteSendRequest,
21
- IGroupInviteListenerInfo,
19
+ groupJoinStatus,
20
+ type IGroupInviteListenerInfo,
22
21
  isValidInvitePassword,
23
22
  } from "@peers-app/peers-sdk";
23
+ import type React from "react";
24
+ import { useCallback, useEffect, useState } from "react";
24
25
  import { LoadingIndicator } from "../../components/loading-indicator";
25
- import { usePromise, useObservable } from "../../hooks";
26
- import { registerInternalPeersUI } from "../../ui-router/ui-loader";
27
26
  import { mainContentPath } from "../../globals";
27
+ import { useObservable, usePromise } from "../../hooks";
28
+ import { registerInternalPeersUI } from "../../ui-router/ui-loader";
28
29
 
29
30
  export const JoinGroup = () => {
30
31
  const userContext = usePromise(() => getUserContext());
@@ -34,7 +35,9 @@ export const JoinGroup = () => {
34
35
  const [isSearching, setIsSearching] = useState(false);
35
36
  const [isJoining, setIsJoining] = useState(false);
36
37
  const [error, setError] = useState<string | null>(null);
37
- const [currentJoiningGroup, setCurrentJoiningGroup] = useState<IGroupInviteListenerInfo | null>(null);
38
+ const [_currentJoiningGroup, setCurrentJoiningGroup] = useState<IGroupInviteListenerInfo | null>(
39
+ null,
40
+ );
38
41
 
39
42
  // Observable state from device layer
40
43
  const [status] = useObservable(groupJoinStatus);
@@ -63,7 +66,7 @@ export const JoinGroup = () => {
63
66
 
64
67
  setError(null);
65
68
  setIsSearching(true);
66
-
69
+
67
70
  // Clear previous results and trigger discovery
68
71
  groupInviteDiscoveryResult([]);
69
72
  groupInviteJoinResult(null);
@@ -71,15 +74,18 @@ export const JoinGroup = () => {
71
74
  }, [password]);
72
75
 
73
76
  // Join a group (set pvar, device layer reacts)
74
- const handleJoin = useCallback((listener: IGroupInviteListenerInfo) => {
75
- setIsJoining(true);
76
- setError(null);
77
- setCurrentJoiningGroup(listener);
78
-
79
- // Clear previous result and trigger join request
80
- groupInviteJoinResult(null);
81
- groupInviteSendRequest({ listener, password });
82
- }, [password]);
77
+ const handleJoin = useCallback(
78
+ (listener: IGroupInviteListenerInfo) => {
79
+ setIsJoining(true);
80
+ setError(null);
81
+ setCurrentJoiningGroup(listener);
82
+
83
+ // Clear previous result and trigger join request
84
+ groupInviteJoinResult(null);
85
+ groupInviteSendRequest({ listener, password });
86
+ },
87
+ [password],
88
+ );
83
89
 
84
90
  // Reset state
85
91
  const handleReset = useCallback(() => {
@@ -94,11 +100,14 @@ export const JoinGroup = () => {
94
100
  }, []);
95
101
 
96
102
  // Handle Enter key
97
- const handleKeyDown = useCallback((e: React.KeyboardEvent) => {
98
- if (e.key === "Enter" && password && !isSearching) {
99
- handleSearch();
100
- }
101
- }, [password, isSearching, handleSearch]);
103
+ const handleKeyDown = useCallback(
104
+ (e: React.KeyboardEvent) => {
105
+ if (e.key === "Enter" && password && !isSearching) {
106
+ handleSearch();
107
+ }
108
+ },
109
+ [password, isSearching, handleSearch],
110
+ );
102
111
 
103
112
  if (!userContext) {
104
113
  return <LoadingIndicator />;
@@ -111,9 +120,7 @@ export const JoinGroup = () => {
111
120
  <i className="bi-box-arrow-in-right me-2" />
112
121
  Join Group
113
122
  </h2>
114
- <p className="text-muted">
115
- Enter the invitation password to find and join a group
116
- </p>
123
+ <p className="text-muted">Enter the invitation password to find and join a group</p>
117
124
  </div>
118
125
 
119
126
  {/* Success state */}
@@ -150,7 +157,6 @@ export const JoinGroup = () => {
150
157
  onKeyDown={handleKeyDown}
151
158
  placeholder="Enter password (e.g., apple-banana-cherry-date)"
152
159
  disabled={isSearching || isJoining}
153
- autoFocus
154
160
  />
155
161
  <button
156
162
  className="btn btn-primary"
@@ -170,9 +176,7 @@ export const JoinGroup = () => {
170
176
  )}
171
177
  </button>
172
178
  </div>
173
- <small className="text-muted">
174
- Ask the group admin for the invitation password
175
- </small>
179
+ <small className="text-muted">Ask the group admin for the invitation password</small>
176
180
  </div>
177
181
  </div>
178
182
 
@@ -215,13 +219,13 @@ export const JoinGroup = () => {
215
219
  <div className="d-flex justify-content-between align-items-center">
216
220
  <div>
217
221
  <div className="d-flex align-items-center mb-1">
218
- <i className={`${listener.group.iconClassName || "bi-people-fill"} me-2`} />
222
+ <i
223
+ className={`${listener.group.iconClassName || "bi-people-fill"} me-2`}
224
+ />
219
225
  <strong>{listener.group.name}</strong>
220
226
  </div>
221
227
  {listener.group.description && (
222
- <p className="text-muted mb-1 small">
223
- {listener.group.description}
224
- </p>
228
+ <p className="text-muted mb-1 small">{listener.group.description}</p>
225
229
  )}
226
230
  <small className="text-muted">
227
231
  <i className="bi-person me-1" />
@@ -269,9 +273,7 @@ export const JoinGroup = () => {
269
273
  <span className="visually-hidden">Joining...</span>
270
274
  </div>
271
275
  <p className="text-muted">Waiting for approval...</p>
272
- <small className="text-muted">
273
- The group admin needs to approve your request
274
- </small>
276
+ <small className="text-muted">The group admin needs to approve your request</small>
275
277
  </div>
276
278
  )}
277
279
  </>
@@ -286,7 +288,7 @@ registerInternalPeersUI({
286
288
  component: JoinGroup,
287
289
  routes: [
288
290
  {
289
- isMatch: (props, context) => context.path === "join-group",
291
+ isMatch: (_props, context) => context.path === "join-group",
290
292
  uiCategory: "screen",
291
293
  priority: 2,
292
294
  },
@@ -1,11 +1,13 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import { emit } from '@peers-app/peers-sdk';
1
+ import { emit } from "@peers-app/peers-sdk";
2
+ import type React from "react";
3
+ import { useCallback, useEffect, useRef, useState } from "react";
4
+ import { getNetworkViewerApi } from "./network-viewer-ipc";
3
5
 
4
6
  export interface IDiagnosticCheck {
5
7
  id: string;
6
8
  label: string;
7
9
  layer: string;
8
- status: 'pass' | 'fail' | 'warn' | 'skip' | 'running';
10
+ status: "pass" | "fail" | "warn" | "skip" | "running";
9
11
  detail: string;
10
12
  suggestion?: string;
11
13
  }
@@ -14,32 +16,36 @@ interface Props {
14
16
  onBack: () => void;
15
17
  }
16
18
 
17
- const STATUS_ICON: Record<IDiagnosticCheck['status'], React.ReactNode> = {
19
+ const STATUS_ICON: Record<IDiagnosticCheck["status"], React.ReactNode> = {
18
20
  pass: <i className="bi bi-check-circle-fill text-success" />,
19
21
  fail: <i className="bi bi-x-circle-fill text-danger" />,
20
22
  warn: <i className="bi bi-exclamation-triangle-fill text-warning" />,
21
23
  skip: <i className="bi bi-dash-circle text-muted" />,
22
24
  running: (
23
- <span className="spinner-border spinner-border-sm text-primary" role="status" aria-hidden="true" />
25
+ <span
26
+ className="spinner-border spinner-border-sm text-primary"
27
+ role="status"
28
+ aria-hidden="true"
29
+ />
24
30
  ),
25
31
  };
26
32
 
27
- const STATUS_BADGE_CLASS: Record<IDiagnosticCheck['status'], string> = {
28
- pass: 'bg-success',
29
- fail: 'bg-danger',
30
- warn: 'bg-warning text-dark',
31
- skip: 'bg-secondary',
32
- running: 'bg-primary',
33
+ const STATUS_BADGE_CLASS: Record<IDiagnosticCheck["status"], string> = {
34
+ pass: "bg-success",
35
+ fail: "bg-danger",
36
+ warn: "bg-warning text-dark",
37
+ skip: "bg-secondary",
38
+ running: "bg-primary",
33
39
  };
34
40
 
35
41
  const LAYER_ORDER = [
36
- 'Local System',
37
- 'Cloud Relay',
38
- 'Local Network',
39
- 'Protocol Support',
40
- 'WebRTC / TURN',
41
- 'Peer State',
42
- 'Active Connections',
42
+ "Local System",
43
+ "Cloud Relay",
44
+ "Local Network",
45
+ "Protocol Support",
46
+ "WebRTC / TURN",
47
+ "Peer State",
48
+ "Active Connections",
43
49
  ];
44
50
 
45
51
  function groupByLayer(checks: IDiagnosticCheck[]): Record<string, IDiagnosticCheck[]> {
@@ -51,17 +57,22 @@ function groupByLayer(checks: IDiagnosticCheck[]): Record<string, IDiagnosticChe
51
57
  return groups;
52
58
  }
53
59
 
54
- function getSummary(checks: IDiagnosticCheck[]): { issues: number; warnings: number; passes: number; skips: number } {
60
+ function getSummary(checks: IDiagnosticCheck[]): {
61
+ issues: number;
62
+ warnings: number;
63
+ passes: number;
64
+ skips: number;
65
+ } {
55
66
  return {
56
- issues: checks.filter(c => c.status === 'fail').length,
57
- warnings: checks.filter(c => c.status === 'warn').length,
58
- passes: checks.filter(c => c.status === 'pass').length,
59
- skips: checks.filter(c => c.status === 'skip').length,
67
+ issues: checks.filter((c) => c.status === "fail").length,
68
+ warnings: checks.filter((c) => c.status === "warn").length,
69
+ passes: checks.filter((c) => c.status === "pass").length,
70
+ skips: checks.filter((c) => c.status === "skip").length,
60
71
  };
61
72
  }
62
73
 
63
74
  function formatReportForAI(checks: IDiagnosticCheck[]): string {
64
- const lines: string[] = ['Connection Troubleshooter Report', '================================'];
75
+ const lines: string[] = ["Connection Troubleshooter Report", "================================"];
65
76
  const groups = groupByLayer(checks);
66
77
 
67
78
  for (const layer of LAYER_ORDER) {
@@ -80,7 +91,7 @@ function formatReportForAI(checks: IDiagnosticCheck[]): string {
80
91
  const { issues, warnings, skips } = getSummary(checks);
81
92
  lines.push(`\nSummary: ${issues} issue(s), ${warnings} warning(s), ${skips} skipped.`);
82
93
 
83
- return lines.join('\n');
94
+ return lines.join("\n");
84
95
  }
85
96
 
86
97
  export function ConnectionTroubleshooter({ onBack }: Props) {
@@ -90,21 +101,24 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
90
101
  const [expanded, setExpanded] = useState<Set<string>>(new Set());
91
102
  const hasRun = useRef(false);
92
103
 
93
- const runDiagnostics = async () => {
104
+ const runDiagnostics = useCallback(async () => {
94
105
  setRunning(true);
95
106
  setDone(false);
96
107
  setChecks([]);
97
108
  setExpanded(new Set());
98
109
 
99
- const api = (window as any).electronAPI?.networkViewer;
110
+ const api = getNetworkViewerApi();
100
111
  if (!api) {
101
- setChecks([{
102
- id: 'no-api',
103
- label: 'Electron API unavailable',
104
- layer: 'Local System',
105
- status: 'fail',
106
- detail: 'The Electron network API is not available. This tool only works in the desktop app.',
107
- }]);
112
+ setChecks([
113
+ {
114
+ id: "no-api",
115
+ label: "Electron API unavailable",
116
+ layer: "Local System",
117
+ status: "fail",
118
+ detail:
119
+ "The Electron network API is not available. This tool only works in the desktop app.",
120
+ },
121
+ ]);
108
122
  setRunning(false);
109
123
  setDone(true);
110
124
  return;
@@ -113,51 +127,52 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
113
127
  try {
114
128
  // Stream results by running all checks on the backend and updating as they come in.
115
129
  // Show a placeholder "running" row immediately while the full batch executes.
116
- const placeholders: IDiagnosticCheck[] = LAYER_ORDER.map(layer => ({
130
+ const placeholders: IDiagnosticCheck[] = LAYER_ORDER.map((layer) => ({
117
131
  id: `placeholder-${layer}`,
118
132
  label: `Checking ${layer}…`,
119
133
  layer,
120
- status: 'running',
121
- detail: '',
134
+ status: "running",
135
+ detail: "",
122
136
  }));
123
137
  setChecks(placeholders);
124
138
 
125
- const results: IDiagnosticCheck[] = await api.runDiagnostics();
139
+ const results = (await api.runDiagnostics()) as IDiagnosticCheck[];
126
140
  setChecks(results);
127
141
 
128
142
  // Auto-expand all failed/warned checks so they're visible immediately
129
143
  const toExpand = new Set<string>();
130
144
  for (const r of results) {
131
- if ((r.status === 'fail' || r.status === 'warn') && r.suggestion) {
145
+ if ((r.status === "fail" || r.status === "warn") && r.suggestion) {
132
146
  toExpand.add(r.id);
133
147
  }
134
148
  }
135
149
  setExpanded(toExpand);
136
- } catch (err: any) {
137
- setChecks([{
138
- id: 'run-error',
139
- label: 'Diagnostics failed to run',
140
- layer: 'Local System',
141
- status: 'fail',
142
- detail: `Error: ${err?.message || 'Unknown error'}`,
143
- suggestion: 'Restart the application and try again.',
144
- }]);
150
+ } catch (err: unknown) {
151
+ setChecks([
152
+ {
153
+ id: "run-error",
154
+ label: "Diagnostics failed to run",
155
+ layer: "Local System",
156
+ status: "fail",
157
+ detail: `Error: ${err instanceof Error ? err.message : "Unknown error"}`,
158
+ suggestion: "Restart the application and try again.",
159
+ },
160
+ ]);
145
161
  } finally {
146
162
  setRunning(false);
147
163
  setDone(true);
148
164
  }
149
- };
165
+ }, []);
150
166
 
151
167
  useEffect(() => {
152
168
  if (!hasRun.current) {
153
169
  hasRun.current = true;
154
- runDiagnostics();
170
+ void runDiagnostics();
155
171
  }
156
- // eslint-disable-next-line react-hooks/exhaustive-deps
157
- }, []);
172
+ }, [runDiagnostics]);
158
173
 
159
174
  const toggleExpand = (id: string) => {
160
- setExpanded(prev => {
175
+ setExpanded((prev) => {
161
176
  const next = new Set(prev);
162
177
  if (next.has(id)) next.delete(id);
163
178
  else next.add(id);
@@ -166,32 +181,37 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
166
181
  };
167
182
 
168
183
  const handleAskAssistant = () => {
169
- const report = formatReportForAI(checks.filter(c => c.status !== 'running'));
184
+ const report = formatReportForAI(checks.filter((c) => c.status !== "running"));
170
185
  const message = `I ran the Peers connection troubleshooter and got the following results. Please help me understand what's wrong and how to fix it:\n\n${report}`;
171
- emit({ name: 'chat:openWithMessage', data: { message } }).catch(() => {
186
+ emit({ name: "chat:openWithMessage", data: { message } }).catch(() => {
172
187
  // Fallback: copy to clipboard
173
- navigator.clipboard.writeText(message).then(() => {
174
- alert('Diagnostic report copied to clipboard. Paste it into the AI assistant chat.');
175
- }).catch(() => {
176
- alert('Could not open AI assistant. Please open the chat manually and paste the diagnostic report.');
177
- });
188
+ navigator.clipboard
189
+ .writeText(message)
190
+ .then(() => {
191
+ alert("Diagnostic report copied to clipboard. Paste it into the AI assistant chat.");
192
+ })
193
+ .catch(() => {
194
+ alert(
195
+ "Could not open AI assistant. Please open the chat manually and paste the diagnostic report.",
196
+ );
197
+ });
178
198
  });
179
199
  };
180
200
 
181
- const groups = groupByLayer(checks.filter(c => !c.id.startsWith('placeholder-')));
182
- const placeholders = checks.filter(c => c.id.startsWith('placeholder-'));
201
+ const groups = groupByLayer(checks.filter((c) => !c.id.startsWith("placeholder-")));
202
+ const placeholders = checks.filter((c) => c.id.startsWith("placeholder-"));
183
203
  const summary = getSummary(checks);
184
- const completedCount = checks.filter(c => c.status !== 'running').length;
204
+ const completedCount = checks.filter((c) => c.status !== "running").length;
185
205
  const totalCount = checks.length;
186
206
  const progressPct = totalCount > 0 ? Math.round((completedCount / totalCount) * 100) : 0;
187
207
 
188
- const overallStatus: IDiagnosticCheck['status'] = !done
189
- ? 'running'
208
+ const overallStatus: IDiagnosticCheck["status"] = !done
209
+ ? "running"
190
210
  : summary.issues > 0
191
- ? 'fail'
192
- : summary.warnings > 0
193
- ? 'warn'
194
- : 'pass';
211
+ ? "fail"
212
+ : summary.warnings > 0
213
+ ? "warn"
214
+ : "pass";
195
215
 
196
216
  return (
197
217
  <div className="container-fluid p-4">
@@ -207,14 +227,14 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
207
227
  Connection Troubleshooter
208
228
  </h4>
209
229
  </div>
210
- <button
211
- className="btn btn-sm btn-primary"
212
- onClick={runDiagnostics}
213
- disabled={running}
214
- >
230
+ <button className="btn btn-sm btn-primary" onClick={runDiagnostics} disabled={running}>
215
231
  {running ? (
216
232
  <>
217
- <span className="spinner-border spinner-border-sm me-1" role="status" aria-hidden="true" />
233
+ <span
234
+ className="spinner-border spinner-border-sm me-1"
235
+ role="status"
236
+ aria-hidden="true"
237
+ />
218
238
  Running…
219
239
  </>
220
240
  ) : (
@@ -231,9 +251,11 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
231
251
  <div className="mb-4">
232
252
  <div className="d-flex justify-content-between mb-1">
233
253
  <small className="text-muted">Running diagnostics…</small>
234
- <small className="text-muted">{completedCount} / {totalCount}</small>
254
+ <small className="text-muted">
255
+ {completedCount} / {totalCount}
256
+ </small>
235
257
  </div>
236
- <div className="progress" style={{ height: '6px' }}>
258
+ <div className="progress" style={{ height: "6px" }}>
237
259
  <div
238
260
  className="progress-bar progress-bar-striped progress-bar-animated"
239
261
  style={{ width: `${progressPct}%` }}
@@ -244,22 +266,39 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
244
266
 
245
267
  {/* Summary card — shown when done */}
246
268
  {done && checks.length > 0 && (
247
- <div className={`alert ${overallStatus === 'pass' ? 'alert-success' : overallStatus === 'warn' ? 'alert-warning' : 'alert-danger'} d-flex justify-content-between align-items-center mb-4`}>
269
+ <div
270
+ className={`alert ${overallStatus === "pass" ? "alert-success" : overallStatus === "warn" ? "alert-warning" : "alert-danger"} d-flex justify-content-between align-items-center mb-4`}
271
+ >
248
272
  <div className="d-flex align-items-center gap-2">
249
- {overallStatus === 'pass' && <i className="bi bi-check-circle-fill fs-5" />}
250
- {overallStatus === 'warn' && <i className="bi bi-exclamation-triangle-fill fs-5" />}
251
- {overallStatus === 'fail' && <i className="bi bi-x-circle-fill fs-5" />}
273
+ {overallStatus === "pass" && <i className="bi bi-check-circle-fill fs-5" />}
274
+ {overallStatus === "warn" && <i className="bi bi-exclamation-triangle-fill fs-5" />}
275
+ {overallStatus === "fail" && <i className="bi bi-x-circle-fill fs-5" />}
252
276
  <div>
253
- {overallStatus === 'pass' && <strong>All checks passed.</strong>}
254
- {overallStatus === 'warn' && <strong>{summary.warnings} warning{summary.warnings > 1 ? 's' : ''} found.</strong>}
255
- {overallStatus === 'fail' && <strong>{summary.issues} issue{summary.issues > 1 ? 's' : ''} found{summary.warnings > 0 ? `, ${summary.warnings} warning${summary.warnings > 1 ? 's' : ''}` : ''}.</strong>}
256
- {' '}
277
+ {overallStatus === "pass" && <strong>All checks passed.</strong>}
278
+ {overallStatus === "warn" && (
279
+ <strong>
280
+ {summary.warnings} warning{summary.warnings > 1 ? "s" : ""} found.
281
+ </strong>
282
+ )}
283
+ {overallStatus === "fail" && (
284
+ <strong>
285
+ {summary.issues} issue{summary.issues > 1 ? "s" : ""} found
286
+ {summary.warnings > 0
287
+ ? `, ${summary.warnings} warning${summary.warnings > 1 ? "s" : ""}`
288
+ : ""}
289
+ .
290
+ </strong>
291
+ )}{" "}
257
292
  <span className="opacity-75">
258
- {summary.passes} passed · {summary.issues} failed · {summary.warnings} warnings · {summary.skips} skipped
293
+ {summary.passes} passed · {summary.issues} failed · {summary.warnings} warnings ·{" "}
294
+ {summary.skips} skipped
259
295
  </span>
260
296
  </div>
261
297
  </div>
262
- <button className="btn btn-sm btn-dark d-flex align-items-center gap-1" onClick={handleAskAssistant}>
298
+ <button
299
+ className="btn btn-sm btn-dark d-flex align-items-center gap-1"
300
+ onClick={handleAskAssistant}
301
+ >
263
302
  <i className="bi bi-chat-dots-fill" />
264
303
  Ask AI Assistant
265
304
  </button>
@@ -270,7 +309,7 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
270
309
  {running && placeholders.length > 0 && (
271
310
  <div className="card mb-3">
272
311
  <div className="card-body p-2">
273
- {placeholders.map(p => (
312
+ {placeholders.map((p) => (
274
313
  <div key={p.id} className="d-flex align-items-center gap-2 p-2 border-bottom">
275
314
  {STATUS_ICON[p.status]}
276
315
  <span className="text-muted small">{p.label}</span>
@@ -281,19 +320,19 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
281
320
  )}
282
321
 
283
322
  {/* Results grouped by layer */}
284
- {LAYER_ORDER.map(layer => {
323
+ {LAYER_ORDER.map((layer) => {
285
324
  const layerChecks = groups[layer];
286
325
  if (!layerChecks || layerChecks.length === 0) return null;
287
326
 
288
- const layerStatus: IDiagnosticCheck['status'] = layerChecks.some(c => c.status === 'fail')
289
- ? 'fail'
290
- : layerChecks.some(c => c.status === 'warn')
291
- ? 'warn'
292
- : layerChecks.some(c => c.status === 'running')
293
- ? 'running'
294
- : layerChecks.every(c => c.status === 'skip')
295
- ? 'skip'
296
- : 'pass';
327
+ const layerStatus: IDiagnosticCheck["status"] = layerChecks.some((c) => c.status === "fail")
328
+ ? "fail"
329
+ : layerChecks.some((c) => c.status === "warn")
330
+ ? "warn"
331
+ : layerChecks.some((c) => c.status === "running")
332
+ ? "running"
333
+ : layerChecks.every((c) => c.status === "skip")
334
+ ? "skip"
335
+ : "pass";
297
336
 
298
337
  return (
299
338
  <div className="card mb-3" key={layer}>
@@ -303,24 +342,26 @@ export function ConnectionTroubleshooter({ onBack }: Props) {
303
342
  <strong className="small">{layer}</strong>
304
343
  </div>
305
344
  <span className={`badge ${STATUS_BADGE_CLASS[layerStatus]}`}>
306
- {layerStatus === 'running' ? 'running' : layerStatus}
345
+ {layerStatus === "running" ? "running" : layerStatus}
307
346
  </span>
308
347
  </div>
309
348
  <div className="list-group list-group-flush">
310
- {layerChecks.map(check => (
349
+ {layerChecks.map((check) => (
311
350
  <div key={check.id} className="list-group-item p-0">
312
351
  <div
313
- className={`d-flex align-items-start gap-2 px-3 py-2 ${check.suggestion ? 'cursor-pointer' : ''}`}
314
- style={{ cursor: check.suggestion ? 'pointer' : 'default' }}
352
+ className={`d-flex align-items-start gap-2 px-3 py-2 ${check.suggestion ? "cursor-pointer" : ""}`}
353
+ style={{ cursor: check.suggestion ? "pointer" : "default" }}
315
354
  onClick={() => check.suggestion && toggleExpand(check.id)}
316
- role={check.suggestion ? 'button' : undefined}
355
+ role={check.suggestion ? "button" : undefined}
317
356
  >
318
357
  <div className="pt-1 flex-shrink-0">{STATUS_ICON[check.status]}</div>
319
358
  <div className="flex-grow-1 min-width-0">
320
359
  <div className="d-flex justify-content-between align-items-start">
321
360
  <span className="small fw-medium">{check.label}</span>
322
361
  {check.suggestion && (
323
- <i className={`bi bi-chevron-${expanded.has(check.id) ? 'up' : 'down'} text-muted ms-2 flex-shrink-0 small`} />
362
+ <i
363
+ className={`bi bi-chevron-${expanded.has(check.id) ? "up" : "down"} text-muted ms-2 flex-shrink-0 small`}
364
+ />
324
365
  )}
325
366
  </div>
326
367
  <div className="small text-muted mt-1">{check.detail}</div>