@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,19 +1,20 @@
1
- import React, { useEffect, useRef, useState } from 'react';
2
- import { useObservable } from '../hooks';
3
- import { colorMode } from '../screens/settings/color-mode-dropdown';
1
+ import { getMe, type IAppNav, Messages, newid } from "@peers-app/peers-sdk";
2
+ // biome-ignore lint/correctness/noUnusedImports: classic JSX (`jsx: react`) needs React in scope for emit
3
+ import React, { useCallback, useEffect, useRef, useState } from "react";
4
+ import { openThreadInTab } from "../globals";
5
+ import { useObservable } from "../hooks";
6
+ import { colorMode } from "../screens/settings/color-mode-dropdown";
7
+ import { systemPackage } from "../system-apps";
8
+ import { goToTabPath } from "../tabs-layout/tabs-state";
9
+ import { allPackages } from "../ui-router/routes-loader";
4
10
  import {
11
+ type Command,
5
12
  closeCommandPalette,
6
13
  commandSearchQuery,
7
- Command,
8
14
  executeCommand,
9
15
  isCommandPaletteOpen,
10
- searchCommands
11
- } from './command-palette';
12
- import { allPackages } from '../ui-router/routes-loader';
13
- import { systemPackage } from '../system-apps';
14
- import { goToTabPath } from '../tabs-layout/tabs-state';
15
- import { IAppNav, Messages, newid, getMe } from "@peers-app/peers-sdk";
16
- import { openThreadInTab } from '../globals';
16
+ searchCommands,
17
+ } from "./command-palette";
17
18
 
18
19
  interface AppSearchItem {
19
20
  packageId: string;
@@ -32,31 +33,31 @@ export function CommandPaletteOverlay() {
32
33
  const [packages] = useObservable(allPackages);
33
34
  const [selectedIndex, setSelectedIndex] = useState(0);
34
35
  const inputRef = useRef<HTMLInputElement>(null);
35
-
36
+
36
37
  // Local state for query input to avoid locking up on fast typing
37
- const [localQuery, setLocalQuery] = useState<string>('');
38
+ const [localQuery, setLocalQuery] = useState<string>("");
38
39
  const debounceTimeoutRef = useRef<NodeJS.Timeout>();
39
-
40
+
40
41
  // Sync local query with persisted query when palette opens
41
42
  useEffect(() => {
42
43
  if (isOpen) {
43
- setLocalQuery(_persistedQuery || '');
44
+ setLocalQuery(_persistedQuery || "");
44
45
  } else {
45
- setLocalQuery('');
46
+ setLocalQuery("");
46
47
  }
47
48
  }, [isOpen, _persistedQuery]);
48
-
49
+
49
50
  // Debounced function to update the persisted query
50
51
  const updatePersistedQuery = (newQuery: string) => {
51
52
  if (debounceTimeoutRef.current) {
52
53
  clearTimeout(debounceTimeoutRef.current);
53
54
  }
54
-
55
+
55
56
  debounceTimeoutRef.current = setTimeout(() => {
56
57
  commandSearchQuery(newQuery);
57
58
  }, 150); // Shorter debounce for command palette (150ms vs 300ms)
58
59
  };
59
-
60
+
60
61
  // Cleanup debounce timeout on unmount
61
62
  useEffect(() => {
62
63
  return () => {
@@ -65,25 +66,27 @@ export function CommandPaletteOverlay() {
65
66
  }
66
67
  };
67
68
  }, []);
68
-
69
+
69
70
  const searchQuery = localQuery;
70
71
  const filteredCommands = searchCommands(searchQuery);
71
-
72
+
72
73
  // Get all apps (system and user)
73
74
  const getAllApps = (): AppSearchItem[] => {
74
75
  const allPackages_ = [...packages, systemPackage];
75
76
  return allPackages_
76
- .filter(p => !p.disabled && p.appNavs && p.appNavs.length > 0)
77
- .flatMap(pkg =>
78
- pkg.appNavs!.map(navItem => {
77
+ .filter((p) => !p.disabled && p.appNavs && p.appNavs.length > 0)
78
+ .flatMap((pkg) => {
79
+ const navs = pkg.appNavs;
80
+ if (!navs) return [];
81
+ return navs.map((navItem) => {
79
82
  // Construct path - use direct path for system apps, package-nav for others
80
83
  let path: string;
81
- if (pkg.packageId === 'system-apps') {
82
- path = navItem.navigationPath ?? navItem.name.replace(/\s/g, '-').toLowerCase();
84
+ if (pkg.packageId === "system-apps") {
85
+ path = navItem.navigationPath ?? navItem.name.replace(/\s/g, "-").toLowerCase();
83
86
  } else {
84
- path = `package-nav/${pkg.packageId}/${(navItem.navigationPath ?? navItem.name).replace(/[^a-zA-Z0-9]/g, '-').toLowerCase()}`;
85
- while (path.includes('//')) {
86
- path = path.replace('//', '/');
87
+ path = `package-nav/${pkg.packageId}/${(navItem.navigationPath ?? navItem.name).replace(/[^a-zA-Z0-9]/g, "-").toLowerCase()}`;
88
+ while (path.includes("//")) {
89
+ path = path.replace("//", "/");
87
90
  }
88
91
  }
89
92
 
@@ -94,10 +97,10 @@ export function CommandPaletteOverlay() {
94
97
  path,
95
98
  name: navItem.name,
96
99
  displayName: navItem.displayName || navItem.name,
97
- iconClassName: navItem.iconClassName || 'bi-box-seam'
100
+ iconClassName: navItem.iconClassName || "bi-box-seam",
98
101
  };
99
- })
100
- );
102
+ });
103
+ });
101
104
  };
102
105
 
103
106
  // Search apps
@@ -105,17 +108,18 @@ export function CommandPaletteOverlay() {
105
108
  if (!query.trim()) return [];
106
109
  const allApps = getAllApps();
107
110
  const lowerQuery = query.toLowerCase();
108
- return allApps.filter(app =>
109
- app.name.toLowerCase().includes(lowerQuery) ||
110
- app.displayName.toLowerCase().includes(lowerQuery) ||
111
- app.packageName.toLowerCase().includes(lowerQuery)
111
+ return allApps.filter(
112
+ (app) =>
113
+ app.name.toLowerCase().includes(lowerQuery) ||
114
+ app.displayName.toLowerCase().includes(lowerQuery) ||
115
+ app.packageName.toLowerCase().includes(lowerQuery),
112
116
  );
113
117
  };
114
118
 
115
119
  const filteredApps = searchApps(searchQuery);
116
-
120
+
117
121
  // Function to create a new thread from search query
118
- const createNewThreadFromQuery = async (query: string) => {
122
+ const createNewThreadFromQuery = useCallback(async (query: string) => {
119
123
  try {
120
124
  const currentUser = await getMe();
121
125
  const threadMessage = await Messages().insert({
@@ -127,59 +131,67 @@ export function CommandPaletteOverlay() {
127
131
  });
128
132
  await openThreadInTab(threadMessage);
129
133
  } catch (error) {
130
- console.error('Failed to create new thread:', error);
134
+ console.error("Failed to create new thread:", error);
131
135
  }
132
- };
133
-
136
+ }, []);
137
+
134
138
  // Create a flattened list that matches the visual rendering order
135
139
  // Apps first, then commands
136
- const allItems: Array<{ type: 'app' | 'command'; app?: AppSearchItem; command?: Command; id: string }> = [];
137
-
140
+ const allItems: Array<{
141
+ type: "app" | "command";
142
+ app?: AppSearchItem;
143
+ command?: Command;
144
+ id: string;
145
+ }> = [];
146
+
138
147
  // Add apps first
139
148
  filteredApps.forEach((app) => {
140
- allItems.push({ type: 'app', app, id: `app-${app.packageId}-${app.path}` });
149
+ allItems.push({ type: "app", app, id: `app-${app.packageId}-${app.path}` });
141
150
  });
142
-
151
+
143
152
  // Then add commands
144
153
  const visualOrderCommands = Object.entries(
145
- filteredCommands.reduce((acc, cmd) => {
146
- const category = cmd.category || 'Other';
147
- if (!acc[category]) acc[category] = [];
148
- acc[category].push(cmd);
149
- return acc;
150
- }, {} as Record<string, Command[]>)
154
+ filteredCommands.reduce(
155
+ (acc, cmd) => {
156
+ const category = cmd.category || "Other";
157
+ if (!acc[category]) acc[category] = [];
158
+ acc[category].push(cmd);
159
+ return acc;
160
+ },
161
+ {} as Record<string, Command[]>,
162
+ ),
151
163
  ).flatMap(([, commands]) => commands);
152
-
164
+
153
165
  visualOrderCommands.forEach((cmd) => {
154
- allItems.push({ type: 'command', command: cmd, id: `command-${cmd.id}` });
166
+ allItems.push({ type: "command", command: cmd, id: `command-${cmd.id}` });
155
167
  });
156
-
168
+
157
169
  // Focus input when opened
158
170
  useEffect(() => {
159
171
  if (isOpen && inputRef.current) {
160
172
  inputRef.current.focus();
161
173
  }
162
174
  }, [isOpen]);
163
-
175
+
164
176
  // Reset selected index when search changes
165
177
  useEffect(() => {
166
178
  setSelectedIndex(0);
167
- }, [searchQuery]);
168
-
179
+ }, []);
180
+
169
181
  // Keyboard navigation
170
182
  useEffect(() => {
171
183
  if (!isOpen) return;
172
-
184
+
173
185
  const handleKeyDown = (e: KeyboardEvent) => {
174
- if (e.key === 'ArrowDown') {
186
+ if (e.key === "ArrowDown") {
175
187
  e.preventDefault();
176
188
  // Allow selection to go one past the end if there's a search query (for new thread option)
177
189
  const maxIndex = searchQuery.trim() ? allItems.length : allItems.length - 1;
178
- setSelectedIndex(prev => Math.min(prev + 1, maxIndex));
179
- } else if (e.key === 'ArrowUp') {
190
+ setSelectedIndex((prev) => Math.min(prev + 1, maxIndex));
191
+ } else if (e.key === "ArrowUp") {
180
192
  e.preventDefault();
181
- setSelectedIndex(prev => Math.max(prev - 1, 0));
182
- } else if (e.key === 'Enter') {
193
+ setSelectedIndex((prev) => Math.max(prev - 1, 0));
194
+ } else if (e.key === "Enter") {
183
195
  e.preventDefault();
184
196
  // Check if the new thread option is selected (selectedIndex >= allItems.length)
185
197
  if (selectedIndex >= allItems.length && searchQuery.trim()) {
@@ -188,10 +200,10 @@ export function CommandPaletteOverlay() {
188
200
  } else {
189
201
  const selectedItem = allItems[selectedIndex];
190
202
  if (selectedItem) {
191
- if (selectedItem.type === 'app' && selectedItem.app) {
203
+ if (selectedItem.type === "app" && selectedItem.app) {
192
204
  closeCommandPalette();
193
205
  goToTabPath(selectedItem.app.path);
194
- } else if (selectedItem.type === 'command' && selectedItem.command) {
206
+ } else if (selectedItem.type === "command" && selectedItem.command) {
195
207
  executeCommand(selectedItem.command.id);
196
208
  }
197
209
  } else if (searchQuery.trim()) {
@@ -203,15 +215,15 @@ export function CommandPaletteOverlay() {
203
215
  }
204
216
  }
205
217
  };
206
-
207
- document.addEventListener('keydown', handleKeyDown);
208
- return () => document.removeEventListener('keydown', handleKeyDown);
209
- }, [isOpen, allItems, selectedIndex]);
210
-
218
+
219
+ document.addEventListener("keydown", handleKeyDown);
220
+ return () => document.removeEventListener("keydown", handleKeyDown);
221
+ }, [isOpen, selectedIndex, createNewThreadFromQuery, searchQuery]);
222
+
211
223
  if (!isOpen) return null;
212
-
213
- const isDark = _colorMode === 'dark';
214
-
224
+
225
+ const isDark = _colorMode === "dark";
226
+
215
227
  return (
216
228
  <div
217
229
  className="position-fixed w-100 h-100 d-flex align-items-start justify-content-center"
@@ -219,9 +231,9 @@ export function CommandPaletteOverlay() {
219
231
  top: 0,
220
232
  left: 0,
221
233
  zIndex: 1050,
222
- backgroundColor: 'rgba(0, 0, 0, 0.5)',
223
- backdropFilter: 'blur(4px)',
224
- paddingTop: '10vh'
234
+ backgroundColor: "rgba(0, 0, 0, 0.5)",
235
+ backdropFilter: "blur(4px)",
236
+ paddingTop: "10vh",
225
237
  }}
226
238
  onClick={(e) => {
227
239
  if (e.target === e.currentTarget) {
@@ -230,37 +242,38 @@ export function CommandPaletteOverlay() {
230
242
  }}
231
243
  >
232
244
  <div
233
- className={`${isDark ? 'bg-dark text-light' : 'bg-white text-dark'}`}
245
+ className={`${isDark ? "bg-dark text-light" : "bg-white text-dark"}`}
234
246
  style={{
235
- width: '90%',
236
- maxWidth: '600px',
237
- borderRadius: '12px',
238
- boxShadow: isDark
239
- ? '0 20px 40px rgba(0, 0, 0, 0.5)'
240
- : '0 20px 40px rgba(0, 0, 0, 0.1)',
241
- border: isDark ? '1px solid #495057' : '1px solid #dee2e6',
242
- overflow: 'hidden'
247
+ width: "90%",
248
+ maxWidth: "600px",
249
+ borderRadius: "12px",
250
+ boxShadow: isDark ? "0 20px 40px rgba(0, 0, 0, 0.5)" : "0 20px 40px rgba(0, 0, 0, 0.1)",
251
+ border: isDark ? "1px solid #495057" : "1px solid #dee2e6",
252
+ overflow: "hidden",
243
253
  }}
244
254
  >
245
255
  {/* Search Input */}
246
- <div className="p-3 border-bottom" style={{
247
- borderBottomColor: isDark ? '#495057' : '#dee2e6'
248
- }}>
256
+ <div
257
+ className="p-3 border-bottom"
258
+ style={{
259
+ borderBottomColor: isDark ? "#495057" : "#dee2e6",
260
+ }}
261
+ >
249
262
  <div className="position-relative">
250
- <i
251
- className="bi-search position-absolute"
263
+ <i
264
+ className="bi-search position-absolute"
252
265
  style={{
253
- left: '12px',
254
- top: '50%',
255
- transform: 'translateY(-50%)',
256
- color: '#6c757d',
257
- zIndex: 1
258
- }}
266
+ left: "12px",
267
+ top: "50%",
268
+ transform: "translateY(-50%)",
269
+ color: "#6c757d",
270
+ zIndex: 1,
271
+ }}
259
272
  />
260
273
  <input
261
274
  ref={inputRef}
262
275
  type="text"
263
- className={`form-control ${isDark ? 'bg-dark text-light border-secondary' : ''}`}
276
+ className={`form-control ${isDark ? "bg-dark text-light border-secondary" : ""}`}
264
277
  placeholder="Search apps, commands, or navigate..."
265
278
  value={searchQuery}
266
279
  onChange={(e) => {
@@ -277,62 +290,62 @@ export function CommandPaletteOverlay() {
277
290
  commandSearchQuery(localQuery);
278
291
  }}
279
292
  style={{
280
- paddingLeft: '40px',
281
- fontSize: '16px',
282
- border: 'none',
283
- outline: 'none',
284
- boxShadow: 'none',
285
- backgroundColor: isDark ? '#343a40' : '#f8f9fa'
293
+ paddingLeft: "40px",
294
+ fontSize: "16px",
295
+ border: "none",
296
+ outline: "none",
297
+ boxShadow: "none",
298
+ backgroundColor: isDark ? "#343a40" : "#f8f9fa",
286
299
  }}
287
300
  />
288
301
  </div>
289
302
  </div>
290
-
303
+
291
304
  {/* Commands and Apps List */}
292
305
  <div
293
306
  style={{
294
- maxHeight: '400px',
295
- overflowY: 'auto'
307
+ maxHeight: "400px",
308
+ overflowY: "auto",
296
309
  }}
297
310
  >
298
311
  {allItems.length === 0 && !searchQuery.trim() ? (
299
312
  <div className="p-4 text-center text-muted">
300
- <i className="bi-search mb-2 d-block" style={{ fontSize: '24px' }} />
313
+ <i className="bi-search mb-2 d-block" style={{ fontSize: "24px" }} />
301
314
  No results found
302
315
  </div>
303
316
  ) : (
304
317
  <div className="py-2">
305
318
  {/* Show "No results" message if there's a query but no results yet */}
306
319
  {allItems.length === 0 && searchQuery.trim() && (
307
- <div className="px-3 py-2 text-muted small text-center">
308
- No matching results
309
- </div>
320
+ <div className="px-3 py-2 text-muted small text-center">No matching results</div>
310
321
  )}
311
322
  {/* Apps Section */}
312
323
  {filteredApps.length > 0 && (
313
324
  <div>
314
- <div
325
+ <div
315
326
  className="px-3 py-1 small text-muted fw-bold text-uppercase"
316
- style={{ fontSize: '11px', letterSpacing: '0.5px' }}
327
+ style={{ fontSize: "11px", letterSpacing: "0.5px" }}
317
328
  >
318
329
  Apps
319
330
  </div>
320
331
  {filteredApps.map((app) => {
321
332
  const appId = `app-${app.packageId}-${app.path}`;
322
- const globalIndex = allItems.findIndex(item => item.id === appId);
333
+ const globalIndex = allItems.findIndex((item) => item.id === appId);
323
334
  const isSelected = globalIndex === selectedIndex;
324
-
335
+
325
336
  return (
326
337
  <div
327
338
  key={`${app.packageId}-${app.path}`}
328
339
  className={`px-3 py-2 d-flex align-items-center justify-content-between ${
329
- isSelected
330
- ? (isDark ? 'bg-primary bg-opacity-25' : 'bg-primary bg-opacity-10')
331
- : ''
340
+ isSelected
341
+ ? isDark
342
+ ? "bg-primary bg-opacity-25"
343
+ : "bg-primary bg-opacity-10"
344
+ : ""
332
345
  }`}
333
346
  style={{
334
- cursor: 'pointer',
335
- transition: 'background-color 0.1s ease'
347
+ cursor: "pointer",
348
+ transition: "background-color 0.1s ease",
336
349
  }}
337
350
  onClick={() => {
338
351
  closeCommandPalette();
@@ -341,21 +354,18 @@ export function CommandPaletteOverlay() {
341
354
  onMouseEnter={() => setSelectedIndex(globalIndex)}
342
355
  >
343
356
  <div className="d-flex align-items-center">
344
- <i
357
+ <i
345
358
  className={`${app.iconClassName} me-3`}
346
- style={{
347
- fontSize: '16px',
348
- color: isSelected ? (isDark ? '#ffffff' : '#0d6efd') : '#6c757d',
349
- minWidth: '16px'
359
+ style={{
360
+ fontSize: "16px",
361
+ color: isSelected ? (isDark ? "#ffffff" : "#0d6efd") : "#6c757d",
362
+ minWidth: "16px",
350
363
  }}
351
364
  />
352
365
  <div>
353
366
  <div className="fw-medium">{app.displayName}</div>
354
- <div
355
- className="small text-muted"
356
- style={{ fontSize: '12px' }}
357
- >
358
- {app.packageId === 'system-apps' ? 'System App' : app.packageName}
367
+ <div className="small text-muted" style={{ fontSize: "12px" }}>
368
+ {app.packageId === "system-apps" ? "System App" : app.packageName}
359
369
  </div>
360
370
  </div>
361
371
  </div>
@@ -366,110 +376,119 @@ export function CommandPaletteOverlay() {
366
376
  )}
367
377
 
368
378
  {/* Commands Section - Group commands by category */}
369
- {filteredCommands.length > 0 && Object.entries(
370
- filteredCommands.reduce((acc, cmd) => {
371
- const category = cmd.category || 'Other';
372
- if (!acc[category]) acc[category] = [];
373
- acc[category].push(cmd);
374
- return acc;
375
- }, {} as Record<string, Command[]>)
376
- ).map(([category, commands]) => (
377
- <div key={category}>
378
- {/* Category Header */}
379
- <div
380
- className="px-3 py-1 small text-muted fw-bold text-uppercase"
381
- style={{ fontSize: '11px', letterSpacing: '0.5px' }}
382
- >
383
- {category}
384
- </div>
385
-
386
- {/* Commands in Category */}
387
- {commands.map((command) => {
388
- const commandId = `command-${command.id}`;
389
- const globalIndex = allItems.findIndex(item => item.id === commandId);
390
- const isSelected = globalIndex === selectedIndex;
391
-
392
- return (
393
- <div
394
- key={command.id}
395
- className={`px-3 py-2 d-flex align-items-center justify-content-between ${
396
- isSelected
397
- ? (isDark ? 'bg-primary bg-opacity-25' : 'bg-primary bg-opacity-10')
398
- : ''
399
- }`}
400
- style={{
401
- cursor: 'pointer',
402
- transition: 'background-color 0.1s ease'
403
- }}
404
- onClick={() => executeCommand(command.id)}
405
- onMouseEnter={() => setSelectedIndex(globalIndex)}
406
- >
407
- <div className="d-flex align-items-center">
408
- {command.iconClassName && (
409
- <i
410
- className={`${command.iconClassName} me-3`}
411
- style={{
412
- fontSize: '16px',
413
- color: isSelected ? (isDark ? '#ffffff' : '#0d6efd') : '#6c757d',
414
- minWidth: '16px'
415
- }}
416
- />
417
- )}
418
- <div>
419
- <div className="fw-medium">{command.label}</div>
420
- {command.description && (
421
- <div
422
- className="small text-muted"
423
- style={{ fontSize: '12px' }}
424
- >
425
- {command.description}
426
- </div>
379
+ {filteredCommands.length > 0 &&
380
+ Object.entries(
381
+ filteredCommands.reduce(
382
+ (acc, cmd) => {
383
+ const category = cmd.category || "Other";
384
+ if (!acc[category]) acc[category] = [];
385
+ acc[category].push(cmd);
386
+ return acc;
387
+ },
388
+ {} as Record<string, Command[]>,
389
+ ),
390
+ ).map(([category, commands]) => (
391
+ <div key={category}>
392
+ {/* Category Header */}
393
+ <div
394
+ className="px-3 py-1 small text-muted fw-bold text-uppercase"
395
+ style={{ fontSize: "11px", letterSpacing: "0.5px" }}
396
+ >
397
+ {category}
398
+ </div>
399
+
400
+ {/* Commands in Category */}
401
+ {commands.map((command) => {
402
+ const commandId = `command-${command.id}`;
403
+ const globalIndex = allItems.findIndex((item) => item.id === commandId);
404
+ const isSelected = globalIndex === selectedIndex;
405
+
406
+ return (
407
+ <div
408
+ key={command.id}
409
+ className={`px-3 py-2 d-flex align-items-center justify-content-between ${
410
+ isSelected
411
+ ? isDark
412
+ ? "bg-primary bg-opacity-25"
413
+ : "bg-primary bg-opacity-10"
414
+ : ""
415
+ }`}
416
+ style={{
417
+ cursor: "pointer",
418
+ transition: "background-color 0.1s ease",
419
+ }}
420
+ onClick={() => executeCommand(command.id)}
421
+ onMouseEnter={() => setSelectedIndex(globalIndex)}
422
+ >
423
+ <div className="d-flex align-items-center">
424
+ {command.iconClassName && (
425
+ <i
426
+ className={`${command.iconClassName} me-3`}
427
+ style={{
428
+ fontSize: "16px",
429
+ color: isSelected ? (isDark ? "#ffffff" : "#0d6efd") : "#6c757d",
430
+ minWidth: "16px",
431
+ }}
432
+ />
427
433
  )}
434
+ <div>
435
+ <div className="fw-medium">{command.label}</div>
436
+ {command.description && (
437
+ <div className="small text-muted" style={{ fontSize: "12px" }}>
438
+ {command.description}
439
+ </div>
440
+ )}
441
+ </div>
428
442
  </div>
443
+
444
+ {command.shortcut && (
445
+ <div
446
+ className={`small px-2 py-1 rounded ${
447
+ isDark ? "bg-secondary bg-opacity-50" : "bg-light"
448
+ }`}
449
+ style={{
450
+ fontSize: "11px",
451
+ fontFamily: "monospace",
452
+ color: isDark ? "#adb5bd" : "#6c757d",
453
+ border: isDark ? "1px solid #495057" : "1px solid #dee2e6",
454
+ }}
455
+ >
456
+ {command.shortcut}
457
+ </div>
458
+ )}
429
459
  </div>
430
-
431
- {command.shortcut && (
432
- <div
433
- className={`small px-2 py-1 rounded ${
434
- isDark ? 'bg-secondary bg-opacity-50' : 'bg-light'
435
- }`}
436
- style={{
437
- fontSize: '11px',
438
- fontFamily: 'monospace',
439
- color: isDark ? '#adb5bd' : '#6c757d',
440
- border: isDark ? '1px solid #495057' : '1px solid #dee2e6'
441
- }}
442
- >
443
- {command.shortcut}
444
- </div>
445
- )}
446
- </div>
447
- );
448
- })}
449
- </div>
450
- ))}
460
+ );
461
+ })}
462
+ </div>
463
+ ))}
451
464
 
452
465
  {/* New Thread Indicator - Show when there's a search query */}
453
466
  {searchQuery.trim() && (
454
467
  <div>
455
- <div
468
+ <div
456
469
  className="px-3 py-1 small text-muted fw-bold text-uppercase"
457
- style={{ fontSize: '11px', letterSpacing: '0.5px' }}
470
+ style={{ fontSize: "11px", letterSpacing: "0.5px" }}
458
471
  >
459
472
  Actions
460
473
  </div>
461
474
  <div
462
475
  className={`px-3 py-2 d-flex align-items-center ${
463
- (allItems.length === 0 || selectedIndex >= allItems.length) && searchQuery.trim()
464
- ? (isDark ? 'bg-primary bg-opacity-25' : 'bg-primary bg-opacity-10')
465
- : ''
476
+ (allItems.length === 0 || selectedIndex >= allItems.length) &&
477
+ searchQuery.trim()
478
+ ? isDark
479
+ ? "bg-primary bg-opacity-25"
480
+ : "bg-primary bg-opacity-10"
481
+ : ""
466
482
  }`}
467
483
  style={{
468
- cursor: 'pointer',
469
- transition: 'background-color 0.1s ease',
470
- borderTop: allItems.length > 0 ? `1px solid ${isDark ? '#495057' : '#dee2e6'}` : 'none',
471
- marginTop: allItems.length > 0 ? '8px' : '0',
472
- paddingTop: allItems.length > 0 ? '12px' : '8px'
484
+ cursor: "pointer",
485
+ transition: "background-color 0.1s ease",
486
+ borderTop:
487
+ allItems.length > 0
488
+ ? `1px solid ${isDark ? "#495057" : "#dee2e6"}`
489
+ : "none",
490
+ marginTop: allItems.length > 0 ? "8px" : "0",
491
+ paddingTop: allItems.length > 0 ? "12px" : "8px",
473
492
  }}
474
493
  onClick={() => {
475
494
  closeCommandPalette();
@@ -481,24 +500,29 @@ export function CommandPaletteOverlay() {
481
500
  }}
482
501
  >
483
502
  <div className="d-flex align-items-center">
484
- <i
503
+ <i
485
504
  className="bi-chat-dots me-3"
486
- style={{
487
- fontSize: '16px',
488
- color: (allItems.length === 0 || selectedIndex >= allItems.length) && searchQuery.trim()
489
- ? (isDark ? '#ffffff' : '#0d6efd')
490
- : '#6c757d',
491
- minWidth: '16px'
505
+ style={{
506
+ fontSize: "16px",
507
+ color:
508
+ (allItems.length === 0 || selectedIndex >= allItems.length) &&
509
+ searchQuery.trim()
510
+ ? isDark
511
+ ? "#ffffff"
512
+ : "#0d6efd"
513
+ : "#6c757d",
514
+ minWidth: "16px",
492
515
  }}
493
516
  />
494
517
  <div>
495
518
  <div className="fw-medium">
496
- Start new thread: <span className="text-muted">{searchQuery.trim().slice(0, 50)}{searchQuery.trim().length > 50 ? '...' : ''}</span>
519
+ Start new thread:{" "}
520
+ <span className="text-muted">
521
+ {searchQuery.trim().slice(0, 50)}
522
+ {searchQuery.trim().length > 50 ? "..." : ""}
523
+ </span>
497
524
  </div>
498
- <div
499
- className="small text-muted"
500
- style={{ fontSize: '12px' }}
501
- >
525
+ <div className="small text-muted" style={{ fontSize: "12px" }}>
502
526
  Press Enter to create
503
527
  </div>
504
528
  </div>
@@ -509,13 +533,13 @@ export function CommandPaletteOverlay() {
509
533
  </div>
510
534
  )}
511
535
  </div>
512
-
536
+
513
537
  {/* Footer */}
514
- <div
538
+ <div
515
539
  className={`px-3 py-2 small text-muted border-top d-flex align-items-center justify-content-between`}
516
540
  style={{
517
- borderTopColor: isDark ? '#495057' : '#dee2e6',
518
- fontSize: '11px'
541
+ borderTopColor: isDark ? "#495057" : "#dee2e6",
542
+ fontSize: "11px",
519
543
  }}
520
544
  >
521
545
  <div className="d-flex align-items-center gap-3">
@@ -530,11 +554,11 @@ export function CommandPaletteOverlay() {
530
554
  </span>
531
555
  </div>
532
556
  <div>
533
- {allItems.length} result{allItems.length !== 1 ? 's' : ''}
534
- {searchQuery.trim() && allItems.length === 0 && ' • Start thread'}
557
+ {allItems.length} result{allItems.length !== 1 ? "s" : ""}
558
+ {searchQuery.trim() && allItems.length === 0 && " • Start thread"}
535
559
  </div>
536
560
  </div>
537
561
  </div>
538
562
  </div>
539
563
  );
540
- }
564
+ }