@elizaos/app-core 2.0.0-alpha.74 → 2.0.0-alpha.76

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 (1183) hide show
  1. package/App.d.ts.map +1 -0
  2. package/{dist/App.js → App.js} +3 -3
  3. package/{dist/components → components}/AdvancedPageView.d.ts.map +1 -1
  4. package/{dist/components → components}/AdvancedPageView.js +0 -10
  5. package/{dist/components → components}/CharacterView.d.ts.map +1 -1
  6. package/components/CharacterView.js +685 -0
  7. package/{dist/components → components}/ChatComposer.d.ts.map +1 -1
  8. package/{dist/components → components}/ChatComposer.js +4 -4
  9. package/{dist/components → components}/ChatView.d.ts.map +1 -1
  10. package/{dist/components → components}/ChatView.js +15 -0
  11. package/{dist/components → components}/CompanionView.js +1 -1
  12. package/{dist/components → components}/ConfigPageView.js +1 -1
  13. package/{dist/components → components}/ElizaCloudDashboard.js +1 -1
  14. package/{dist/components → components}/FlaminaGuide.js +1 -1
  15. package/{dist/components → components}/OnboardingWizard.d.ts.map +1 -1
  16. package/{dist/components → components}/OnboardingWizard.js +3 -2
  17. package/{dist/components → components}/PluginsView.d.ts.map +1 -1
  18. package/{dist/components → components}/PluginsView.js +1 -5
  19. package/{dist/components → components}/avatar/VrmEngine.d.ts +13 -0
  20. package/{dist/components → components}/avatar/VrmEngine.d.ts.map +1 -1
  21. package/{dist/components → components}/avatar/VrmEngine.js +66 -0
  22. package/{dist/components → components}/avatar/VrmViewer.d.ts +15 -0
  23. package/{dist/components → components}/avatar/VrmViewer.d.ts.map +1 -1
  24. package/{dist/components → components}/avatar/VrmViewer.js +56 -1
  25. package/{src/components/index.ts → components/index.d.ts} +1 -1
  26. package/{dist/components → components}/index.d.ts.map +1 -1
  27. package/{dist/components → components}/index.js +0 -1
  28. package/{dist/components → components}/onboarding/ConnectionStep.d.ts.map +1 -1
  29. package/{dist/components → components}/onboarding/ConnectionStep.js +12 -7
  30. package/{dist/components → components}/permissions/StreamingPermissions.d.ts.map +1 -1
  31. package/{dist/components → components}/permissions/StreamingPermissions.js +1 -1
  32. package/{dist/components → components}/ui-switch.js +4 -4
  33. package/{dist/i18n → i18n}/locales/en.json +45 -1
  34. package/{src/i18n → i18n}/locales/es.json +41 -0
  35. package/{dist/i18n → i18n}/locales/ko.json +41 -0
  36. package/{dist/i18n → i18n}/locales/pt.json +41 -0
  37. package/{dist/i18n → i18n}/locales/zh-CN.json +41 -0
  38. package/package.json +143 -53
  39. package/{dist/state → state}/AppContext.d.ts.map +1 -1
  40. package/{dist/state → state}/AppContext.js +38 -16
  41. package/{dist/styles → styles}/anime.css +1 -4
  42. package/{dist/styles → styles}/onboarding-game.css +125 -9
  43. package/.turbo/turbo-build.log +0 -2
  44. package/.turbo/turbo-lint$colon$check.log +0 -2
  45. package/.turbo/turbo-typecheck.log +0 -1
  46. package/dist/App.d.ts.map +0 -1
  47. package/dist/components/CharacterView.js +0 -719
  48. package/dist/components/MiladyBar.d.ts +0 -2
  49. package/dist/components/MiladyBar.d.ts.map +0 -1
  50. package/dist/components/MiladyBar.js +0 -50
  51. package/dist/components/MiladyBarSettings.d.ts +0 -2
  52. package/dist/components/MiladyBarSettings.d.ts.map +0 -1
  53. package/dist/components/MiladyBarSettings.js +0 -513
  54. package/dist/components/SecurityPageView.d.ts +0 -2
  55. package/dist/components/SecurityPageView.d.ts.map +0 -1
  56. package/dist/components/SecurityPageView.js +0 -81
  57. package/dist/components/index.d.ts +0 -97
  58. package/dist/components/milady-bar/CloudCreditsChip.d.ts +0 -2
  59. package/dist/components/milady-bar/CloudCreditsChip.d.ts.map +0 -1
  60. package/dist/components/milady-bar/CloudCreditsChip.js +0 -25
  61. package/dist/components/milady-bar/ProviderDropdown.d.ts +0 -13
  62. package/dist/components/milady-bar/ProviderDropdown.d.ts.map +0 -1
  63. package/dist/components/milady-bar/ProviderDropdown.js +0 -68
  64. package/dist/components/milady-bar/WalletSummary.d.ts +0 -2
  65. package/dist/components/milady-bar/WalletSummary.d.ts.map +0 -1
  66. package/dist/components/milady-bar/WalletSummary.js +0 -37
  67. package/dist/components/milady-bar/index.d.ts +0 -4
  68. package/dist/components/milady-bar/index.d.ts.map +0 -1
  69. package/dist/components/milady-bar/index.js +0 -3
  70. package/dist/hooks/useMiladyBar.d.ts +0 -2
  71. package/dist/hooks/useMiladyBar.d.ts.map +0 -1
  72. package/dist/hooks/useMiladyBar.js +0 -472
  73. package/dist/i18n/locales/es.json +0 -1195
  74. package/dist/package.json +0 -180
  75. package/src/App.tsx +0 -504
  76. package/src/actions/character.test.ts +0 -139
  77. package/src/actions/character.ts +0 -334
  78. package/src/actions/chat-helpers.ts +0 -100
  79. package/src/actions/cloud.ts +0 -59
  80. package/src/actions/index.ts +0 -12
  81. package/src/actions/lifecycle.ts +0 -175
  82. package/src/actions/onboarding.ts +0 -38
  83. package/src/actions/triggers.ts +0 -190
  84. package/src/ambient.d.ts +0 -33
  85. package/src/api/client.ts +0 -5659
  86. package/src/api/index.ts +0 -1
  87. package/src/autonomy/index.ts +0 -477
  88. package/src/bridge/capacitor-bridge.ts +0 -295
  89. package/src/bridge/electrobun-rpc.ts +0 -78
  90. package/src/bridge/electrobun-runtime.ts +0 -28
  91. package/src/bridge/index.ts +0 -5
  92. package/src/bridge/native-plugins.ts +0 -138
  93. package/src/bridge/plugin-bridge.ts +0 -352
  94. package/src/bridge/storage-bridge.ts +0 -162
  95. package/src/chat/index.ts +0 -250
  96. package/src/coding/index.ts +0 -43
  97. package/src/components/AdvancedPageView.tsx +0 -382
  98. package/src/components/AgentActivityBox.tsx +0 -49
  99. package/src/components/ApiKeyConfig.tsx +0 -222
  100. package/src/components/AppsPageView.tsx +0 -52
  101. package/src/components/AppsView.tsx +0 -293
  102. package/src/components/AvatarLoader.tsx +0 -104
  103. package/src/components/AvatarSelector.tsx +0 -223
  104. package/src/components/BscTradePanel.tsx +0 -549
  105. package/src/components/BugReportModal.tsx +0 -499
  106. package/src/components/CharacterRoster.tsx +0 -143
  107. package/src/components/CharacterView.tsx +0 -1575
  108. package/src/components/ChatAvatar.test.ts +0 -97
  109. package/src/components/ChatAvatar.tsx +0 -147
  110. package/src/components/ChatComposer.tsx +0 -330
  111. package/src/components/ChatMessage.tsx +0 -448
  112. package/src/components/ChatModalView.test.tsx +0 -118
  113. package/src/components/ChatModalView.tsx +0 -125
  114. package/src/components/ChatView.tsx +0 -992
  115. package/src/components/CloudOnboarding.tsx +0 -81
  116. package/src/components/CloudSourceControls.tsx +0 -85
  117. package/src/components/CodingAgentSettingsSection.tsx +0 -537
  118. package/src/components/CommandPalette.tsx +0 -284
  119. package/src/components/CompanionSceneHost.tsx +0 -517
  120. package/src/components/CompanionShell.tsx +0 -31
  121. package/src/components/CompanionView.tsx +0 -110
  122. package/src/components/ConfigPageView.tsx +0 -763
  123. package/src/components/ConfigSaveFooter.tsx +0 -41
  124. package/src/components/ConfirmModal.tsx +0 -379
  125. package/src/components/ConnectionFailedBanner.tsx +0 -91
  126. package/src/components/ConnectorsPageView.tsx +0 -13
  127. package/src/components/ConversationsSidebar.tsx +0 -279
  128. package/src/components/CustomActionEditor.tsx +0 -1127
  129. package/src/components/CustomActionsPanel.tsx +0 -288
  130. package/src/components/CustomActionsView.tsx +0 -325
  131. package/src/components/DatabasePageView.tsx +0 -55
  132. package/src/components/DatabaseView.tsx +0 -814
  133. package/src/components/ElizaCloudDashboard.tsx +0 -1696
  134. package/src/components/EmotePicker.tsx +0 -529
  135. package/src/components/ErrorBoundary.tsx +0 -76
  136. package/src/components/FineTuningView.tsx +0 -1080
  137. package/src/components/FlaminaGuide.test.tsx +0 -61
  138. package/src/components/FlaminaGuide.tsx +0 -212
  139. package/src/components/GameView.tsx +0 -551
  140. package/src/components/GameViewOverlay.tsx +0 -133
  141. package/src/components/GlobalEmoteOverlay.tsx +0 -152
  142. package/src/components/Header.test.tsx +0 -413
  143. package/src/components/Header.tsx +0 -400
  144. package/src/components/HeartbeatsView.tsx +0 -1003
  145. package/src/components/InventoryView.tsx +0 -393
  146. package/src/components/KnowledgeView.tsx +0 -1128
  147. package/src/components/LanguageDropdown.tsx +0 -192
  148. package/src/components/LifoMonitorPanel.tsx +0 -196
  149. package/src/components/LifoSandboxView.tsx +0 -499
  150. package/src/components/LoadingScreen.tsx +0 -112
  151. package/src/components/LogsPageView.tsx +0 -17
  152. package/src/components/LogsView.tsx +0 -239
  153. package/src/components/MediaGalleryView.tsx +0 -431
  154. package/src/components/MediaSettingsSection.tsx +0 -893
  155. package/src/components/MessageContent.tsx +0 -815
  156. package/src/components/MiladyBar.tsx +0 -103
  157. package/src/components/MiladyBarSettings.tsx +0 -872
  158. package/src/components/OnboardingWizard.test.tsx +0 -104
  159. package/src/components/OnboardingWizard.tsx +0 -249
  160. package/src/components/PairingView.tsx +0 -109
  161. package/src/components/PermissionsSection.tsx +0 -1184
  162. package/src/components/PluginsPageView.tsx +0 -9
  163. package/src/components/PluginsView.tsx +0 -3129
  164. package/src/components/ProviderSwitcher.tsx +0 -903
  165. package/src/components/RestartBanner.tsx +0 -76
  166. package/src/components/RuntimeView.tsx +0 -460
  167. package/src/components/SaveCommandModal.tsx +0 -211
  168. package/src/components/SecretsView.tsx +0 -569
  169. package/src/components/SecurityPageView.tsx +0 -242
  170. package/src/components/SettingsView.tsx +0 -825
  171. package/src/components/ShellOverlays.tsx +0 -41
  172. package/src/components/ShortcutsOverlay.tsx +0 -155
  173. package/src/components/SkillsView.tsx +0 -1435
  174. package/src/components/StartupFailureView.tsx +0 -63
  175. package/src/components/StreamView.tsx +0 -481
  176. package/src/components/StripeEmbeddedCheckout.tsx +0 -155
  177. package/src/components/SubscriptionStatus.tsx +0 -640
  178. package/src/components/SystemWarningBanner.tsx +0 -71
  179. package/src/components/ThemeToggle.tsx +0 -103
  180. package/src/components/TrajectoriesView.tsx +0 -526
  181. package/src/components/TrajectoryDetailView.tsx +0 -426
  182. package/src/components/TriggersView.tsx +0 -1
  183. package/src/components/VectorBrowserView.tsx +0 -1633
  184. package/src/components/VoiceConfigView.tsx +0 -674
  185. package/src/components/VrmStage.test.ts +0 -176
  186. package/src/components/VrmStage.tsx +0 -309
  187. package/src/components/WhatsAppQrOverlay.tsx +0 -230
  188. package/src/components/__tests__/chainConfig.test.ts +0 -220
  189. package/src/components/apps/AppDetailPane.tsx +0 -242
  190. package/src/components/apps/AppsCatalogGrid.tsx +0 -137
  191. package/src/components/apps/extensions/registry.ts +0 -13
  192. package/src/components/apps/extensions/types.ts +0 -9
  193. package/src/components/apps/helpers.ts +0 -43
  194. package/src/components/avatar/VrmAnimationLoader.test.ts +0 -164
  195. package/src/components/avatar/VrmAnimationLoader.ts +0 -151
  196. package/src/components/avatar/VrmBlinkController.ts +0 -118
  197. package/src/components/avatar/VrmCameraManager.ts +0 -407
  198. package/src/components/avatar/VrmEngine.ts +0 -2767
  199. package/src/components/avatar/VrmFootShadow.ts +0 -96
  200. package/src/components/avatar/VrmViewer.tsx +0 -421
  201. package/src/components/avatar/__tests__/VrmCameraManager.test.ts +0 -168
  202. package/src/components/avatar/__tests__/VrmEngine.test.ts +0 -1574
  203. package/src/components/avatar/mixamoVRMRigMap.ts +0 -62
  204. package/src/components/avatar/retargetMixamoFbxToVrm.ts +0 -144
  205. package/src/components/avatar/retargetMixamoGltfToVrm.ts +0 -119
  206. package/src/components/chainConfig.ts +0 -400
  207. package/src/components/companion/CompanionHeader.tsx +0 -50
  208. package/src/components/companion/CompanionSceneHost.tsx +0 -5
  209. package/src/components/companion/VrmStage.tsx +0 -2
  210. package/src/components/companion/__tests__/walletUtils.test.ts +0 -742
  211. package/src/components/companion/index.ts +0 -18
  212. package/src/components/companion/walletUtils.ts +0 -290
  213. package/src/components/companion-shell-styles.test.ts +0 -142
  214. package/src/components/companion-shell-styles.ts +0 -270
  215. package/src/components/confirm-delete-control.tsx +0 -69
  216. package/src/components/conversations/ConversationListItem.tsx +0 -185
  217. package/src/components/conversations/conversation-utils.ts +0 -151
  218. package/src/components/format.ts +0 -131
  219. package/src/components/inventory/CopyableAddress.tsx +0 -41
  220. package/src/components/inventory/InventoryToolbar.tsx +0 -142
  221. package/src/components/inventory/NftGrid.tsx +0 -99
  222. package/src/components/inventory/TokenLogo.tsx +0 -71
  223. package/src/components/inventory/TokensTable.tsx +0 -216
  224. package/src/components/inventory/constants.ts +0 -170
  225. package/src/components/inventory/index.ts +0 -29
  226. package/src/components/inventory/media-url.test.ts +0 -38
  227. package/src/components/inventory/media-url.ts +0 -36
  228. package/src/components/inventory/useInventoryData.ts +0 -460
  229. package/src/components/knowledge-upload-image.ts +0 -215
  230. package/src/components/labels.ts +0 -46
  231. package/src/components/milady-bar/CloudCreditsChip.tsx +0 -61
  232. package/src/components/milady-bar/ProviderDropdown.tsx +0 -166
  233. package/src/components/milady-bar/WalletSummary.tsx +0 -61
  234. package/src/components/milady-bar/index.ts +0 -3
  235. package/src/components/onboarding/ActivateStep.tsx +0 -34
  236. package/src/components/onboarding/ConnectionStep.tsx +0 -1590
  237. package/src/components/onboarding/IdentityStep.tsx +0 -251
  238. package/src/components/onboarding/OnboardingPanel.tsx +0 -39
  239. package/src/components/onboarding/OnboardingStepNav.tsx +0 -41
  240. package/src/components/onboarding/PermissionsStep.tsx +0 -20
  241. package/src/components/onboarding/RpcStep.tsx +0 -402
  242. package/src/components/permissions/PermissionIcon.tsx +0 -25
  243. package/src/components/permissions/StreamingPermissions.tsx +0 -413
  244. package/src/components/plugins/showcase-data.ts +0 -481
  245. package/src/components/shared/ShellHeaderControls.tsx +0 -198
  246. package/src/components/shared-companion-scene-context.ts +0 -15
  247. package/src/components/skeletons.tsx +0 -88
  248. package/src/components/stream/ActivityFeed.tsx +0 -113
  249. package/src/components/stream/AvatarPip.tsx +0 -10
  250. package/src/components/stream/ChatContent.tsx +0 -126
  251. package/src/components/stream/ChatTicker.tsx +0 -55
  252. package/src/components/stream/IdleContent.tsx +0 -73
  253. package/src/components/stream/StatusBar.tsx +0 -463
  254. package/src/components/stream/StreamSettings.tsx +0 -506
  255. package/src/components/stream/StreamTerminal.tsx +0 -94
  256. package/src/components/stream/StreamVoiceConfig.tsx +0 -160
  257. package/src/components/stream/helpers.ts +0 -134
  258. package/src/components/stream/overlays/OverlayLayer.tsx +0 -75
  259. package/src/components/stream/overlays/built-in/ActionTickerWidget.tsx +0 -64
  260. package/src/components/stream/overlays/built-in/AlertPopupWidget.tsx +0 -87
  261. package/src/components/stream/overlays/built-in/BrandingWidget.tsx +0 -51
  262. package/src/components/stream/overlays/built-in/CustomHtmlWidget.tsx +0 -105
  263. package/src/components/stream/overlays/built-in/PeonGlassWidget.tsx +0 -265
  264. package/src/components/stream/overlays/built-in/PeonHudWidget.tsx +0 -247
  265. package/src/components/stream/overlays/built-in/PeonSakuraWidget.tsx +0 -278
  266. package/src/components/stream/overlays/built-in/ThoughtBubbleWidget.tsx +0 -77
  267. package/src/components/stream/overlays/built-in/ViewerCountWidget.tsx +0 -46
  268. package/src/components/stream/overlays/built-in/index.ts +0 -13
  269. package/src/components/stream/overlays/registry.ts +0 -22
  270. package/src/components/stream/overlays/types.ts +0 -90
  271. package/src/components/stream/overlays/useOverlayLayout.ts +0 -218
  272. package/src/components/trajectory-format.ts +0 -50
  273. package/src/components/ui-badges.tsx +0 -109
  274. package/src/components/ui-switch.tsx +0 -57
  275. package/src/components/vector-browser-three.ts +0 -29
  276. package/src/config/branding.ts +0 -67
  277. package/src/config/config-catalog.ts +0 -1092
  278. package/src/config/config-field.tsx +0 -1924
  279. package/src/config/config-renderer.tsx +0 -734
  280. package/src/config/index.ts +0 -12
  281. package/src/config/ui-renderer.tsx +0 -1751
  282. package/src/config/ui-spec.ts +0 -256
  283. package/src/events/index.ts +0 -96
  284. package/src/hooks/index.ts +0 -14
  285. package/src/hooks/useBugReport.tsx +0 -43
  286. package/src/hooks/useCanvasWindow.ts +0 -372
  287. package/src/hooks/useChatAvatarVoice.ts +0 -111
  288. package/src/hooks/useClickOutside.ts +0 -31
  289. package/src/hooks/useContextMenu.ts +0 -127
  290. package/src/hooks/useKeyboardShortcuts.ts +0 -86
  291. package/src/hooks/useLifoSync.ts +0 -143
  292. package/src/hooks/useMemoryMonitor.ts +0 -334
  293. package/src/hooks/useMiladyBar.ts +0 -594
  294. package/src/hooks/useRenderGuard.ts +0 -43
  295. package/src/hooks/useRetakeCapture.ts +0 -68
  296. package/src/hooks/useStreamPopoutNavigation.ts +0 -27
  297. package/src/hooks/useTimeout.ts +0 -37
  298. package/src/hooks/useVoiceChat.ts +0 -1442
  299. package/src/hooks/useWhatsAppPairing.ts +0 -123
  300. package/src/i18n/index.ts +0 -76
  301. package/src/i18n/locales/en.json +0 -1195
  302. package/src/i18n/locales/ko.json +0 -1195
  303. package/src/i18n/locales/pt.json +0 -1195
  304. package/src/i18n/locales/zh-CN.json +0 -1195
  305. package/src/i18n/messages.ts +0 -21
  306. package/src/index.ts +0 -6
  307. package/src/navigation/index.ts +0 -286
  308. package/src/navigation.test.ts +0 -189
  309. package/src/onboarding-config.test.ts +0 -104
  310. package/src/onboarding-config.ts +0 -122
  311. package/src/platform/browser-launch.test.ts +0 -94
  312. package/src/platform/browser-launch.ts +0 -149
  313. package/src/platform/index.ts +0 -58
  314. package/src/platform/init.ts +0 -238
  315. package/src/platform/lifo.ts +0 -225
  316. package/src/providers/index.ts +0 -108
  317. package/src/shell-params.test.ts +0 -48
  318. package/src/shell-params.ts +0 -36
  319. package/src/state/AppContext.tsx +0 -6415
  320. package/src/state/index.ts +0 -6
  321. package/src/state/internal.ts +0 -91
  322. package/src/state/onboarding-resume.test.ts +0 -135
  323. package/src/state/onboarding-resume.ts +0 -263
  324. package/src/state/parsers.test.ts +0 -124
  325. package/src/state/parsers.ts +0 -309
  326. package/src/state/persistence.ts +0 -379
  327. package/src/state/shell-routing.ts +0 -39
  328. package/src/state/types.ts +0 -724
  329. package/src/state/ui-preferences.ts +0 -3
  330. package/src/state/useApp.ts +0 -23
  331. package/src/state/vrm.ts +0 -108
  332. package/src/styles/anime.css +0 -6324
  333. package/src/styles/base.css +0 -213
  334. package/src/styles/onboarding-game.css +0 -976
  335. package/src/styles/styles.css +0 -2087
  336. package/src/styles/xterm.css +0 -241
  337. package/src/types/index.ts +0 -715
  338. package/src/types/react-test-renderer.d.ts +0 -45
  339. package/src/utils/asset-url.ts +0 -110
  340. package/src/utils/assistant-text.ts +0 -172
  341. package/src/utils/clipboard.ts +0 -41
  342. package/src/utils/desktop-dialogs.ts +0 -80
  343. package/src/utils/eliza-globals.ts +0 -44
  344. package/src/utils/index.ts +0 -7
  345. package/src/utils/number-parsing.ts +0 -125
  346. package/src/utils/openExternalUrl.ts +0 -20
  347. package/src/utils/spoken-text.ts +0 -65
  348. package/src/utils/streaming-text.ts +0 -120
  349. package/src/voice/index.ts +0 -1
  350. package/src/voice/types.ts +0 -197
  351. package/src/wallet-rpc.ts +0 -176
  352. package/test/app/AppContext.pty-sessions.test.tsx +0 -143
  353. package/test/app/MessageContent.test.tsx +0 -366
  354. package/test/app/PermissionsOnboarding.test.tsx +0 -358
  355. package/test/app/PermissionsSection.test.tsx +0 -575
  356. package/test/app/advanced-trajectory-fine-tuning.e2e.test.ts +0 -396
  357. package/test/app/agent-activity-box.test.tsx +0 -132
  358. package/test/app/agent-transfer-lock.test.ts +0 -279
  359. package/test/app/api-client-electrobun-fallback.test.ts +0 -139
  360. package/test/app/api-client-electron-fallback.test.ts +0 -139
  361. package/test/app/api-client-timeout.test.ts +0 -75
  362. package/test/app/api-client-ws.test.ts +0 -98
  363. package/test/app/api-client.ws-max-reconnect.test.ts +0 -139
  364. package/test/app/api-client.ws-reconnect.test.ts +0 -157
  365. package/test/app/app-context-autonomy-events.test.ts +0 -559
  366. package/test/app/apps-page-view.test.ts +0 -114
  367. package/test/app/apps-view.test.ts +0 -768
  368. package/test/app/autonomous-workflows.e2e.test.ts +0 -765
  369. package/test/app/autonomy-events.test.ts +0 -150
  370. package/test/app/avatar-selector.test.tsx +0 -52
  371. package/test/app/bsc-trade-panel.test.tsx +0 -134
  372. package/test/app/bug-report-modal.test.tsx +0 -353
  373. package/test/app/character-action-bar-visibility.test.ts +0 -70
  374. package/test/app/character-customization.e2e.test.ts +0 -1384
  375. package/test/app/character-save-journey.test.ts +0 -1245
  376. package/test/app/chat-advanced-features.e2e.test.ts +0 -706
  377. package/test/app/chat-composer.test.tsx +0 -181
  378. package/test/app/chat-journey.test.ts +0 -1075
  379. package/test/app/chat-language-header.test.ts +0 -64
  380. package/test/app/chat-message.test.tsx +0 -222
  381. package/test/app/chat-modal-view.test.tsx +0 -191
  382. package/test/app/chat-routine-filter.test.ts +0 -96
  383. package/test/app/chat-send-lock.test.ts +0 -1465
  384. package/test/app/chat-stream-api-client.test.tsx +0 -390
  385. package/test/app/chat-view-game-modal.test.tsx +0 -661
  386. package/test/app/chat-view.test.tsx +0 -877
  387. package/test/app/cloud-api.e2e.test.ts +0 -258
  388. package/test/app/cloud-login-flow.e2e.test.ts +0 -494
  389. package/test/app/cloud-login-lock.test.ts +0 -416
  390. package/test/app/command-palette.test.tsx +0 -184
  391. package/test/app/command-registry.test.ts +0 -75
  392. package/test/app/companion-greeting-wave.test.tsx +0 -431
  393. package/test/app/companion-scene-host.test.tsx +0 -85
  394. package/test/app/companion-stale-conversation.test.tsx +0 -447
  395. package/test/app/companion-view.test.tsx +0 -690
  396. package/test/app/confirm-delete-control.test.ts +0 -79
  397. package/test/app/confirm-modal.test.tsx +0 -219
  398. package/test/app/connection-mode-persistence.test.ts +0 -411
  399. package/test/app/connectors-ui.e2e.test.ts +0 -508
  400. package/test/app/conversations-sidebar-game-modal.test.tsx +0 -265
  401. package/test/app/conversations-sidebar.test.tsx +0 -185
  402. package/test/app/custom-actions-smoke.test.ts +0 -387
  403. package/test/app/custom-avatar-api-client.test.ts +0 -207
  404. package/test/app/desktop-utils.test.ts +0 -145
  405. package/test/app/electrobun-rpc-bridge.test.ts +0 -83
  406. package/test/app/events.test.ts +0 -88
  407. package/test/app/export-import-flows.e2e.test.ts +0 -700
  408. package/test/app/fine-tuning-view.test.ts +0 -471
  409. package/test/app/game-view-auth-session.test.tsx +0 -187
  410. package/test/app/game-view.test.ts +0 -444
  411. package/test/app/global-emote-overlay.test.tsx +0 -106
  412. package/test/app/header-status.test.tsx +0 -149
  413. package/test/app/i18n.test.ts +0 -152
  414. package/test/app/inventory-bsc-view.test.ts +0 -940
  415. package/test/app/knowledge-ui.e2e.test.ts +0 -762
  416. package/test/app/knowledge-upload-helpers.test.ts +0 -124
  417. package/test/app/lifecycle-lock.test.ts +0 -267
  418. package/test/app/lifo-popout-utils.test.ts +0 -208
  419. package/test/app/lifo-safe-endpoint.test.ts +0 -34
  420. package/test/app/loading-screen.test.tsx +0 -45
  421. package/test/app/memory-monitor.test.ts +0 -331
  422. package/test/app/milady-bar-regression.test.tsx +0 -519
  423. package/test/app/milady-bar-settings.test.tsx +0 -1056
  424. package/test/app/milady-bar.test.tsx +0 -583
  425. package/test/app/navigation.test.tsx +0 -22
  426. package/test/app/onboarding-e2e-journey.test.ts +0 -1391
  427. package/test/app/onboarding-finish-lock.test.ts +0 -676
  428. package/test/app/onboarding-language.test.tsx +0 -160
  429. package/test/app/onboarding-steps.test.tsx +0 -376
  430. package/test/app/open-external-url.test.ts +0 -65
  431. package/test/app/pages-navigation-smoke.e2e.test.ts +0 -646
  432. package/test/app/pairing-lock.test.ts +0 -260
  433. package/test/app/pairing-view.test.tsx +0 -74
  434. package/test/app/permissions-section.test.ts +0 -432
  435. package/test/app/plugin-bridge.test.ts +0 -109
  436. package/test/app/plugins-ui.e2e.test.ts +0 -605
  437. package/test/app/plugins-view-game-modal.test.tsx +0 -686
  438. package/test/app/plugins-view-toggle-restart.test.ts +0 -129
  439. package/test/app/provider-dropdown-default.test.tsx +0 -300
  440. package/test/app/restart-banner.test.tsx +0 -205
  441. package/test/app/retake-capture.test.ts +0 -84
  442. package/test/app/sandbox-api-client.test.ts +0 -108
  443. package/test/app/save-command-modal.test.tsx +0 -109
  444. package/test/app/secrets-view.test.tsx +0 -92
  445. package/test/app/settings-control-styles.test.tsx +0 -142
  446. package/test/app/settings-reset.e2e.test.ts +0 -726
  447. package/test/app/settings-sections.e2e.test.ts +0 -614
  448. package/test/app/shared-format.test.ts +0 -44
  449. package/test/app/shared-switch.test.ts +0 -69
  450. package/test/app/shell-mode-switching.e2e.test.ts +0 -841
  451. package/test/app/shell-mode-tab-memory.test.tsx +0 -58
  452. package/test/app/shell-overlays.test.tsx +0 -50
  453. package/test/app/shortcuts-overlay.test.tsx +0 -111
  454. package/test/app/sse-interruption.test.ts +0 -122
  455. package/test/app/startup-asset-missing.e2e.test.ts +0 -126
  456. package/test/app/startup-backend-missing.e2e.test.ts +0 -126
  457. package/test/app/startup-chat.e2e.test.ts +0 -323
  458. package/test/app/startup-conversation-restore.test.tsx +0 -381
  459. package/test/app/startup-failure-view.test.tsx +0 -103
  460. package/test/app/startup-onboarding.e2e.test.ts +0 -712
  461. package/test/app/startup-timeout.test.tsx +0 -80
  462. package/test/app/startup-token-401.e2e.test.ts +0 -103
  463. package/test/app/stream-helpers.test.ts +0 -46
  464. package/test/app/stream-popout-navigation.test.tsx +0 -41
  465. package/test/app/stream-status-bar.test.tsx +0 -89
  466. package/test/app/theme-toggle.test.tsx +0 -40
  467. package/test/app/training-api-client.test.ts +0 -128
  468. package/test/app/trajectories-view.test.tsx +0 -220
  469. package/test/app/triggers-api-client.test.ts +0 -77
  470. package/test/app/triggers-navigation.test.ts +0 -113
  471. package/test/app/triggers-view.e2e.test.ts +0 -675
  472. package/test/app/update-channel-lock.test.ts +0 -259
  473. package/test/app/vector-browser.async-cleanup.test.tsx +0 -367
  474. package/test/app/vector-browser.e2e.test.ts +0 -653
  475. package/test/app/vrm-stage.test.tsx +0 -351
  476. package/test/app/vrm-viewer.test.tsx +0 -298
  477. package/test/app/wallet-api-save-lock.test.ts +0 -299
  478. package/test/app/wallet-hooks.test.ts +0 -405
  479. package/test/app/wallet-ui-flows.e2e.test.ts +0 -556
  480. package/test/avatar/asset-url.test.ts +0 -90
  481. package/test/avatar/avatar-selector.test.ts +0 -173
  482. package/test/avatar/mixamo-vrm-rig-map.test.ts +0 -111
  483. package/test/avatar/voice-chat-streaming-text.test.ts +0 -96
  484. package/test/avatar/voice-chat.test.ts +0 -391
  485. package/test/browser-extension/README.md +0 -138
  486. package/test/browser-extension/test-harness.ts +0 -499
  487. package/test/capacitor-plugins.e2e.test.ts +0 -168
  488. package/test/test-types.ts +0 -5
  489. package/test/ui/command-palette-commands.test.ts +0 -57
  490. package/test/ui/ui-renderer.test.ts +0 -39
  491. package/test/utils/assistant-text.test.ts +0 -68
  492. package/test/utils/eliza-globals.test.ts +0 -59
  493. package/test/utils/package-exports.test.ts +0 -70
  494. package/test/utils/streaming-text.test.ts +0 -89
  495. package/tsconfig.build.json +0 -19
  496. package/tsconfig.json +0 -20
  497. package/tsconfig.typecheck.json +0 -12
  498. /package/{dist/App.d.ts → App.d.ts} +0 -0
  499. /package/{dist/actions → actions}/character.d.ts +0 -0
  500. /package/{dist/actions → actions}/character.d.ts.map +0 -0
  501. /package/{dist/actions → actions}/character.js +0 -0
  502. /package/{dist/actions → actions}/chat-helpers.d.ts +0 -0
  503. /package/{dist/actions → actions}/chat-helpers.d.ts.map +0 -0
  504. /package/{dist/actions → actions}/chat-helpers.js +0 -0
  505. /package/{dist/actions → actions}/cloud.d.ts +0 -0
  506. /package/{dist/actions → actions}/cloud.d.ts.map +0 -0
  507. /package/{dist/actions → actions}/cloud.js +0 -0
  508. /package/{dist/actions → actions}/index.d.ts +0 -0
  509. /package/{dist/actions → actions}/index.d.ts.map +0 -0
  510. /package/{dist/actions → actions}/index.js +0 -0
  511. /package/{dist/actions → actions}/lifecycle.d.ts +0 -0
  512. /package/{dist/actions → actions}/lifecycle.d.ts.map +0 -0
  513. /package/{dist/actions → actions}/lifecycle.js +0 -0
  514. /package/{dist/actions → actions}/onboarding.d.ts +0 -0
  515. /package/{dist/actions → actions}/onboarding.d.ts.map +0 -0
  516. /package/{dist/actions → actions}/onboarding.js +0 -0
  517. /package/{dist/actions → actions}/triggers.d.ts +0 -0
  518. /package/{dist/actions → actions}/triggers.d.ts.map +0 -0
  519. /package/{dist/actions → actions}/triggers.js +0 -0
  520. /package/{dist/api → api}/client.d.ts +0 -0
  521. /package/{dist/api → api}/client.d.ts.map +0 -0
  522. /package/{dist/api → api}/client.js +0 -0
  523. /package/{dist/api → api}/index.d.ts +0 -0
  524. /package/{dist/api → api}/index.d.ts.map +0 -0
  525. /package/{dist/api → api}/index.js +0 -0
  526. /package/{dist/autonomy → autonomy}/index.d.ts +0 -0
  527. /package/{dist/autonomy → autonomy}/index.d.ts.map +0 -0
  528. /package/{dist/autonomy → autonomy}/index.js +0 -0
  529. /package/{dist/bridge → bridge}/capacitor-bridge.d.ts +0 -0
  530. /package/{dist/bridge → bridge}/capacitor-bridge.d.ts.map +0 -0
  531. /package/{dist/bridge → bridge}/capacitor-bridge.js +0 -0
  532. /package/{dist/bridge → bridge}/electrobun-rpc.d.ts +0 -0
  533. /package/{dist/bridge → bridge}/electrobun-rpc.d.ts.map +0 -0
  534. /package/{dist/bridge → bridge}/electrobun-rpc.js +0 -0
  535. /package/{dist/bridge → bridge}/electrobun-runtime.d.ts +0 -0
  536. /package/{dist/bridge → bridge}/electrobun-runtime.d.ts.map +0 -0
  537. /package/{dist/bridge → bridge}/electrobun-runtime.js +0 -0
  538. /package/{dist/bridge → bridge}/index.d.ts +0 -0
  539. /package/{dist/bridge → bridge}/index.d.ts.map +0 -0
  540. /package/{dist/bridge → bridge}/index.js +0 -0
  541. /package/{dist/bridge → bridge}/native-plugins.d.ts +0 -0
  542. /package/{dist/bridge → bridge}/native-plugins.d.ts.map +0 -0
  543. /package/{dist/bridge → bridge}/native-plugins.js +0 -0
  544. /package/{dist/bridge → bridge}/plugin-bridge.d.ts +0 -0
  545. /package/{dist/bridge → bridge}/plugin-bridge.d.ts.map +0 -0
  546. /package/{dist/bridge → bridge}/plugin-bridge.js +0 -0
  547. /package/{dist/bridge → bridge}/storage-bridge.d.ts +0 -0
  548. /package/{dist/bridge → bridge}/storage-bridge.d.ts.map +0 -0
  549. /package/{dist/bridge → bridge}/storage-bridge.js +0 -0
  550. /package/{dist/chat → chat}/index.d.ts +0 -0
  551. /package/{dist/chat → chat}/index.d.ts.map +0 -0
  552. /package/{dist/chat → chat}/index.js +0 -0
  553. /package/{dist/coding → coding}/index.d.ts +0 -0
  554. /package/{dist/coding → coding}/index.d.ts.map +0 -0
  555. /package/{dist/coding → coding}/index.js +0 -0
  556. /package/{dist/components → components}/AdvancedPageView.d.ts +0 -0
  557. /package/{dist/components → components}/AgentActivityBox.d.ts +0 -0
  558. /package/{dist/components → components}/AgentActivityBox.d.ts.map +0 -0
  559. /package/{dist/components → components}/AgentActivityBox.js +0 -0
  560. /package/{dist/components → components}/ApiKeyConfig.d.ts +0 -0
  561. /package/{dist/components → components}/ApiKeyConfig.d.ts.map +0 -0
  562. /package/{dist/components → components}/ApiKeyConfig.js +0 -0
  563. /package/{dist/components → components}/AppsPageView.d.ts +0 -0
  564. /package/{dist/components → components}/AppsPageView.d.ts.map +0 -0
  565. /package/{dist/components → components}/AppsPageView.js +0 -0
  566. /package/{dist/components → components}/AppsView.d.ts +0 -0
  567. /package/{dist/components → components}/AppsView.d.ts.map +0 -0
  568. /package/{dist/components → components}/AppsView.js +0 -0
  569. /package/{dist/components → components}/AvatarLoader.d.ts +0 -0
  570. /package/{dist/components → components}/AvatarLoader.d.ts.map +0 -0
  571. /package/{dist/components → components}/AvatarLoader.js +0 -0
  572. /package/{dist/components → components}/AvatarSelector.d.ts +0 -0
  573. /package/{dist/components → components}/AvatarSelector.d.ts.map +0 -0
  574. /package/{dist/components → components}/AvatarSelector.js +0 -0
  575. /package/{dist/components → components}/BscTradePanel.d.ts +0 -0
  576. /package/{dist/components → components}/BscTradePanel.d.ts.map +0 -0
  577. /package/{dist/components → components}/BscTradePanel.js +0 -0
  578. /package/{dist/components → components}/BugReportModal.d.ts +0 -0
  579. /package/{dist/components → components}/BugReportModal.d.ts.map +0 -0
  580. /package/{dist/components → components}/BugReportModal.js +0 -0
  581. /package/{dist/components → components}/CharacterRoster.d.ts +0 -0
  582. /package/{dist/components → components}/CharacterRoster.d.ts.map +0 -0
  583. /package/{dist/components → components}/CharacterRoster.js +0 -0
  584. /package/{dist/components → components}/CharacterView.d.ts +0 -0
  585. /package/{dist/components → components}/ChatAvatar.d.ts +0 -0
  586. /package/{dist/components → components}/ChatAvatar.d.ts.map +0 -0
  587. /package/{dist/components → components}/ChatAvatar.js +0 -0
  588. /package/{dist/components → components}/ChatComposer.d.ts +0 -0
  589. /package/{dist/components → components}/ChatMessage.d.ts +0 -0
  590. /package/{dist/components → components}/ChatMessage.d.ts.map +0 -0
  591. /package/{dist/components → components}/ChatMessage.js +0 -0
  592. /package/{dist/components → components}/ChatModalView.d.ts +0 -0
  593. /package/{dist/components → components}/ChatModalView.d.ts.map +0 -0
  594. /package/{dist/components → components}/ChatModalView.js +0 -0
  595. /package/{dist/components → components}/ChatView.d.ts +0 -0
  596. /package/{dist/components → components}/CloudOnboarding.d.ts +0 -0
  597. /package/{dist/components → components}/CloudOnboarding.d.ts.map +0 -0
  598. /package/{dist/components → components}/CloudOnboarding.js +0 -0
  599. /package/{dist/components → components}/CloudSourceControls.d.ts +0 -0
  600. /package/{dist/components → components}/CloudSourceControls.d.ts.map +0 -0
  601. /package/{dist/components → components}/CloudSourceControls.js +0 -0
  602. /package/{dist/components → components}/CodingAgentSettingsSection.d.ts +0 -0
  603. /package/{dist/components → components}/CodingAgentSettingsSection.d.ts.map +0 -0
  604. /package/{dist/components → components}/CodingAgentSettingsSection.js +0 -0
  605. /package/{dist/components → components}/CommandPalette.d.ts +0 -0
  606. /package/{dist/components → components}/CommandPalette.d.ts.map +0 -0
  607. /package/{dist/components → components}/CommandPalette.js +0 -0
  608. /package/{dist/components → components}/CompanionSceneHost.d.ts +0 -0
  609. /package/{dist/components → components}/CompanionSceneHost.d.ts.map +0 -0
  610. /package/{dist/components → components}/CompanionSceneHost.js +0 -0
  611. /package/{dist/components → components}/CompanionShell.d.ts +0 -0
  612. /package/{dist/components → components}/CompanionShell.d.ts.map +0 -0
  613. /package/{dist/components → components}/CompanionShell.js +0 -0
  614. /package/{dist/components → components}/CompanionView.d.ts +0 -0
  615. /package/{dist/components → components}/CompanionView.d.ts.map +0 -0
  616. /package/{dist/components → components}/ConfigPageView.d.ts +0 -0
  617. /package/{dist/components → components}/ConfigPageView.d.ts.map +0 -0
  618. /package/{dist/components → components}/ConfigSaveFooter.d.ts +0 -0
  619. /package/{dist/components → components}/ConfigSaveFooter.d.ts.map +0 -0
  620. /package/{dist/components → components}/ConfigSaveFooter.js +0 -0
  621. /package/{dist/components → components}/ConfirmModal.d.ts +0 -0
  622. /package/{dist/components → components}/ConfirmModal.d.ts.map +0 -0
  623. /package/{dist/components → components}/ConfirmModal.js +0 -0
  624. /package/{dist/components → components}/ConnectionFailedBanner.d.ts +0 -0
  625. /package/{dist/components → components}/ConnectionFailedBanner.d.ts.map +0 -0
  626. /package/{dist/components → components}/ConnectionFailedBanner.js +0 -0
  627. /package/{dist/components → components}/ConnectorsPageView.d.ts +0 -0
  628. /package/{dist/components → components}/ConnectorsPageView.d.ts.map +0 -0
  629. /package/{dist/components → components}/ConnectorsPageView.js +0 -0
  630. /package/{dist/components → components}/ConversationsSidebar.d.ts +0 -0
  631. /package/{dist/components → components}/ConversationsSidebar.d.ts.map +0 -0
  632. /package/{dist/components → components}/ConversationsSidebar.js +0 -0
  633. /package/{dist/components → components}/CustomActionEditor.d.ts +0 -0
  634. /package/{dist/components → components}/CustomActionEditor.d.ts.map +0 -0
  635. /package/{dist/components → components}/CustomActionEditor.js +0 -0
  636. /package/{dist/components → components}/CustomActionsPanel.d.ts +0 -0
  637. /package/{dist/components → components}/CustomActionsPanel.d.ts.map +0 -0
  638. /package/{dist/components → components}/CustomActionsPanel.js +0 -0
  639. /package/{dist/components → components}/CustomActionsView.d.ts +0 -0
  640. /package/{dist/components → components}/CustomActionsView.d.ts.map +0 -0
  641. /package/{dist/components → components}/CustomActionsView.js +0 -0
  642. /package/{dist/components → components}/DatabasePageView.d.ts +0 -0
  643. /package/{dist/components → components}/DatabasePageView.d.ts.map +0 -0
  644. /package/{dist/components → components}/DatabasePageView.js +0 -0
  645. /package/{dist/components → components}/DatabaseView.d.ts +0 -0
  646. /package/{dist/components → components}/DatabaseView.d.ts.map +0 -0
  647. /package/{dist/components → components}/DatabaseView.js +0 -0
  648. /package/{dist/components → components}/ElizaCloudDashboard.d.ts +0 -0
  649. /package/{dist/components → components}/ElizaCloudDashboard.d.ts.map +0 -0
  650. /package/{dist/components → components}/EmotePicker.d.ts +0 -0
  651. /package/{dist/components → components}/EmotePicker.d.ts.map +0 -0
  652. /package/{dist/components → components}/EmotePicker.js +0 -0
  653. /package/{dist/components → components}/ErrorBoundary.d.ts +0 -0
  654. /package/{dist/components → components}/ErrorBoundary.d.ts.map +0 -0
  655. /package/{dist/components → components}/ErrorBoundary.js +0 -0
  656. /package/{dist/components → components}/FineTuningView.d.ts +0 -0
  657. /package/{dist/components → components}/FineTuningView.d.ts.map +0 -0
  658. /package/{dist/components → components}/FineTuningView.js +0 -0
  659. /package/{dist/components → components}/FlaminaGuide.d.ts +0 -0
  660. /package/{dist/components → components}/FlaminaGuide.d.ts.map +0 -0
  661. /package/{dist/components → components}/GameView.d.ts +0 -0
  662. /package/{dist/components → components}/GameView.d.ts.map +0 -0
  663. /package/{dist/components → components}/GameView.js +0 -0
  664. /package/{dist/components → components}/GameViewOverlay.d.ts +0 -0
  665. /package/{dist/components → components}/GameViewOverlay.d.ts.map +0 -0
  666. /package/{dist/components → components}/GameViewOverlay.js +0 -0
  667. /package/{dist/components → components}/GlobalEmoteOverlay.d.ts +0 -0
  668. /package/{dist/components → components}/GlobalEmoteOverlay.d.ts.map +0 -0
  669. /package/{dist/components → components}/GlobalEmoteOverlay.js +0 -0
  670. /package/{dist/components → components}/Header.d.ts +0 -0
  671. /package/{dist/components → components}/Header.d.ts.map +0 -0
  672. /package/{dist/components → components}/Header.js +0 -0
  673. /package/{dist/components → components}/HeartbeatsView.d.ts +0 -0
  674. /package/{dist/components → components}/HeartbeatsView.d.ts.map +0 -0
  675. /package/{dist/components → components}/HeartbeatsView.js +0 -0
  676. /package/{dist/components → components}/InventoryView.d.ts +0 -0
  677. /package/{dist/components → components}/InventoryView.d.ts.map +0 -0
  678. /package/{dist/components → components}/InventoryView.js +0 -0
  679. /package/{dist/components → components}/KnowledgeView.d.ts +0 -0
  680. /package/{dist/components → components}/KnowledgeView.d.ts.map +0 -0
  681. /package/{dist/components → components}/KnowledgeView.js +0 -0
  682. /package/{dist/components → components}/LanguageDropdown.d.ts +0 -0
  683. /package/{dist/components → components}/LanguageDropdown.d.ts.map +0 -0
  684. /package/{dist/components → components}/LanguageDropdown.js +0 -0
  685. /package/{dist/components → components}/LifoMonitorPanel.d.ts +0 -0
  686. /package/{dist/components → components}/LifoMonitorPanel.d.ts.map +0 -0
  687. /package/{dist/components → components}/LifoMonitorPanel.js +0 -0
  688. /package/{dist/components → components}/LifoSandboxView.d.ts +0 -0
  689. /package/{dist/components → components}/LifoSandboxView.d.ts.map +0 -0
  690. /package/{dist/components → components}/LifoSandboxView.js +0 -0
  691. /package/{dist/components → components}/LoadingScreen.d.ts +0 -0
  692. /package/{dist/components → components}/LoadingScreen.d.ts.map +0 -0
  693. /package/{dist/components → components}/LoadingScreen.js +0 -0
  694. /package/{dist/components → components}/LogsPageView.d.ts +0 -0
  695. /package/{dist/components → components}/LogsPageView.d.ts.map +0 -0
  696. /package/{dist/components → components}/LogsPageView.js +0 -0
  697. /package/{dist/components → components}/LogsView.d.ts +0 -0
  698. /package/{dist/components → components}/LogsView.d.ts.map +0 -0
  699. /package/{dist/components → components}/LogsView.js +0 -0
  700. /package/{dist/components → components}/MediaGalleryView.d.ts +0 -0
  701. /package/{dist/components → components}/MediaGalleryView.d.ts.map +0 -0
  702. /package/{dist/components → components}/MediaGalleryView.js +0 -0
  703. /package/{dist/components → components}/MediaSettingsSection.d.ts +0 -0
  704. /package/{dist/components → components}/MediaSettingsSection.d.ts.map +0 -0
  705. /package/{dist/components → components}/MediaSettingsSection.js +0 -0
  706. /package/{dist/components → components}/MessageContent.d.ts +0 -0
  707. /package/{dist/components → components}/MessageContent.d.ts.map +0 -0
  708. /package/{dist/components → components}/MessageContent.js +0 -0
  709. /package/{dist/components → components}/OnboardingWizard.d.ts +0 -0
  710. /package/{dist/components → components}/PairingView.d.ts +0 -0
  711. /package/{dist/components → components}/PairingView.d.ts.map +0 -0
  712. /package/{dist/components → components}/PairingView.js +0 -0
  713. /package/{dist/components → components}/PermissionsSection.d.ts +0 -0
  714. /package/{dist/components → components}/PermissionsSection.d.ts.map +0 -0
  715. /package/{dist/components → components}/PermissionsSection.js +0 -0
  716. /package/{dist/components → components}/PluginsPageView.d.ts +0 -0
  717. /package/{dist/components → components}/PluginsPageView.d.ts.map +0 -0
  718. /package/{dist/components → components}/PluginsPageView.js +0 -0
  719. /package/{dist/components → components}/PluginsView.d.ts +0 -0
  720. /package/{dist/components → components}/ProviderSwitcher.d.ts +0 -0
  721. /package/{dist/components → components}/ProviderSwitcher.d.ts.map +0 -0
  722. /package/{dist/components → components}/ProviderSwitcher.js +0 -0
  723. /package/{dist/components → components}/RestartBanner.d.ts +0 -0
  724. /package/{dist/components → components}/RestartBanner.d.ts.map +0 -0
  725. /package/{dist/components → components}/RestartBanner.js +0 -0
  726. /package/{dist/components → components}/RuntimeView.d.ts +0 -0
  727. /package/{dist/components → components}/RuntimeView.d.ts.map +0 -0
  728. /package/{dist/components → components}/RuntimeView.js +0 -0
  729. /package/{dist/components → components}/SaveCommandModal.d.ts +0 -0
  730. /package/{dist/components → components}/SaveCommandModal.d.ts.map +0 -0
  731. /package/{dist/components → components}/SaveCommandModal.js +0 -0
  732. /package/{dist/components → components}/SecretsView.d.ts +0 -0
  733. /package/{dist/components → components}/SecretsView.d.ts.map +0 -0
  734. /package/{dist/components → components}/SecretsView.js +0 -0
  735. /package/{dist/components → components}/SettingsView.d.ts +0 -0
  736. /package/{dist/components → components}/SettingsView.d.ts.map +0 -0
  737. /package/{dist/components → components}/SettingsView.js +0 -0
  738. /package/{dist/components → components}/ShellOverlays.d.ts +0 -0
  739. /package/{dist/components → components}/ShellOverlays.d.ts.map +0 -0
  740. /package/{dist/components → components}/ShellOverlays.js +0 -0
  741. /package/{dist/components → components}/ShortcutsOverlay.d.ts +0 -0
  742. /package/{dist/components → components}/ShortcutsOverlay.d.ts.map +0 -0
  743. /package/{dist/components → components}/ShortcutsOverlay.js +0 -0
  744. /package/{dist/components → components}/SkillsView.d.ts +0 -0
  745. /package/{dist/components → components}/SkillsView.d.ts.map +0 -0
  746. /package/{dist/components → components}/SkillsView.js +0 -0
  747. /package/{dist/components → components}/StartupFailureView.d.ts +0 -0
  748. /package/{dist/components → components}/StartupFailureView.d.ts.map +0 -0
  749. /package/{dist/components → components}/StartupFailureView.js +0 -0
  750. /package/{dist/components → components}/StreamView.d.ts +0 -0
  751. /package/{dist/components → components}/StreamView.d.ts.map +0 -0
  752. /package/{dist/components → components}/StreamView.js +0 -0
  753. /package/{dist/components → components}/StripeEmbeddedCheckout.d.ts +0 -0
  754. /package/{dist/components → components}/StripeEmbeddedCheckout.d.ts.map +0 -0
  755. /package/{dist/components → components}/StripeEmbeddedCheckout.js +0 -0
  756. /package/{dist/components → components}/SubscriptionStatus.d.ts +0 -0
  757. /package/{dist/components → components}/SubscriptionStatus.d.ts.map +0 -0
  758. /package/{dist/components → components}/SubscriptionStatus.js +0 -0
  759. /package/{dist/components → components}/SystemWarningBanner.d.ts +0 -0
  760. /package/{dist/components → components}/SystemWarningBanner.d.ts.map +0 -0
  761. /package/{dist/components → components}/SystemWarningBanner.js +0 -0
  762. /package/{dist/components → components}/ThemeToggle.d.ts +0 -0
  763. /package/{dist/components → components}/ThemeToggle.d.ts.map +0 -0
  764. /package/{dist/components → components}/ThemeToggle.js +0 -0
  765. /package/{dist/components → components}/TrajectoriesView.d.ts +0 -0
  766. /package/{dist/components → components}/TrajectoriesView.d.ts.map +0 -0
  767. /package/{dist/components → components}/TrajectoriesView.js +0 -0
  768. /package/{dist/components → components}/TrajectoryDetailView.d.ts +0 -0
  769. /package/{dist/components → components}/TrajectoryDetailView.d.ts.map +0 -0
  770. /package/{dist/components → components}/TrajectoryDetailView.js +0 -0
  771. /package/{dist/components → components}/TriggersView.d.ts +0 -0
  772. /package/{dist/components → components}/TriggersView.d.ts.map +0 -0
  773. /package/{dist/components → components}/TriggersView.js +0 -0
  774. /package/{dist/components → components}/VectorBrowserView.d.ts +0 -0
  775. /package/{dist/components → components}/VectorBrowserView.d.ts.map +0 -0
  776. /package/{dist/components → components}/VectorBrowserView.js +0 -0
  777. /package/{dist/components → components}/VoiceConfigView.d.ts +0 -0
  778. /package/{dist/components → components}/VoiceConfigView.d.ts.map +0 -0
  779. /package/{dist/components → components}/VoiceConfigView.js +0 -0
  780. /package/{dist/components → components}/VrmStage.d.ts +0 -0
  781. /package/{dist/components → components}/VrmStage.d.ts.map +0 -0
  782. /package/{dist/components → components}/VrmStage.js +0 -0
  783. /package/{dist/components → components}/WhatsAppQrOverlay.d.ts +0 -0
  784. /package/{dist/components → components}/WhatsAppQrOverlay.d.ts.map +0 -0
  785. /package/{dist/components → components}/WhatsAppQrOverlay.js +0 -0
  786. /package/{dist/components → components}/apps/AppDetailPane.d.ts +0 -0
  787. /package/{dist/components → components}/apps/AppDetailPane.d.ts.map +0 -0
  788. /package/{dist/components → components}/apps/AppDetailPane.js +0 -0
  789. /package/{dist/components → components}/apps/AppsCatalogGrid.d.ts +0 -0
  790. /package/{dist/components → components}/apps/AppsCatalogGrid.d.ts.map +0 -0
  791. /package/{dist/components → components}/apps/AppsCatalogGrid.js +0 -0
  792. /package/{dist/components → components}/apps/extensions/registry.d.ts +0 -0
  793. /package/{dist/components → components}/apps/extensions/registry.d.ts.map +0 -0
  794. /package/{dist/components → components}/apps/extensions/registry.js +0 -0
  795. /package/{dist/components → components}/apps/extensions/types.d.ts +0 -0
  796. /package/{dist/components → components}/apps/extensions/types.d.ts.map +0 -0
  797. /package/{dist/components → components}/apps/extensions/types.js +0 -0
  798. /package/{dist/components → components}/apps/helpers.d.ts +0 -0
  799. /package/{dist/components → components}/apps/helpers.d.ts.map +0 -0
  800. /package/{dist/components → components}/apps/helpers.js +0 -0
  801. /package/{dist/components → components}/avatar/VrmAnimationLoader.d.ts +0 -0
  802. /package/{dist/components → components}/avatar/VrmAnimationLoader.d.ts.map +0 -0
  803. /package/{dist/components → components}/avatar/VrmAnimationLoader.js +0 -0
  804. /package/{dist/components → components}/avatar/VrmBlinkController.d.ts +0 -0
  805. /package/{dist/components → components}/avatar/VrmBlinkController.d.ts.map +0 -0
  806. /package/{dist/components → components}/avatar/VrmBlinkController.js +0 -0
  807. /package/{dist/components → components}/avatar/VrmCameraManager.d.ts +0 -0
  808. /package/{dist/components → components}/avatar/VrmCameraManager.d.ts.map +0 -0
  809. /package/{dist/components → components}/avatar/VrmCameraManager.js +0 -0
  810. /package/{dist/components → components}/avatar/VrmFootShadow.d.ts +0 -0
  811. /package/{dist/components → components}/avatar/VrmFootShadow.d.ts.map +0 -0
  812. /package/{dist/components → components}/avatar/VrmFootShadow.js +0 -0
  813. /package/{dist/components → components}/avatar/mixamoVRMRigMap.d.ts +0 -0
  814. /package/{dist/components → components}/avatar/mixamoVRMRigMap.d.ts.map +0 -0
  815. /package/{dist/components → components}/avatar/mixamoVRMRigMap.js +0 -0
  816. /package/{dist/components → components}/avatar/retargetMixamoFbxToVrm.d.ts +0 -0
  817. /package/{dist/components → components}/avatar/retargetMixamoFbxToVrm.d.ts.map +0 -0
  818. /package/{dist/components → components}/avatar/retargetMixamoFbxToVrm.js +0 -0
  819. /package/{dist/components → components}/avatar/retargetMixamoGltfToVrm.d.ts +0 -0
  820. /package/{dist/components → components}/avatar/retargetMixamoGltfToVrm.d.ts.map +0 -0
  821. /package/{dist/components → components}/avatar/retargetMixamoGltfToVrm.js +0 -0
  822. /package/{dist/components → components}/chainConfig.d.ts +0 -0
  823. /package/{dist/components → components}/chainConfig.d.ts.map +0 -0
  824. /package/{dist/components → components}/chainConfig.js +0 -0
  825. /package/{dist/components → components}/companion/CompanionHeader.d.ts +0 -0
  826. /package/{dist/components → components}/companion/CompanionHeader.d.ts.map +0 -0
  827. /package/{dist/components → components}/companion/CompanionHeader.js +0 -0
  828. /package/{dist/components → components}/companion/CompanionSceneHost.d.ts +0 -0
  829. /package/{dist/components → components}/companion/CompanionSceneHost.d.ts.map +0 -0
  830. /package/{dist/components → components}/companion/CompanionSceneHost.js +0 -0
  831. /package/{dist/components → components}/companion/VrmStage.d.ts +0 -0
  832. /package/{dist/components → components}/companion/VrmStage.d.ts.map +0 -0
  833. /package/{dist/components → components}/companion/VrmStage.js +0 -0
  834. /package/{dist/components → components}/companion/index.d.ts +0 -0
  835. /package/{dist/components → components}/companion/index.d.ts.map +0 -0
  836. /package/{dist/components → components}/companion/index.js +0 -0
  837. /package/{dist/components → components}/companion/walletUtils.d.ts +0 -0
  838. /package/{dist/components → components}/companion/walletUtils.d.ts.map +0 -0
  839. /package/{dist/components → components}/companion/walletUtils.js +0 -0
  840. /package/{dist/components → components}/companion-shell-styles.d.ts +0 -0
  841. /package/{dist/components → components}/companion-shell-styles.d.ts.map +0 -0
  842. /package/{dist/components → components}/companion-shell-styles.js +0 -0
  843. /package/{dist/components → components}/confirm-delete-control.d.ts +0 -0
  844. /package/{dist/components → components}/confirm-delete-control.d.ts.map +0 -0
  845. /package/{dist/components → components}/confirm-delete-control.js +0 -0
  846. /package/{dist/components → components}/conversations/ConversationListItem.d.ts +0 -0
  847. /package/{dist/components → components}/conversations/ConversationListItem.d.ts.map +0 -0
  848. /package/{dist/components → components}/conversations/ConversationListItem.js +0 -0
  849. /package/{dist/components → components}/conversations/conversation-utils.d.ts +0 -0
  850. /package/{dist/components → components}/conversations/conversation-utils.d.ts.map +0 -0
  851. /package/{dist/components → components}/conversations/conversation-utils.js +0 -0
  852. /package/{dist/components → components}/format.d.ts +0 -0
  853. /package/{dist/components → components}/format.d.ts.map +0 -0
  854. /package/{dist/components → components}/format.js +0 -0
  855. /package/{dist/components → components}/inventory/CopyableAddress.d.ts +0 -0
  856. /package/{dist/components → components}/inventory/CopyableAddress.d.ts.map +0 -0
  857. /package/{dist/components → components}/inventory/CopyableAddress.js +0 -0
  858. /package/{dist/components → components}/inventory/InventoryToolbar.d.ts +0 -0
  859. /package/{dist/components → components}/inventory/InventoryToolbar.d.ts.map +0 -0
  860. /package/{dist/components → components}/inventory/InventoryToolbar.js +0 -0
  861. /package/{dist/components → components}/inventory/NftGrid.d.ts +0 -0
  862. /package/{dist/components → components}/inventory/NftGrid.d.ts.map +0 -0
  863. /package/{dist/components → components}/inventory/NftGrid.js +0 -0
  864. /package/{dist/components → components}/inventory/TokenLogo.d.ts +0 -0
  865. /package/{dist/components → components}/inventory/TokenLogo.d.ts.map +0 -0
  866. /package/{dist/components → components}/inventory/TokenLogo.js +0 -0
  867. /package/{dist/components → components}/inventory/TokensTable.d.ts +0 -0
  868. /package/{dist/components → components}/inventory/TokensTable.d.ts.map +0 -0
  869. /package/{dist/components → components}/inventory/TokensTable.js +0 -0
  870. /package/{dist/components → components}/inventory/constants.d.ts +0 -0
  871. /package/{dist/components → components}/inventory/constants.d.ts.map +0 -0
  872. /package/{dist/components → components}/inventory/constants.js +0 -0
  873. /package/{dist/components → components}/inventory/index.d.ts +0 -0
  874. /package/{dist/components → components}/inventory/index.d.ts.map +0 -0
  875. /package/{dist/components → components}/inventory/index.js +0 -0
  876. /package/{dist/components → components}/inventory/media-url.d.ts +0 -0
  877. /package/{dist/components → components}/inventory/media-url.d.ts.map +0 -0
  878. /package/{dist/components → components}/inventory/media-url.js +0 -0
  879. /package/{dist/components → components}/inventory/useInventoryData.d.ts +0 -0
  880. /package/{dist/components → components}/inventory/useInventoryData.d.ts.map +0 -0
  881. /package/{dist/components → components}/inventory/useInventoryData.js +0 -0
  882. /package/{dist/components → components}/knowledge-upload-image.d.ts +0 -0
  883. /package/{dist/components → components}/knowledge-upload-image.d.ts.map +0 -0
  884. /package/{dist/components → components}/knowledge-upload-image.js +0 -0
  885. /package/{dist/components → components}/labels.d.ts +0 -0
  886. /package/{dist/components → components}/labels.d.ts.map +0 -0
  887. /package/{dist/components → components}/labels.js +0 -0
  888. /package/{dist/components → components}/onboarding/ActivateStep.d.ts +0 -0
  889. /package/{dist/components → components}/onboarding/ActivateStep.d.ts.map +0 -0
  890. /package/{dist/components → components}/onboarding/ActivateStep.js +0 -0
  891. /package/{dist/components → components}/onboarding/ConnectionStep.d.ts +0 -0
  892. /package/{dist/components → components}/onboarding/IdentityStep.d.ts +0 -0
  893. /package/{dist/components → components}/onboarding/IdentityStep.d.ts.map +0 -0
  894. /package/{dist/components → components}/onboarding/IdentityStep.js +0 -0
  895. /package/{dist/components → components}/onboarding/OnboardingPanel.d.ts +0 -0
  896. /package/{dist/components → components}/onboarding/OnboardingPanel.d.ts.map +0 -0
  897. /package/{dist/components → components}/onboarding/OnboardingPanel.js +0 -0
  898. /package/{dist/components → components}/onboarding/OnboardingStepNav.d.ts +0 -0
  899. /package/{dist/components → components}/onboarding/OnboardingStepNav.d.ts.map +0 -0
  900. /package/{dist/components → components}/onboarding/OnboardingStepNav.js +0 -0
  901. /package/{dist/components → components}/onboarding/PermissionsStep.d.ts +0 -0
  902. /package/{dist/components → components}/onboarding/PermissionsStep.d.ts.map +0 -0
  903. /package/{dist/components → components}/onboarding/PermissionsStep.js +0 -0
  904. /package/{dist/components → components}/onboarding/RpcStep.d.ts +0 -0
  905. /package/{dist/components → components}/onboarding/RpcStep.d.ts.map +0 -0
  906. /package/{dist/components → components}/onboarding/RpcStep.js +0 -0
  907. /package/{dist/components → components}/permissions/PermissionIcon.d.ts +0 -0
  908. /package/{dist/components → components}/permissions/PermissionIcon.d.ts.map +0 -0
  909. /package/{dist/components → components}/permissions/PermissionIcon.js +0 -0
  910. /package/{dist/components → components}/permissions/StreamingPermissions.d.ts +0 -0
  911. /package/{dist/components → components}/plugins/showcase-data.d.ts +0 -0
  912. /package/{dist/components → components}/plugins/showcase-data.d.ts.map +0 -0
  913. /package/{dist/components → components}/plugins/showcase-data.js +0 -0
  914. /package/{dist/components → components}/shared/ShellHeaderControls.d.ts +0 -0
  915. /package/{dist/components → components}/shared/ShellHeaderControls.d.ts.map +0 -0
  916. /package/{dist/components → components}/shared/ShellHeaderControls.js +0 -0
  917. /package/{dist/components → components}/shared-companion-scene-context.d.ts +0 -0
  918. /package/{dist/components → components}/shared-companion-scene-context.d.ts.map +0 -0
  919. /package/{dist/components → components}/shared-companion-scene-context.js +0 -0
  920. /package/{dist/components → components}/skeletons.d.ts +0 -0
  921. /package/{dist/components → components}/skeletons.d.ts.map +0 -0
  922. /package/{dist/components → components}/skeletons.js +0 -0
  923. /package/{dist/components → components}/stream/ActivityFeed.d.ts +0 -0
  924. /package/{dist/components → components}/stream/ActivityFeed.d.ts.map +0 -0
  925. /package/{dist/components → components}/stream/ActivityFeed.js +0 -0
  926. /package/{dist/components → components}/stream/AvatarPip.d.ts +0 -0
  927. /package/{dist/components → components}/stream/AvatarPip.d.ts.map +0 -0
  928. /package/{dist/components → components}/stream/AvatarPip.js +0 -0
  929. /package/{dist/components → components}/stream/ChatContent.d.ts +0 -0
  930. /package/{dist/components → components}/stream/ChatContent.d.ts.map +0 -0
  931. /package/{dist/components → components}/stream/ChatContent.js +0 -0
  932. /package/{dist/components → components}/stream/ChatTicker.d.ts +0 -0
  933. /package/{dist/components → components}/stream/ChatTicker.d.ts.map +0 -0
  934. /package/{dist/components → components}/stream/ChatTicker.js +0 -0
  935. /package/{dist/components → components}/stream/IdleContent.d.ts +0 -0
  936. /package/{dist/components → components}/stream/IdleContent.d.ts.map +0 -0
  937. /package/{dist/components → components}/stream/IdleContent.js +0 -0
  938. /package/{dist/components → components}/stream/StatusBar.d.ts +0 -0
  939. /package/{dist/components → components}/stream/StatusBar.d.ts.map +0 -0
  940. /package/{dist/components → components}/stream/StatusBar.js +0 -0
  941. /package/{dist/components → components}/stream/StreamSettings.d.ts +0 -0
  942. /package/{dist/components → components}/stream/StreamSettings.d.ts.map +0 -0
  943. /package/{dist/components → components}/stream/StreamSettings.js +0 -0
  944. /package/{dist/components → components}/stream/StreamTerminal.d.ts +0 -0
  945. /package/{dist/components → components}/stream/StreamTerminal.d.ts.map +0 -0
  946. /package/{dist/components → components}/stream/StreamTerminal.js +0 -0
  947. /package/{dist/components → components}/stream/StreamVoiceConfig.d.ts +0 -0
  948. /package/{dist/components → components}/stream/StreamVoiceConfig.d.ts.map +0 -0
  949. /package/{dist/components → components}/stream/StreamVoiceConfig.js +0 -0
  950. /package/{dist/components → components}/stream/helpers.d.ts +0 -0
  951. /package/{dist/components → components}/stream/helpers.d.ts.map +0 -0
  952. /package/{dist/components → components}/stream/helpers.js +0 -0
  953. /package/{dist/components → components}/stream/overlays/OverlayLayer.d.ts +0 -0
  954. /package/{dist/components → components}/stream/overlays/OverlayLayer.d.ts.map +0 -0
  955. /package/{dist/components → components}/stream/overlays/OverlayLayer.js +0 -0
  956. /package/{dist/components → components}/stream/overlays/built-in/ActionTickerWidget.d.ts +0 -0
  957. /package/{dist/components → components}/stream/overlays/built-in/ActionTickerWidget.d.ts.map +0 -0
  958. /package/{dist/components → components}/stream/overlays/built-in/ActionTickerWidget.js +0 -0
  959. /package/{dist/components → components}/stream/overlays/built-in/AlertPopupWidget.d.ts +0 -0
  960. /package/{dist/components → components}/stream/overlays/built-in/AlertPopupWidget.d.ts.map +0 -0
  961. /package/{dist/components → components}/stream/overlays/built-in/AlertPopupWidget.js +0 -0
  962. /package/{dist/components → components}/stream/overlays/built-in/BrandingWidget.d.ts +0 -0
  963. /package/{dist/components → components}/stream/overlays/built-in/BrandingWidget.d.ts.map +0 -0
  964. /package/{dist/components → components}/stream/overlays/built-in/BrandingWidget.js +0 -0
  965. /package/{dist/components → components}/stream/overlays/built-in/CustomHtmlWidget.d.ts +0 -0
  966. /package/{dist/components → components}/stream/overlays/built-in/CustomHtmlWidget.d.ts.map +0 -0
  967. /package/{dist/components → components}/stream/overlays/built-in/CustomHtmlWidget.js +0 -0
  968. /package/{dist/components → components}/stream/overlays/built-in/PeonGlassWidget.d.ts +0 -0
  969. /package/{dist/components → components}/stream/overlays/built-in/PeonGlassWidget.d.ts.map +0 -0
  970. /package/{dist/components → components}/stream/overlays/built-in/PeonGlassWidget.js +0 -0
  971. /package/{dist/components → components}/stream/overlays/built-in/PeonHudWidget.d.ts +0 -0
  972. /package/{dist/components → components}/stream/overlays/built-in/PeonHudWidget.d.ts.map +0 -0
  973. /package/{dist/components → components}/stream/overlays/built-in/PeonHudWidget.js +0 -0
  974. /package/{dist/components → components}/stream/overlays/built-in/PeonSakuraWidget.d.ts +0 -0
  975. /package/{dist/components → components}/stream/overlays/built-in/PeonSakuraWidget.d.ts.map +0 -0
  976. /package/{dist/components → components}/stream/overlays/built-in/PeonSakuraWidget.js +0 -0
  977. /package/{dist/components → components}/stream/overlays/built-in/ThoughtBubbleWidget.d.ts +0 -0
  978. /package/{dist/components → components}/stream/overlays/built-in/ThoughtBubbleWidget.d.ts.map +0 -0
  979. /package/{dist/components → components}/stream/overlays/built-in/ThoughtBubbleWidget.js +0 -0
  980. /package/{dist/components → components}/stream/overlays/built-in/ViewerCountWidget.d.ts +0 -0
  981. /package/{dist/components → components}/stream/overlays/built-in/ViewerCountWidget.d.ts.map +0 -0
  982. /package/{dist/components → components}/stream/overlays/built-in/ViewerCountWidget.js +0 -0
  983. /package/{dist/components → components}/stream/overlays/built-in/index.d.ts +0 -0
  984. /package/{dist/components → components}/stream/overlays/built-in/index.d.ts.map +0 -0
  985. /package/{dist/components → components}/stream/overlays/built-in/index.js +0 -0
  986. /package/{dist/components → components}/stream/overlays/registry.d.ts +0 -0
  987. /package/{dist/components → components}/stream/overlays/registry.d.ts.map +0 -0
  988. /package/{dist/components → components}/stream/overlays/registry.js +0 -0
  989. /package/{dist/components → components}/stream/overlays/types.d.ts +0 -0
  990. /package/{dist/components → components}/stream/overlays/types.d.ts.map +0 -0
  991. /package/{dist/components → components}/stream/overlays/types.js +0 -0
  992. /package/{dist/components → components}/stream/overlays/useOverlayLayout.d.ts +0 -0
  993. /package/{dist/components → components}/stream/overlays/useOverlayLayout.d.ts.map +0 -0
  994. /package/{dist/components → components}/stream/overlays/useOverlayLayout.js +0 -0
  995. /package/{dist/components → components}/trajectory-format.d.ts +0 -0
  996. /package/{dist/components → components}/trajectory-format.d.ts.map +0 -0
  997. /package/{dist/components → components}/trajectory-format.js +0 -0
  998. /package/{dist/components → components}/ui-badges.d.ts +0 -0
  999. /package/{dist/components → components}/ui-badges.d.ts.map +0 -0
  1000. /package/{dist/components → components}/ui-badges.js +0 -0
  1001. /package/{dist/components → components}/ui-switch.d.ts +0 -0
  1002. /package/{dist/components → components}/ui-switch.d.ts.map +0 -0
  1003. /package/{dist/components → components}/vector-browser-three.d.ts +0 -0
  1004. /package/{dist/components → components}/vector-browser-three.d.ts.map +0 -0
  1005. /package/{dist/components → components}/vector-browser-three.js +0 -0
  1006. /package/{dist/config → config}/branding.d.ts +0 -0
  1007. /package/{dist/config → config}/branding.d.ts.map +0 -0
  1008. /package/{dist/config → config}/branding.js +0 -0
  1009. /package/{dist/config → config}/config-catalog.d.ts +0 -0
  1010. /package/{dist/config → config}/config-catalog.d.ts.map +0 -0
  1011. /package/{dist/config → config}/config-catalog.js +0 -0
  1012. /package/{dist/config → config}/config-field.d.ts +0 -0
  1013. /package/{dist/config → config}/config-field.d.ts.map +0 -0
  1014. /package/{dist/config → config}/config-field.js +0 -0
  1015. /package/{dist/config → config}/config-renderer.d.ts +0 -0
  1016. /package/{dist/config → config}/config-renderer.d.ts.map +0 -0
  1017. /package/{dist/config → config}/config-renderer.js +0 -0
  1018. /package/{dist/config → config}/index.d.ts +0 -0
  1019. /package/{dist/config → config}/index.d.ts.map +0 -0
  1020. /package/{dist/config → config}/index.js +0 -0
  1021. /package/{dist/config → config}/ui-renderer.d.ts +0 -0
  1022. /package/{dist/config → config}/ui-renderer.d.ts.map +0 -0
  1023. /package/{dist/config → config}/ui-renderer.js +0 -0
  1024. /package/{dist/config → config}/ui-spec.d.ts +0 -0
  1025. /package/{dist/config → config}/ui-spec.d.ts.map +0 -0
  1026. /package/{dist/config → config}/ui-spec.js +0 -0
  1027. /package/{dist/events → events}/index.d.ts +0 -0
  1028. /package/{dist/events → events}/index.d.ts.map +0 -0
  1029. /package/{dist/events → events}/index.js +0 -0
  1030. /package/{dist/hooks → hooks}/index.d.ts +0 -0
  1031. /package/{dist/hooks → hooks}/index.d.ts.map +0 -0
  1032. /package/{dist/hooks → hooks}/index.js +0 -0
  1033. /package/{dist/hooks → hooks}/useBugReport.d.ts +0 -0
  1034. /package/{dist/hooks → hooks}/useBugReport.d.ts.map +0 -0
  1035. /package/{dist/hooks → hooks}/useBugReport.js +0 -0
  1036. /package/{dist/hooks → hooks}/useCanvasWindow.d.ts +0 -0
  1037. /package/{dist/hooks → hooks}/useCanvasWindow.d.ts.map +0 -0
  1038. /package/{dist/hooks → hooks}/useCanvasWindow.js +0 -0
  1039. /package/{dist/hooks → hooks}/useChatAvatarVoice.d.ts +0 -0
  1040. /package/{dist/hooks → hooks}/useChatAvatarVoice.d.ts.map +0 -0
  1041. /package/{dist/hooks → hooks}/useChatAvatarVoice.js +0 -0
  1042. /package/{dist/hooks → hooks}/useClickOutside.d.ts +0 -0
  1043. /package/{dist/hooks → hooks}/useClickOutside.d.ts.map +0 -0
  1044. /package/{dist/hooks → hooks}/useClickOutside.js +0 -0
  1045. /package/{dist/hooks → hooks}/useContextMenu.d.ts +0 -0
  1046. /package/{dist/hooks → hooks}/useContextMenu.d.ts.map +0 -0
  1047. /package/{dist/hooks → hooks}/useContextMenu.js +0 -0
  1048. /package/{dist/hooks → hooks}/useKeyboardShortcuts.d.ts +0 -0
  1049. /package/{dist/hooks → hooks}/useKeyboardShortcuts.d.ts.map +0 -0
  1050. /package/{dist/hooks → hooks}/useKeyboardShortcuts.js +0 -0
  1051. /package/{dist/hooks → hooks}/useLifoSync.d.ts +0 -0
  1052. /package/{dist/hooks → hooks}/useLifoSync.d.ts.map +0 -0
  1053. /package/{dist/hooks → hooks}/useLifoSync.js +0 -0
  1054. /package/{dist/hooks → hooks}/useMemoryMonitor.d.ts +0 -0
  1055. /package/{dist/hooks → hooks}/useMemoryMonitor.d.ts.map +0 -0
  1056. /package/{dist/hooks → hooks}/useMemoryMonitor.js +0 -0
  1057. /package/{dist/hooks → hooks}/useRenderGuard.d.ts +0 -0
  1058. /package/{dist/hooks → hooks}/useRenderGuard.d.ts.map +0 -0
  1059. /package/{dist/hooks → hooks}/useRenderGuard.js +0 -0
  1060. /package/{dist/hooks → hooks}/useRetakeCapture.d.ts +0 -0
  1061. /package/{dist/hooks → hooks}/useRetakeCapture.d.ts.map +0 -0
  1062. /package/{dist/hooks → hooks}/useRetakeCapture.js +0 -0
  1063. /package/{dist/hooks → hooks}/useStreamPopoutNavigation.d.ts +0 -0
  1064. /package/{dist/hooks → hooks}/useStreamPopoutNavigation.d.ts.map +0 -0
  1065. /package/{dist/hooks → hooks}/useStreamPopoutNavigation.js +0 -0
  1066. /package/{dist/hooks → hooks}/useTimeout.d.ts +0 -0
  1067. /package/{dist/hooks → hooks}/useTimeout.d.ts.map +0 -0
  1068. /package/{dist/hooks → hooks}/useTimeout.js +0 -0
  1069. /package/{dist/hooks → hooks}/useVoiceChat.d.ts +0 -0
  1070. /package/{dist/hooks → hooks}/useVoiceChat.d.ts.map +0 -0
  1071. /package/{dist/hooks → hooks}/useVoiceChat.js +0 -0
  1072. /package/{dist/hooks → hooks}/useWhatsAppPairing.d.ts +0 -0
  1073. /package/{dist/hooks → hooks}/useWhatsAppPairing.d.ts.map +0 -0
  1074. /package/{dist/hooks → hooks}/useWhatsAppPairing.js +0 -0
  1075. /package/{dist/i18n → i18n}/index.d.ts +0 -0
  1076. /package/{dist/i18n → i18n}/index.d.ts.map +0 -0
  1077. /package/{dist/i18n → i18n}/index.js +0 -0
  1078. /package/{dist/i18n → i18n}/messages.d.ts +0 -0
  1079. /package/{dist/i18n → i18n}/messages.d.ts.map +0 -0
  1080. /package/{dist/i18n → i18n}/messages.js +0 -0
  1081. /package/{dist/index.d.ts → index.d.ts} +0 -0
  1082. /package/{dist/index.d.ts.map → index.d.ts.map} +0 -0
  1083. /package/{dist/index.js → index.js} +0 -0
  1084. /package/{dist/navigation → navigation}/index.d.ts +0 -0
  1085. /package/{dist/navigation → navigation}/index.d.ts.map +0 -0
  1086. /package/{dist/navigation → navigation}/index.js +0 -0
  1087. /package/{dist/onboarding-config.d.ts → onboarding-config.d.ts} +0 -0
  1088. /package/{dist/onboarding-config.d.ts.map → onboarding-config.d.ts.map} +0 -0
  1089. /package/{dist/onboarding-config.js → onboarding-config.js} +0 -0
  1090. /package/{dist/platform → platform}/browser-launch.d.ts +0 -0
  1091. /package/{dist/platform → platform}/browser-launch.d.ts.map +0 -0
  1092. /package/{dist/platform → platform}/browser-launch.js +0 -0
  1093. /package/{dist/platform → platform}/index.d.ts +0 -0
  1094. /package/{dist/platform → platform}/index.d.ts.map +0 -0
  1095. /package/{dist/platform → platform}/index.js +0 -0
  1096. /package/{dist/platform → platform}/init.d.ts +0 -0
  1097. /package/{dist/platform → platform}/init.d.ts.map +0 -0
  1098. /package/{dist/platform → platform}/init.js +0 -0
  1099. /package/{dist/platform → platform}/lifo.d.ts +0 -0
  1100. /package/{dist/platform → platform}/lifo.d.ts.map +0 -0
  1101. /package/{dist/platform → platform}/lifo.js +0 -0
  1102. /package/{dist/providers → providers}/index.d.ts +0 -0
  1103. /package/{dist/providers → providers}/index.d.ts.map +0 -0
  1104. /package/{dist/providers → providers}/index.js +0 -0
  1105. /package/{dist/shell-params.d.ts → shell-params.d.ts} +0 -0
  1106. /package/{dist/shell-params.d.ts.map → shell-params.d.ts.map} +0 -0
  1107. /package/{dist/shell-params.js → shell-params.js} +0 -0
  1108. /package/{dist/state → state}/AppContext.d.ts +0 -0
  1109. /package/{dist/state → state}/index.d.ts +0 -0
  1110. /package/{dist/state → state}/index.d.ts.map +0 -0
  1111. /package/{dist/state → state}/index.js +0 -0
  1112. /package/{dist/state → state}/internal.d.ts +0 -0
  1113. /package/{dist/state → state}/internal.d.ts.map +0 -0
  1114. /package/{dist/state → state}/internal.js +0 -0
  1115. /package/{dist/state → state}/onboarding-resume.d.ts +0 -0
  1116. /package/{dist/state → state}/onboarding-resume.d.ts.map +0 -0
  1117. /package/{dist/state → state}/onboarding-resume.js +0 -0
  1118. /package/{dist/state → state}/parsers.d.ts +0 -0
  1119. /package/{dist/state → state}/parsers.d.ts.map +0 -0
  1120. /package/{dist/state → state}/parsers.js +0 -0
  1121. /package/{dist/state → state}/persistence.d.ts +0 -0
  1122. /package/{dist/state → state}/persistence.d.ts.map +0 -0
  1123. /package/{dist/state → state}/persistence.js +0 -0
  1124. /package/{dist/state → state}/shell-routing.d.ts +0 -0
  1125. /package/{dist/state → state}/shell-routing.d.ts.map +0 -0
  1126. /package/{dist/state → state}/shell-routing.js +0 -0
  1127. /package/{dist/state → state}/types.d.ts +0 -0
  1128. /package/{dist/state → state}/types.d.ts.map +0 -0
  1129. /package/{dist/state → state}/types.js +0 -0
  1130. /package/{dist/state → state}/ui-preferences.d.ts +0 -0
  1131. /package/{dist/state → state}/ui-preferences.d.ts.map +0 -0
  1132. /package/{dist/state → state}/ui-preferences.js +0 -0
  1133. /package/{dist/state → state}/useApp.d.ts +0 -0
  1134. /package/{dist/state → state}/useApp.d.ts.map +0 -0
  1135. /package/{dist/state → state}/useApp.js +0 -0
  1136. /package/{dist/state → state}/vrm.d.ts +0 -0
  1137. /package/{dist/state → state}/vrm.d.ts.map +0 -0
  1138. /package/{dist/state → state}/vrm.js +0 -0
  1139. /package/{dist/styles → styles}/base.css +0 -0
  1140. /package/{dist/styles → styles}/styles.css +0 -0
  1141. /package/{dist/styles → styles}/xterm.css +0 -0
  1142. /package/{dist/types → types}/index.d.ts +0 -0
  1143. /package/{dist/types → types}/index.d.ts.map +0 -0
  1144. /package/{dist/types → types}/index.js +0 -0
  1145. /package/{dist/utils → utils}/asset-url.d.ts +0 -0
  1146. /package/{dist/utils → utils}/asset-url.d.ts.map +0 -0
  1147. /package/{dist/utils → utils}/asset-url.js +0 -0
  1148. /package/{dist/utils → utils}/assistant-text.d.ts +0 -0
  1149. /package/{dist/utils → utils}/assistant-text.d.ts.map +0 -0
  1150. /package/{dist/utils → utils}/assistant-text.js +0 -0
  1151. /package/{dist/utils → utils}/clipboard.d.ts +0 -0
  1152. /package/{dist/utils → utils}/clipboard.d.ts.map +0 -0
  1153. /package/{dist/utils → utils}/clipboard.js +0 -0
  1154. /package/{dist/utils → utils}/desktop-dialogs.d.ts +0 -0
  1155. /package/{dist/utils → utils}/desktop-dialogs.d.ts.map +0 -0
  1156. /package/{dist/utils → utils}/desktop-dialogs.js +0 -0
  1157. /package/{dist/utils → utils}/eliza-globals.d.ts +0 -0
  1158. /package/{dist/utils → utils}/eliza-globals.d.ts.map +0 -0
  1159. /package/{dist/utils → utils}/eliza-globals.js +0 -0
  1160. /package/{dist/utils → utils}/index.d.ts +0 -0
  1161. /package/{dist/utils → utils}/index.d.ts.map +0 -0
  1162. /package/{dist/utils → utils}/index.js +0 -0
  1163. /package/{dist/utils → utils}/number-parsing.d.ts +0 -0
  1164. /package/{dist/utils → utils}/number-parsing.d.ts.map +0 -0
  1165. /package/{dist/utils → utils}/number-parsing.js +0 -0
  1166. /package/{dist/utils → utils}/openExternalUrl.d.ts +0 -0
  1167. /package/{dist/utils → utils}/openExternalUrl.d.ts.map +0 -0
  1168. /package/{dist/utils → utils}/openExternalUrl.js +0 -0
  1169. /package/{dist/utils → utils}/spoken-text.d.ts +0 -0
  1170. /package/{dist/utils → utils}/spoken-text.d.ts.map +0 -0
  1171. /package/{dist/utils → utils}/spoken-text.js +0 -0
  1172. /package/{dist/utils → utils}/streaming-text.d.ts +0 -0
  1173. /package/{dist/utils → utils}/streaming-text.d.ts.map +0 -0
  1174. /package/{dist/utils → utils}/streaming-text.js +0 -0
  1175. /package/{dist/voice → voice}/index.d.ts +0 -0
  1176. /package/{dist/voice → voice}/index.d.ts.map +0 -0
  1177. /package/{dist/voice → voice}/index.js +0 -0
  1178. /package/{dist/voice → voice}/types.d.ts +0 -0
  1179. /package/{dist/voice → voice}/types.d.ts.map +0 -0
  1180. /package/{dist/voice → voice}/types.js +0 -0
  1181. /package/{dist/wallet-rpc.d.ts → wallet-rpc.d.ts} +0 -0
  1182. /package/{dist/wallet-rpc.d.ts.map → wallet-rpc.d.ts.map} +0 -0
  1183. /package/{dist/wallet-rpc.js → wallet-rpc.js} +0 -0
@@ -1,3129 +0,0 @@
1
- /**
2
- * Plugins view — tag-filtered plugin management.
3
- *
4
- * Renders a unified plugin list with searchable/filterable cards and per-plugin settings.
5
- */
6
-
7
- import { Button, Input } from "@elizaos/ui";
8
- import type { LucideIcon } from "lucide-react";
9
- import {
10
- Binary,
11
- BookOpen,
12
- Bot,
13
- Brain,
14
- BrickWall,
15
- Briefcase,
16
- Calendar,
17
- ChevronRight,
18
- Chrome,
19
- Circle,
20
- CircleDashed,
21
- CircleDot,
22
- ClipboardList,
23
- Clock,
24
- Cloud,
25
- Command,
26
- Construction,
27
- CreditCard,
28
- Diamond,
29
- Dna,
30
- Droplets,
31
- Eye,
32
- Feather,
33
- FileKey,
34
- FileText,
35
- Fingerprint,
36
- Gamepad,
37
- Gamepad2,
38
- Github,
39
- Handshake,
40
- Hash,
41
- Layers,
42
- Leaf,
43
- Link,
44
- Lock,
45
- LockKeyhole,
46
- Mail,
47
- MessageCircle,
48
- MessageSquare,
49
- MessagesSquare,
50
- Mic,
51
- Monitor,
52
- MousePointer2,
53
- Package,
54
- PenTool,
55
- Phone,
56
- Pickaxe,
57
- Puzzle,
58
- RefreshCw,
59
- Rss,
60
- ScrollText,
61
- Send,
62
- Server,
63
- Settings,
64
- Shell,
65
- Shuffle,
66
- Smartphone,
67
- Sparkle,
68
- Sparkles,
69
- Square,
70
- Star,
71
- StickyNote,
72
- Target,
73
- Tornado,
74
- TrendingDown,
75
- Triangle,
76
- Twitter,
77
- Video,
78
- Volume2,
79
- Wallet,
80
- Webhook,
81
- Wrench,
82
- Zap,
83
- } from "lucide-react";
84
- import { useCallback, useEffect, useMemo, useRef, useState } from "react";
85
- import type { PluginInfo, PluginParamDef } from "../api";
86
- import { client } from "../api";
87
- import {
88
- ConfigRenderer,
89
- defaultRegistry,
90
- type JsonSchemaObject,
91
- } from "../config";
92
- import { useApp } from "../state";
93
- import type { ConfigUiHint } from "../types";
94
- import { openExternalUrl, resolveAppAssetUrl } from "../utils";
95
- import { autoLabel } from "./labels";
96
- import { SHOWCASE_PLUGIN } from "./plugins/showcase-data";
97
- import { WhatsAppQrOverlay } from "./WhatsAppQrOverlay";
98
-
99
- /* ── Always-on plugins (hidden from all views) ────────────────────────── */
100
-
101
- /**
102
- * Plugin IDs hidden from Features/Connectors views.
103
- * Core plugins are visible in Admin > Plugins instead.
104
- */
105
- const ALWAYS_ON_PLUGIN_IDS = new Set([
106
- // Core (always loaded)
107
- "sql",
108
- "local-embedding",
109
- "knowledge",
110
- "agent-skills",
111
- "directives",
112
- "commands",
113
- "personality",
114
- "experience",
115
- // Optional core (shown in admin)
116
- "agent-orchestrator",
117
- "shell",
118
- "plugin-manager",
119
- "cli",
120
- "code",
121
- "edge-tts",
122
- "pdf",
123
- "scratchpad",
124
- "secrets-manager",
125
- "todo",
126
- "trust",
127
- "form",
128
- "goals",
129
- "scheduling",
130
- // Internal / infrastructure
131
- "elizacloud",
132
- "evm",
133
- "memory",
134
- "rolodex",
135
- "tts",
136
- "elevenlabs",
137
- "cron",
138
- "webhooks",
139
- "browser",
140
- "vision",
141
- "computeruse",
142
- ]);
143
-
144
- /* ── Helpers ────────────────────────────────────────────────────────── */
145
-
146
- /** Detect advanced / debug parameters that should be collapsed by default. */
147
- function isAdvancedParam(param: PluginParamDef): boolean {
148
- const k = param.key.toUpperCase();
149
- const d = (param.description ?? "").toLowerCase();
150
- return (
151
- k.includes("EXPERIMENTAL") ||
152
- k.includes("DEBUG") ||
153
- k.includes("VERBOSE") ||
154
- k.includes("TELEMETRY") ||
155
- k.includes("BROWSER_BASE") ||
156
- d.includes("experimental") ||
157
- d.includes("advanced") ||
158
- d.includes("debug")
159
- );
160
- }
161
-
162
- /** Convert PluginParamDef[] to a JSON Schema + ConfigUiHints for ConfigRenderer. */
163
- export function paramsToSchema(
164
- params: PluginParamDef[],
165
- pluginId: string,
166
- ): {
167
- schema: JsonSchemaObject;
168
- hints: Record<string, ConfigUiHint>;
169
- } {
170
- const properties: Record<string, Record<string, unknown>> = {};
171
- const required: string[] = [];
172
- const hints: Record<string, ConfigUiHint> = {};
173
-
174
- for (const p of params) {
175
- // Build JSON Schema property
176
- const prop: Record<string, unknown> = {};
177
- if (p.type === "boolean") {
178
- prop.type = "boolean";
179
- } else if (p.type === "number") {
180
- prop.type = "number";
181
- } else {
182
- prop.type = "string";
183
- }
184
- if (p.description) prop.description = p.description;
185
- if (p.default != null) prop.default = p.default;
186
- if (p.options?.length) {
187
- prop.enum = p.options;
188
- }
189
-
190
- // Auto-detect format from key name
191
- const keyUpper = p.key.toUpperCase();
192
- if (
193
- keyUpper.includes("URL") ||
194
- keyUpper.includes("ENDPOINT") ||
195
- keyUpper.includes("BASE_URL")
196
- ) {
197
- prop.format = "uri";
198
- } else if (keyUpper.includes("EMAIL")) {
199
- prop.format = "email";
200
- } else if (
201
- keyUpper.includes("_DATE") ||
202
- keyUpper.includes("_SINCE") ||
203
- keyUpper.includes("_UNTIL")
204
- ) {
205
- prop.format = "date";
206
- }
207
-
208
- // Auto-detect number types from key patterns
209
- if (keyUpper.includes("PORT") && prop.type === "string") {
210
- prop.type = "number";
211
- } else if (
212
- (keyUpper.includes("TIMEOUT") ||
213
- keyUpper.includes("INTERVAL") ||
214
- keyUpper.includes("_MS")) &&
215
- prop.type === "string"
216
- ) {
217
- prop.type = "number";
218
- } else if (
219
- (keyUpper.includes("COUNT") ||
220
- keyUpper.includes("LIMIT") ||
221
- keyUpper.startsWith("MAX_")) &&
222
- prop.type === "string"
223
- ) {
224
- prop.type = "number";
225
- } else if (
226
- (keyUpper.includes("RETRY") || keyUpper.includes("RETRIES")) &&
227
- prop.type === "string"
228
- ) {
229
- prop.type = "number";
230
- }
231
-
232
- // Auto-detect boolean from key patterns
233
- if (
234
- prop.type === "string" &&
235
- (keyUpper.includes("SHOULD_") ||
236
- keyUpper.endsWith("_ENABLED") ||
237
- keyUpper.endsWith("_DISABLED") ||
238
- keyUpper.startsWith("USE_") ||
239
- keyUpper.startsWith("ALLOW_") ||
240
- keyUpper.startsWith("IS_") ||
241
- keyUpper.startsWith("ENABLE_") ||
242
- keyUpper.startsWith("DISABLE_") ||
243
- keyUpper.startsWith("FORCE_") ||
244
- keyUpper.endsWith("_AUTONOMOUS_MODE"))
245
- ) {
246
- prop.type = "boolean";
247
- }
248
-
249
- // Auto-detect number from key patterns (RATE, DELAY, THRESHOLD, SIZE, TEMPERATURE)
250
- if (
251
- prop.type === "string" &&
252
- (keyUpper.includes("_RATE") ||
253
- keyUpper.includes("DELAY") ||
254
- keyUpper.includes("THRESHOLD") ||
255
- keyUpper.includes("_SIZE") ||
256
- keyUpper.includes("TEMPERATURE") ||
257
- keyUpper.includes("_DEPTH") ||
258
- keyUpper.includes("_PERCENT") ||
259
- keyUpper.includes("_RATIO"))
260
- ) {
261
- prop.type = "number";
262
- }
263
-
264
- // Auto-detect comma-separated lists → array renderer
265
- if (prop.type === "string" && !prop.enum) {
266
- const descLower = (p.description || "").toLowerCase();
267
- const isCommaSep =
268
- descLower.includes("comma-separated") ||
269
- descLower.includes("comma separated");
270
- const isListSuffix =
271
- keyUpper.endsWith("_IDS") ||
272
- keyUpper.endsWith("_CHANNELS") ||
273
- keyUpper.endsWith("_ROOMS") ||
274
- keyUpper.endsWith("_RELAYS") ||
275
- keyUpper.endsWith("_FEEDS") ||
276
- keyUpper.endsWith("_DEXES") ||
277
- keyUpper.endsWith("_WHITELIST") ||
278
- keyUpper.endsWith("_BLACKLIST") ||
279
- keyUpper.endsWith("_ALLOWLIST") ||
280
- keyUpper.endsWith("_SPACES") ||
281
- keyUpper.endsWith("_THREADS") ||
282
- keyUpper.endsWith("_ROLES") ||
283
- keyUpper.endsWith("_TENANTS") ||
284
- keyUpper.endsWith("_DIRS");
285
- if (isCommaSep || isListSuffix) {
286
- prop.type = "array";
287
- prop.items = { type: "string" };
288
- }
289
- }
290
-
291
- // Auto-detect textarea (prompts, instructions, templates, greetings)
292
- if (prop.type === "string" && !prop.enum && !keyUpper.includes("MODEL")) {
293
- if (
294
- keyUpper.includes("INSTRUCTIONS") ||
295
- keyUpper.includes("_GREETING") ||
296
- keyUpper.endsWith("_PROMPT") ||
297
- keyUpper.endsWith("_TEMPLATE") ||
298
- keyUpper.includes("SYSTEM_MESSAGE")
299
- ) {
300
- prop.maxLength = 999;
301
- }
302
- }
303
-
304
- // Auto-detect JSON fields (json-encoded or serialized values)
305
- if (prop.type === "string" && !p.sensitive) {
306
- const descLower = (p.description || "").toLowerCase();
307
- if (
308
- descLower.includes("json-encoded") ||
309
- descLower.includes("json array") ||
310
- descLower.includes("serialized") ||
311
- descLower.includes("json format")
312
- ) {
313
- (prop as Record<string, unknown>).__jsonHint = true;
314
- }
315
- }
316
-
317
- // Auto-detect file/directory paths → file renderer
318
- if (prop.type === "string") {
319
- if (
320
- (keyUpper.endsWith("_PATH") && !keyUpper.includes("WEBHOOK")) ||
321
- keyUpper.endsWith("_DIR") ||
322
- keyUpper.endsWith("_DIRECTORY") ||
323
- keyUpper.endsWith("_FOLDER") ||
324
- keyUpper.endsWith("_FILE")
325
- ) {
326
- (prop as Record<string, unknown>).__fileHint = true;
327
- }
328
- }
329
-
330
- // Auto-detect textarea from long descriptions
331
- if (p.description && p.description.length > 200) {
332
- prop.maxLength = 999;
333
- }
334
-
335
- properties[p.key] = prop;
336
-
337
- if (p.required) required.push(p.key);
338
-
339
- // Build UI hint
340
- const hint: ConfigUiHint = {
341
- label: autoLabel(p.key, pluginId),
342
- sensitive: p.sensitive ?? false,
343
- advanced: isAdvancedParam(p),
344
- };
345
-
346
- // Port numbers — constrain range
347
- if (keyUpper.includes("PORT")) {
348
- hint.min = 1;
349
- hint.max = 65535;
350
- prop.minimum = 1;
351
- prop.maximum = 65535;
352
- }
353
-
354
- // Timeout/interval — show unit
355
- if (
356
- keyUpper.includes("TIMEOUT") ||
357
- keyUpper.includes("INTERVAL") ||
358
- keyUpper.includes("_MS")
359
- ) {
360
- hint.unit = "ms";
361
- prop.minimum = 0;
362
- hint.min = 0;
363
- }
364
-
365
- // Count/limit — non-negative
366
- if (
367
- keyUpper.includes("COUNT") ||
368
- keyUpper.includes("LIMIT") ||
369
- keyUpper.startsWith("MAX_")
370
- ) {
371
- hint.min = 0;
372
- prop.minimum = 0;
373
- }
374
-
375
- // Retry — bounded range
376
- if (keyUpper.includes("RETRY") || keyUpper.includes("RETRIES")) {
377
- hint.min = 0;
378
- hint.max = 100;
379
- prop.minimum = 0;
380
- prop.maximum = 100;
381
- }
382
-
383
- // Debug/verbose/enabled — mark as advanced
384
- if (
385
- keyUpper.includes("DEBUG") ||
386
- keyUpper.includes("VERBOSE") ||
387
- keyUpper.includes("ENABLED")
388
- ) {
389
- hint.advanced = true;
390
- }
391
-
392
- // Model selection — NOT advanced (important user-facing choice)
393
- if (keyUpper.includes("MODEL") && p.options?.length) {
394
- hint.advanced = false;
395
- }
396
-
397
- // Region/zone — suggest common cloud regions when no options provided
398
- if (
399
- (keyUpper.includes("REGION") || keyUpper.includes("ZONE")) &&
400
- !p.options?.length
401
- ) {
402
- hint.type = "select";
403
- hint.options = [
404
- { value: "us-east-1", label: "US East (N. Virginia)" },
405
- { value: "us-west-2", label: "US West (Oregon)" },
406
- { value: "eu-west-1", label: "EU (Ireland)" },
407
- { value: "eu-central-1", label: "EU (Frankfurt)" },
408
- { value: "ap-southeast-1", label: "Asia Pacific (Singapore)" },
409
- { value: "ap-northeast-1", label: "Asia Pacific (Tokyo)" },
410
- ];
411
- }
412
-
413
- // File/directory path → file renderer
414
- if ((prop as Record<string, unknown>).__fileHint) {
415
- hint.type = "file";
416
- delete (prop as Record<string, unknown>).__fileHint;
417
- }
418
-
419
- // JSON-encoded value → json renderer
420
- if ((prop as Record<string, unknown>).__jsonHint) {
421
- hint.type = "json";
422
- delete (prop as Record<string, unknown>).__jsonHint;
423
- }
424
-
425
- // Model name fields — helpful placeholder (overridden by server-provided model options via configUiHints)
426
- if (
427
- keyUpper.includes("MODEL") &&
428
- prop.type === "string" &&
429
- !p.options?.length
430
- ) {
431
- if (!hint.placeholder) {
432
- if (keyUpper.includes("EMBEDDING")) {
433
- hint.placeholder = "e.g., text-embedding-3-small";
434
- } else if (keyUpper.includes("TTS")) {
435
- hint.placeholder = "e.g., tts-1, eleven_multilingual_v2";
436
- } else if (keyUpper.includes("STT")) {
437
- hint.placeholder = "e.g., whisper-1";
438
- } else if (keyUpper.includes("IMAGE")) {
439
- hint.placeholder = "e.g., dall-e-3, gpt-4o";
440
- } else {
441
- hint.placeholder = "e.g., gpt-4o, claude-sonnet-4-20250514";
442
- }
443
- }
444
- }
445
-
446
- // Mode/strategy fields — extract options from description if available
447
- if (
448
- prop.type === "string" &&
449
- !prop.enum &&
450
- !p.sensitive &&
451
- (keyUpper.endsWith("_MODE") || keyUpper.endsWith("_STRATEGY"))
452
- ) {
453
- const desc = p.description ?? "";
454
- // Match "auto | local | mcp" or "filesystem|in-context|sqlite"
455
- const pipeMatch =
456
- desc.match(/:\s*([a-z0-9_-]+(?:\s*[|/]\s*[a-z0-9_-]+)+)/i) ??
457
- desc.match(/\(([a-z0-9_-]+(?:\s*[|/,]\s*[a-z0-9_-]+)+)\)/i);
458
- if (pipeMatch) {
459
- const opts = pipeMatch[1]
460
- .split(/[|/,]/)
461
- .map((s) => s.trim())
462
- .filter(Boolean);
463
- const safeOpts = opts.filter((v) => /^[a-z0-9_-]+$/i.test(v));
464
- if (safeOpts.length >= 2 && safeOpts.length <= 10) {
465
- hint.type = "select";
466
- hint.options = safeOpts.map((v) => ({ value: v, label: v }));
467
- }
468
- } else {
469
- // Match 'polling' or 'webhook' -or- 'env', 'oauth', or 'bearer' style
470
- const quotedOpts = [...desc.matchAll(/'([a-z0-9_-]+)'/gi)].map(
471
- (m) => m[1],
472
- );
473
- const safeQuoted = quotedOpts.filter((v) => /^[a-z0-9_-]+$/i.test(v));
474
- if (safeQuoted.length >= 2 && safeQuoted.length <= 10) {
475
- // Radio for 2 options, select for 3+
476
- hint.type = safeQuoted.length === 2 ? "radio" : "select";
477
- hint.options = safeQuoted.map((v) => ({ value: v, label: v }));
478
- }
479
- }
480
- }
481
-
482
- if (p.description) {
483
- hint.help = p.description;
484
- if (p.default != null) hint.help += ` (default: ${String(p.default)})`;
485
- }
486
- if (p.sensitive)
487
- hint.placeholder = p.isSet ? "******** (already set)" : "Enter value...";
488
- else if (p.default) hint.placeholder = `Default: ${String(p.default)}`;
489
- hints[p.key] = hint;
490
- }
491
-
492
- return {
493
- schema: { type: "object", properties, required } as JsonSchemaObject,
494
- hints,
495
- };
496
- }
497
-
498
- /* ── PluginConfigForm bridge ─────────────────────────────────────────── */
499
-
500
- function PluginConfigForm({
501
- plugin,
502
- pluginConfigs,
503
- onParamChange,
504
- }: {
505
- plugin: PluginInfo;
506
- pluginConfigs: Record<string, Record<string, string>>;
507
- onParamChange: (pluginId: string, paramKey: string, value: string) => void;
508
- }) {
509
- const params = plugin.parameters ?? [];
510
- const { schema, hints: autoHints } = useMemo(
511
- () => paramsToSchema(params, plugin.id),
512
- [params, plugin.id],
513
- );
514
-
515
- // Merge server-provided configUiHints over auto-generated hints.
516
- // Server hints take priority (override auto-generated ones).
517
- const hints = useMemo(() => {
518
- const serverHints = plugin.configUiHints;
519
- if (!serverHints || Object.keys(serverHints).length === 0) return autoHints;
520
- const merged: Record<string, ConfigUiHint> = { ...autoHints };
521
- for (const [key, serverHint] of Object.entries(serverHints)) {
522
- merged[key] = { ...merged[key], ...serverHint };
523
- }
524
- return merged;
525
- }, [autoHints, plugin.configUiHints]);
526
-
527
- // Build values from current config state + existing server values.
528
- // Array-typed fields need comma-separated strings parsed into arrays.
529
- const values = useMemo(() => {
530
- const v: Record<string, unknown> = {};
531
- const props = (schema.properties ?? {}) as Record<
532
- string,
533
- Record<string, unknown>
534
- >;
535
- for (const p of params) {
536
- const isArrayField = props[p.key]?.type === "array";
537
- const configValue = pluginConfigs[plugin.id]?.[p.key];
538
- if (configValue !== undefined) {
539
- if (isArrayField && typeof configValue === "string") {
540
- v[p.key] = configValue
541
- ? configValue
542
- .split(",")
543
- .map((s: string) => s.trim())
544
- .filter(Boolean)
545
- : [];
546
- } else {
547
- v[p.key] = configValue;
548
- }
549
- } else if (p.isSet && !p.sensitive && p.currentValue != null) {
550
- if (isArrayField && typeof p.currentValue === "string") {
551
- v[p.key] = String(p.currentValue)
552
- ? String(p.currentValue)
553
- .split(",")
554
- .map((s: string) => s.trim())
555
- .filter(Boolean)
556
- : [];
557
- } else {
558
- v[p.key] = p.currentValue;
559
- }
560
- }
561
- }
562
- return v;
563
- }, [params, plugin.id, pluginConfigs, schema]);
564
-
565
- const setKeys = useMemo(
566
- () =>
567
- new Set(
568
- params
569
- .filter((p: PluginParamDef) => p.isSet)
570
- .map((p: PluginParamDef) => p.key),
571
- ),
572
- [params],
573
- );
574
-
575
- const handleChange = useCallback(
576
- (key: string, value: unknown) => {
577
- // Join array values back to comma-separated strings for env var storage
578
- const stringValue = Array.isArray(value)
579
- ? value.join(", ")
580
- : String(value ?? "");
581
- onParamChange(plugin.id, key, stringValue);
582
- },
583
- [plugin.id, onParamChange],
584
- );
585
-
586
- return (
587
- <ConfigRenderer
588
- schema={schema}
589
- hints={hints}
590
- values={values}
591
- setKeys={setKeys}
592
- registry={defaultRegistry}
593
- pluginId={plugin.id}
594
- onChange={handleChange}
595
- />
596
- );
597
- }
598
-
599
- /* ── Default Icons ─────────────────────────────────────────────────── */
600
-
601
- const DEFAULT_ICONS: Record<string, LucideIcon> = {
602
- // AI Providers
603
- anthropic: Brain,
604
- "google-genai": Sparkles,
605
- groq: Zap,
606
- "local-ai": Monitor,
607
- ollama: Bot,
608
- openai: CircleDashed,
609
- openrouter: Shuffle,
610
- "vercel-ai-gateway": Triangle,
611
- xai: Hash,
612
- // Connectors — chat & social
613
- discord: MessageCircle,
614
- telegram: Send,
615
- slack: Briefcase,
616
- twitter: Twitter,
617
- whatsapp: Smartphone,
618
- signal: Lock,
619
- imessage: MessageSquare,
620
- bluebubbles: Droplets,
621
- bluesky: Leaf,
622
- farcaster: Circle,
623
- instagram: Video,
624
- nostr: Fingerprint,
625
- twitch: Gamepad2,
626
- matrix: Link,
627
- mattermost: Diamond,
628
- msteams: Square,
629
- "google-chat": MessagesSquare,
630
- feishu: Feather,
631
- line: Circle,
632
- "nextcloud-talk": Cloud,
633
- tlon: Tornado,
634
- zalo: Circle,
635
- zalouser: Circle,
636
- // Features — voice & audio
637
- "edge-tts": Volume2,
638
- elevenlabs: Mic,
639
- tts: Volume2,
640
- "simple-voice": Mic,
641
- "robot-voice": Bot,
642
- // Features — blockchain & finance
643
- evm: Link,
644
- solana: CircleDot,
645
- "auto-trader": TrendingDown,
646
- "lp-manager": Wallet,
647
- "social-alpha": Layers,
648
- polymarket: Gamepad2,
649
- x402: CreditCard,
650
- trust: Handshake,
651
- iq: Puzzle,
652
- // Features — dev tools & infra
653
- cli: Hash,
654
- code: Puzzle,
655
- shell: Shell,
656
- github: Github,
657
- linear: Square,
658
- mcp: Puzzle,
659
- browser: Chrome,
660
- computeruse: MousePointer2,
661
- n8n: Settings,
662
- webhooks: Webhook,
663
- // Features — knowledge & memory
664
- knowledge: BookOpen,
665
- memory: Dna,
666
- "local-embedding": Binary,
667
- pdf: FileText,
668
- "secrets-manager": FileKey,
669
- scratchpad: StickyNote,
670
- rlm: RefreshCw,
671
- // Features — agents & orchestration
672
- "agent-orchestrator": Target,
673
- "agent-skills": Wrench,
674
- "plugin-manager": Package,
675
- "copilot-proxy": Handshake,
676
- directives: ClipboardList,
677
- goals: Target,
678
- "eliza-classic": Bot,
679
- // Features — media & content
680
- vision: Eye,
681
- rss: Rss,
682
- "gmail-watch": Mail,
683
- prose: PenTool,
684
- form: ClipboardList,
685
- // Features — scheduling & automation
686
- cron: Clock,
687
- scheduling: Calendar,
688
- todo: ClipboardList,
689
- commands: Command,
690
- // Features — storage & logging
691
- "s3-storage": Server,
692
- "trajectory-logger": TrendingDown,
693
- experience: Star,
694
- // Features — gaming & misc
695
- minecraft: Pickaxe,
696
- roblox: BrickWall,
697
- babylon: Gamepad,
698
- mysticism: Sparkle,
699
- personality: Target,
700
- moltbook: ScrollText,
701
- tee: LockKeyhole,
702
- blooio: Circle,
703
- acp: Construction,
704
- elizacloud: Cloud,
705
- twilio: Phone,
706
- };
707
-
708
- /** Resolve display icon: explicit plugin.icon, fallback to default map, or null. */
709
- function resolveIcon(p: PluginInfo): LucideIcon | string | null {
710
- if (p.icon) return p.icon;
711
- return DEFAULT_ICONS[p.id] ?? null;
712
- }
713
-
714
- function iconImageSource(icon: string): string | null {
715
- const value = icon.trim();
716
- if (!value) return null;
717
- if (
718
- /^(https?:|data:image\/|blob:|file:|capacitor:|electrobun:|app:|\/|\.\/|\.\.\/)/i.test(
719
- value,
720
- )
721
- ) {
722
- return resolveAppAssetUrl(value);
723
- }
724
- return null;
725
- }
726
-
727
- function getPluginResourceLinks(
728
- plugin: Pick<PluginInfo, "setupGuideUrl" | "homepage" | "repository">,
729
- ): Array<{ key: string; label: string; url: string }> {
730
- const seen = new Set<string>();
731
- const ordered = [
732
- { key: "guide", label: "Setup guide", url: plugin.setupGuideUrl },
733
- { key: "official", label: "Official", url: plugin.homepage },
734
- { key: "source", label: "Source", url: plugin.repository },
735
- ];
736
- return ordered.flatMap((item) => {
737
- const url = item.url?.trim();
738
- if (!url || seen.has(url)) return [];
739
- seen.add(url);
740
- return [{ key: item.key, label: item.label, url }];
741
- });
742
- }
743
-
744
- /* ── Sub-group Classification ──────────────────────────────────────── */
745
-
746
- /** Map plugin IDs to fine-grained sub-groups for the "Feature" category. */
747
- const FEATURE_SUBGROUP: Record<string, string> = {
748
- // Voice & Audio
749
- "edge-tts": "voice",
750
- elevenlabs: "voice",
751
- tts: "voice",
752
- "simple-voice": "voice",
753
- "robot-voice": "voice",
754
- // Blockchain & Finance
755
- evm: "blockchain",
756
- solana: "blockchain",
757
- "auto-trader": "blockchain",
758
- "lp-manager": "blockchain",
759
- "social-alpha": "blockchain",
760
- polymarket: "blockchain",
761
- x402: "blockchain",
762
- trust: "blockchain",
763
- iq: "blockchain",
764
- // Dev Tools & Infrastructure
765
- cli: "devtools",
766
- code: "devtools",
767
- shell: "devtools",
768
- github: "devtools",
769
- linear: "devtools",
770
- mcp: "devtools",
771
- browser: "devtools",
772
- computeruse: "devtools",
773
- n8n: "devtools",
774
- webhooks: "devtools",
775
- // Knowledge & Memory
776
- knowledge: "knowledge",
777
- memory: "knowledge",
778
- "local-embedding": "knowledge",
779
- pdf: "knowledge",
780
- "secrets-manager": "knowledge",
781
- scratchpad: "knowledge",
782
- rlm: "knowledge",
783
- // Agents & Orchestration
784
- "agent-orchestrator": "agents",
785
- "agent-skills": "agents",
786
- "plugin-manager": "agents",
787
- "copilot-proxy": "agents",
788
- directives: "agents",
789
- goals: "agents",
790
- "eliza-classic": "agents",
791
- // Media & Content
792
- vision: "media",
793
- rss: "media",
794
- "gmail-watch": "media",
795
- prose: "media",
796
- form: "media",
797
- // Scheduling & Automation
798
- cron: "automation",
799
- scheduling: "automation",
800
- todo: "automation",
801
- commands: "automation",
802
- // Storage & Logging
803
- "s3-storage": "storage",
804
- "trajectory-logger": "storage",
805
- experience: "storage",
806
- // Gaming & Creative
807
- minecraft: "gaming",
808
- roblox: "gaming",
809
- babylon: "gaming",
810
- mysticism: "gaming",
811
- personality: "gaming",
812
- moltbook: "gaming",
813
- };
814
-
815
- const SUBGROUP_DISPLAY_ORDER = [
816
- "ai-provider",
817
- "connector",
818
- "streaming",
819
- "voice",
820
- "blockchain",
821
- "devtools",
822
- "knowledge",
823
- "agents",
824
- "media",
825
- "automation",
826
- "storage",
827
- "gaming",
828
- "feature-other",
829
- "showcase",
830
- ] as const;
831
-
832
- const SUBGROUP_LABELS: Record<string, string> = {
833
- "ai-provider": "AI Providers",
834
- connector: "Connectors",
835
- voice: "Voice & Audio",
836
- blockchain: "Blockchain & Finance",
837
- devtools: "Dev Tools & Infrastructure",
838
- knowledge: "Knowledge & Memory",
839
- agents: "Agents & Orchestration",
840
- media: "Media & Content",
841
- automation: "Scheduling & Automation",
842
- storage: "Storage & Logging",
843
- gaming: "Gaming & Creative",
844
- "feature-other": "Other Features",
845
- streaming: "Streaming Destinations",
846
- showcase: "Showcase",
847
- };
848
-
849
- const SUBGROUP_NAV_ICONS: Record<string, LucideIcon> = {
850
- all: Package,
851
- "ai-provider": Brain,
852
- connector: MessageCircle,
853
- streaming: Video,
854
- voice: Mic,
855
- blockchain: Wallet,
856
- devtools: Shell,
857
- knowledge: BookOpen,
858
- agents: Target,
859
- media: Eye,
860
- automation: Calendar,
861
- storage: Server,
862
- gaming: Gamepad2,
863
- "feature-other": Puzzle,
864
- showcase: Sparkles,
865
- };
866
-
867
- function subgroupForPlugin(plugin: PluginInfo): string {
868
- if (plugin.id === "__ui-showcase__") return "showcase";
869
- if (plugin.category === "ai-provider") return "ai-provider";
870
- if (plugin.category === "connector") return "connector";
871
- if (plugin.category === "streaming") return "streaming";
872
- return FEATURE_SUBGROUP[plugin.id] ?? "feature-other";
873
- }
874
-
875
- type StatusFilter = "all" | "enabled" | "disabled";
876
- type PluginsViewMode = "all" | "connectors" | "streaming" | "social";
877
- type SubgroupTag = { id: string; label: string; count: number };
878
-
879
- function comparePlugins(left: PluginInfo, right: PluginInfo): number {
880
- if (left.enabled !== right.enabled) return left.enabled ? -1 : 1;
881
- if (left.enabled && right.enabled) {
882
- const leftNeedsConfig =
883
- left.parameters?.some(
884
- (param: PluginParamDef) => param.required && !param.isSet,
885
- ) ?? false;
886
- const rightNeedsConfig =
887
- right.parameters?.some(
888
- (param: PluginParamDef) => param.required && !param.isSet,
889
- ) ?? false;
890
- if (leftNeedsConfig !== rightNeedsConfig) {
891
- return leftNeedsConfig ? -1 : 1;
892
- }
893
- }
894
- return (left.name ?? "").localeCompare(right.name ?? "");
895
- }
896
-
897
- function matchesPluginFilters(
898
- plugin: PluginInfo,
899
- searchLower: string,
900
- statusFilter: StatusFilter,
901
- ): boolean {
902
- const matchesStatus =
903
- statusFilter === "all" ||
904
- (statusFilter === "enabled" && plugin.enabled) ||
905
- (statusFilter === "disabled" && !plugin.enabled);
906
- const matchesSearch =
907
- !searchLower ||
908
- (plugin.name ?? "").toLowerCase().includes(searchLower) ||
909
- (plugin.description ?? "").toLowerCase().includes(searchLower) ||
910
- (plugin.tags ?? []).some((tag) =>
911
- (tag ?? "").toLowerCase().includes(searchLower),
912
- ) ||
913
- plugin.id.toLowerCase().includes(searchLower);
914
- return matchesStatus && matchesSearch;
915
- }
916
-
917
- function sortPlugins(
918
- filteredPlugins: PluginInfo[],
919
- pluginOrder: string[],
920
- allowCustomOrder: boolean,
921
- ): PluginInfo[] {
922
- if (!allowCustomOrder || pluginOrder.length === 0) {
923
- return [...filteredPlugins].sort(comparePlugins);
924
- }
925
-
926
- const orderMap = new Map(pluginOrder.map((id, index) => [id, index]));
927
- return [...filteredPlugins].sort((left, right) => {
928
- const leftIndex = orderMap.get(left.id);
929
- const rightIndex = orderMap.get(right.id);
930
- if (leftIndex != null && rightIndex != null) return leftIndex - rightIndex;
931
- if (leftIndex != null) return -1;
932
- if (rightIndex != null) return 1;
933
- return comparePlugins(left, right);
934
- });
935
- }
936
-
937
- function buildPluginListState(options: {
938
- allowCustomOrder: boolean;
939
- effectiveSearch: string;
940
- effectiveStatusFilter: StatusFilter;
941
- isConnectorLikeMode: boolean;
942
- mode: PluginsViewMode;
943
- pluginOrder: string[];
944
- plugins: PluginInfo[];
945
- showSubgroupFilters: boolean;
946
- subgroupFilter: string;
947
- }): {
948
- categoryPlugins: PluginInfo[];
949
- enabledCount: number;
950
- nonDbPlugins: PluginInfo[];
951
- sorted: PluginInfo[];
952
- subgroupTags: SubgroupTag[];
953
- visiblePlugins: PluginInfo[];
954
- } {
955
- const {
956
- allowCustomOrder,
957
- effectiveSearch,
958
- effectiveStatusFilter,
959
- isConnectorLikeMode,
960
- mode,
961
- pluginOrder,
962
- plugins,
963
- showSubgroupFilters,
964
- subgroupFilter,
965
- } = options;
966
- const categoryPlugins = plugins.filter(
967
- (plugin) =>
968
- plugin.category !== "database" &&
969
- !ALWAYS_ON_PLUGIN_IDS.has(plugin.id) &&
970
- (!isConnectorLikeMode || plugin.category === "connector") &&
971
- (mode !== "streaming" || plugin.category === "streaming"),
972
- );
973
- const nonDbPlugins = [SHOWCASE_PLUGIN, ...categoryPlugins];
974
- const searchLower = effectiveSearch.toLowerCase();
975
- const sorted = sortPlugins(
976
- categoryPlugins.filter((plugin) =>
977
- matchesPluginFilters(plugin, searchLower, effectiveStatusFilter),
978
- ),
979
- pluginOrder,
980
- allowCustomOrder,
981
- );
982
- const enabledCount = categoryPlugins.filter(
983
- (plugin) => plugin.enabled,
984
- ).length;
985
-
986
- const subgroupCounts: Record<string, number> = {};
987
- const visiblePlugins: PluginInfo[] = [];
988
- for (const plugin of sorted) {
989
- const subgroup = subgroupForPlugin(plugin);
990
- subgroupCounts[subgroup] = (subgroupCounts[subgroup] ?? 0) + 1;
991
- if (
992
- !showSubgroupFilters ||
993
- subgroupFilter === "all" ||
994
- subgroup === subgroupFilter
995
- ) {
996
- visiblePlugins.push(plugin);
997
- }
998
- }
999
-
1000
- const subgroupTags = [
1001
- { id: "all", label: "All", count: sorted.length },
1002
- ...SUBGROUP_DISPLAY_ORDER.filter(
1003
- (subgroupId) => (subgroupCounts[subgroupId] ?? 0) > 0,
1004
- ).map((subgroupId) => ({
1005
- id: subgroupId,
1006
- label: SUBGROUP_LABELS[subgroupId],
1007
- count: subgroupCounts[subgroupId] ?? 0,
1008
- })),
1009
- ];
1010
-
1011
- return {
1012
- categoryPlugins,
1013
- enabledCount,
1014
- nonDbPlugins,
1015
- sorted,
1016
- subgroupTags,
1017
- visiblePlugins,
1018
- };
1019
- }
1020
-
1021
- /* ── Shared PluginListView ─────────────────────────────────────────── */
1022
-
1023
- interface PluginListViewProps {
1024
- /** Label used in search placeholder and empty state messages. */
1025
- label: string;
1026
- /** Optional list mode for pre-filtered views like Connectors. */
1027
- mode?: PluginsViewMode;
1028
- /** Whether the view is rendered in a full-screen gamified modal. */
1029
- inModal?: boolean;
1030
- }
1031
-
1032
- function PluginListView({ label, mode = "all", inModal }: PluginListViewProps) {
1033
- const {
1034
- plugins,
1035
- pluginStatusFilter,
1036
- pluginSearch,
1037
- pluginSettingsOpen,
1038
- pluginSaving,
1039
- pluginSaveSuccess,
1040
- loadPlugins,
1041
- handlePluginToggle,
1042
- handlePluginConfigSave,
1043
- setActionNotice,
1044
- setState,
1045
- t,
1046
- } = useApp();
1047
-
1048
- const [pluginConfigs, setPluginConfigs] = useState<
1049
- Record<string, Record<string, string>>
1050
- >({});
1051
- const [testResults, setTestResults] = useState<
1052
- Map<
1053
- string,
1054
- {
1055
- success: boolean;
1056
- message?: string;
1057
- error?: string;
1058
- durationMs: number;
1059
- loading: boolean;
1060
- }
1061
- >
1062
- >(new Map());
1063
- const [addDirOpen, setAddDirOpen] = useState(false);
1064
- const [addDirPath, setAddDirPath] = useState("");
1065
- const [addDirLoading, setAddDirLoading] = useState(false);
1066
- const [installingPlugins, setInstallingPlugins] = useState<Set<string>>(
1067
- new Set(),
1068
- );
1069
- const [installProgress, setInstallProgress] = useState<
1070
- Map<string, { phase: string; message: string }>
1071
- >(new Map());
1072
- const [togglingPlugins, setTogglingPlugins] = useState<Set<string>>(
1073
- new Set(),
1074
- );
1075
- const hasPluginToggleInFlight = togglingPlugins.size > 0;
1076
-
1077
- // ── Drag-to-reorder state ────────────────────────────────────────
1078
- const [pluginOrder, setPluginOrder] = useState<string[]>(() => {
1079
- try {
1080
- const stored = localStorage.getItem("pluginOrder");
1081
- return stored ? JSON.parse(stored) : [];
1082
- } catch {
1083
- return [];
1084
- }
1085
- });
1086
- const [draggingId, setDraggingId] = useState<string | null>(null);
1087
- const [dragOverId, setDragOverId] = useState<string | null>(null);
1088
- const dragRef = useRef<string | null>(null);
1089
- const isSocialMode = mode === "social";
1090
- const isConnectorLikeMode = mode === "connectors" || mode === "social";
1091
- const resultLabel = isSocialMode ? "connectors" : label.toLowerCase();
1092
- const searchPlaceholder = isSocialMode
1093
- ? "Search..."
1094
- : `Search ${label.toLowerCase()}...`;
1095
- const effectiveStatusFilter: StatusFilter =
1096
- isSocialMode && pluginStatusFilter === "disabled"
1097
- ? "all"
1098
- : pluginStatusFilter;
1099
- const effectiveSearch = pluginSearch;
1100
- const showToolbar = true;
1101
- const allowCustomOrder = !isSocialMode;
1102
- const showPluginManagementActions = !isSocialMode;
1103
-
1104
- // Load plugins on mount
1105
- useEffect(() => {
1106
- void loadPlugins();
1107
- }, [loadPlugins]);
1108
-
1109
- // Listen for install progress events via WebSocket
1110
- useEffect(() => {
1111
- const unbind = client.onWsEvent(
1112
- "install-progress",
1113
- (data: Record<string, unknown>) => {
1114
- const pluginName = data.pluginName as string;
1115
- const phase = data.phase as string;
1116
- const message = data.message as string;
1117
- if (!pluginName) return;
1118
- if (phase === "complete" || phase === "error") {
1119
- setInstallProgress((prev) => {
1120
- const next = new Map(prev);
1121
- next.delete(pluginName);
1122
- return next;
1123
- });
1124
- } else {
1125
- setInstallProgress((prev) =>
1126
- new Map(prev).set(pluginName, { phase, message }),
1127
- );
1128
- }
1129
- },
1130
- );
1131
- return unbind;
1132
- }, []);
1133
-
1134
- // Persist custom order
1135
- useEffect(() => {
1136
- if (pluginOrder.length > 0) {
1137
- localStorage.setItem("pluginOrder", JSON.stringify(pluginOrder));
1138
- }
1139
- }, [pluginOrder]);
1140
-
1141
- const [subgroupFilter, setSubgroupFilter] = useState<string>("all");
1142
- const showSubgroupFilters =
1143
- mode !== "connectors" && mode !== "streaming" && mode !== "social";
1144
- const showDesktopSubgroupSidebar = showSubgroupFilters;
1145
- const {
1146
- categoryPlugins,
1147
- enabledCount,
1148
- nonDbPlugins,
1149
- sorted,
1150
- subgroupTags,
1151
- visiblePlugins,
1152
- } = useMemo(
1153
- () =>
1154
- buildPluginListState({
1155
- allowCustomOrder,
1156
- effectiveSearch,
1157
- effectiveStatusFilter,
1158
- isConnectorLikeMode,
1159
- mode,
1160
- pluginOrder,
1161
- plugins,
1162
- showSubgroupFilters,
1163
- subgroupFilter,
1164
- }),
1165
- [
1166
- allowCustomOrder,
1167
- effectiveSearch,
1168
- effectiveStatusFilter,
1169
- isConnectorLikeMode,
1170
- mode,
1171
- pluginOrder,
1172
- plugins,
1173
- showSubgroupFilters,
1174
- subgroupFilter,
1175
- ],
1176
- );
1177
-
1178
- useEffect(() => {
1179
- if (!showSubgroupFilters) return;
1180
- if (subgroupFilter === "all") return;
1181
- if (!subgroupTags.some((tag) => tag.id === subgroupFilter)) {
1182
- setSubgroupFilter("all");
1183
- }
1184
- }, [showSubgroupFilters, subgroupFilter, subgroupTags]);
1185
-
1186
- const renderSubgroupFilterButton = useCallback(
1187
- (
1188
- tag: { id: string; label: string; count: number },
1189
- options?: { sidebar?: boolean },
1190
- ) => {
1191
- const isActive = subgroupFilter === tag.id;
1192
- if (options?.sidebar) {
1193
- const Icon = SUBGROUP_NAV_ICONS[tag.id] ?? Package;
1194
- return (
1195
- <button
1196
- key={tag.id}
1197
- type="button"
1198
- onClick={() => setSubgroupFilter(tag.id)}
1199
- aria-current={isActive ? "page" : undefined}
1200
- className={`flex w-full items-center gap-3 rounded-2xl border px-4 py-3 text-left transition-all duration-200 ${isActive
1201
- ? "border-accent/40 bg-accent/12 text-txt shadow-[0_10px_30px_rgba(var(--accent),0.08)]"
1202
- : "border-transparent text-muted hover:border-border/60 hover:bg-card/55 hover:text-txt"
1203
- }`}
1204
- >
1205
- <span
1206
- className={`flex h-10 w-10 shrink-0 items-center justify-center rounded-xl border ${isActive
1207
- ? "border-accent/30 bg-accent/18 text-txt-strong"
1208
- : "border-border/50 bg-bg-accent/80 text-muted"
1209
- }`}
1210
- >
1211
- <Icon className="w-4 h-4" />
1212
- </span>
1213
- <span className="min-w-0 flex-1">
1214
- <span className="block text-sm font-semibold leading-snug text-current">
1215
- {tag.label}
1216
- </span>
1217
- </span>
1218
- <span
1219
- className={`rounded-full border px-2 py-0.5 text-[10px] font-mono leading-none ${isActive
1220
- ? "border-accent/20 bg-accent/20 text-txt"
1221
- : "border-border/50 bg-black/10 text-muted"
1222
- }`}
1223
- >
1224
- {tag.count}
1225
- </span>
1226
- </button>
1227
- );
1228
- }
1229
-
1230
- return (
1231
- <Button
1232
- key={tag.id}
1233
- variant={isActive ? "default" : "outline"}
1234
- size="sm"
1235
- className={`h-7 px-3 text-[11px] font-bold tracking-wide rounded-lg transition-all ${isActive
1236
- ? "shadow-[0_0_10px_rgba(var(--accent),0.2)] border-accent"
1237
- : "bg-card/40 backdrop-blur-sm border-border/40 text-muted hover:text-txt shadow-sm hover:border-accent/30"
1238
- }`}
1239
- onClick={() => setSubgroupFilter(tag.id)}
1240
- >
1241
- {tag.label}
1242
- <span
1243
- className={`ml-1.5 px-1.5 py-0.5 rounded border text-[9px] font-mono leading-none ${isActive ? "bg-black/20 border-black/10" : "bg-black/10 border-white/5"}`}
1244
- >
1245
- {tag.count}
1246
- </span>
1247
- </Button>
1248
- );
1249
- },
1250
- [subgroupFilter],
1251
- );
1252
-
1253
- // ── Handlers ───────────────────────────────────────────────────────
1254
-
1255
- const toggleSettings = (pluginId: string) => {
1256
- const next = new Set<string>();
1257
- if (!pluginSettingsOpen.has(pluginId)) next.add(pluginId);
1258
- setState("pluginSettingsOpen", next);
1259
- };
1260
-
1261
- const handleParamChange = (
1262
- pluginId: string,
1263
- paramKey: string,
1264
- value: string,
1265
- ) => {
1266
- setPluginConfigs((prev) => ({
1267
- ...prev,
1268
- [pluginId]: { ...prev[pluginId], [paramKey]: value },
1269
- }));
1270
- };
1271
-
1272
- const handleConfigSave = async (pluginId: string) => {
1273
- // Showcase plugin: no-op save (it's not a real plugin)
1274
- if (pluginId === "__ui-showcase__") return;
1275
- const config = pluginConfigs[pluginId] ?? {};
1276
- await handlePluginConfigSave(pluginId, config);
1277
- setPluginConfigs((prev) => {
1278
- const next = { ...prev };
1279
- delete next[pluginId];
1280
- return next;
1281
- });
1282
- };
1283
-
1284
- const handleConfigReset = (pluginId: string) => {
1285
- setPluginConfigs((prev) => {
1286
- const next = { ...prev };
1287
- delete next[pluginId];
1288
- return next;
1289
- });
1290
- };
1291
-
1292
- const handleTestConnection = async (pluginId: string) => {
1293
- setTestResults((prev) => {
1294
- const next = new Map(prev);
1295
- next.set(pluginId, { success: false, loading: true, durationMs: 0 });
1296
- return next;
1297
- });
1298
- try {
1299
- const result = await client.testPluginConnection(pluginId);
1300
- setTestResults((prev) => {
1301
- const next = new Map(prev);
1302
- next.set(pluginId, { ...result, loading: false });
1303
- return next;
1304
- });
1305
- } catch (err) {
1306
- setTestResults((prev) => {
1307
- const next = new Map(prev);
1308
- next.set(pluginId, {
1309
- success: false,
1310
- error: err instanceof Error ? err.message : String(err),
1311
- loading: false,
1312
- durationMs: 0,
1313
- });
1314
- return next;
1315
- });
1316
- }
1317
- };
1318
-
1319
- const handleInstallPlugin = async (pluginId: string, npmName: string) => {
1320
- setInstallingPlugins((prev) => new Set(prev).add(pluginId));
1321
- try {
1322
- await client.installRegistryPlugin(npmName);
1323
- await loadPlugins();
1324
- setActionNotice(
1325
- `${npmName} installed. Restart required to activate.`,
1326
- "success",
1327
- );
1328
- } catch (err) {
1329
- setActionNotice(
1330
- `Failed to install ${npmName}: ${err instanceof Error ? err.message : "unknown error"}`,
1331
- "error",
1332
- 3800,
1333
- );
1334
- // Still try to refresh in case install succeeded but restart failed
1335
- try {
1336
- await loadPlugins();
1337
- } catch {
1338
- /* ignore */
1339
- }
1340
- } finally {
1341
- setInstallingPlugins((prev) => {
1342
- const next = new Set(prev);
1343
- next.delete(pluginId);
1344
- return next;
1345
- });
1346
- }
1347
- };
1348
-
1349
- const handleTogglePlugin = useCallback(
1350
- async (pluginId: string, enabled: boolean) => {
1351
- let shouldStart = false;
1352
- setTogglingPlugins((prev) => {
1353
- if (prev.has(pluginId) || prev.size > 0) return prev;
1354
- shouldStart = true;
1355
- return new Set(prev).add(pluginId);
1356
- });
1357
- if (!shouldStart) return;
1358
-
1359
- try {
1360
- await handlePluginToggle(pluginId, enabled);
1361
- } finally {
1362
- setTogglingPlugins((prev) => {
1363
- const next = new Set(prev);
1364
- next.delete(pluginId);
1365
- return next;
1366
- });
1367
- }
1368
- },
1369
- [handlePluginToggle],
1370
- );
1371
-
1372
- const handleOpenPluginExternalUrl = useCallback(
1373
- async (url: string) => {
1374
- try {
1375
- await openExternalUrl(url);
1376
- } catch (err) {
1377
- setActionNotice(
1378
- err instanceof Error ? err.message : "Failed to open external link.",
1379
- "error",
1380
- 4200,
1381
- );
1382
- }
1383
- },
1384
- [setActionNotice],
1385
- );
1386
-
1387
- // ── Add from directory ──────────────────────────────────────────────
1388
-
1389
- const handleAddFromDirectory = async () => {
1390
- const trimmed = addDirPath.trim();
1391
- if (!trimmed) return;
1392
- setAddDirLoading(true);
1393
- try {
1394
- await client.installRegistryPlugin(trimmed);
1395
- await loadPlugins();
1396
- setAddDirPath("");
1397
- setAddDirOpen(false);
1398
- setActionNotice(`Plugin installed from ${trimmed}`, "success");
1399
- } catch (err) {
1400
- setActionNotice(
1401
- `Failed to add plugin: ${err instanceof Error ? err.message : "unknown error"}`,
1402
- "error",
1403
- 3800,
1404
- );
1405
- }
1406
- setAddDirLoading(false);
1407
- };
1408
-
1409
- // ── Drag-to-reorder handlers ─────────────────────────────────────
1410
-
1411
- const handleDragStart = useCallback(
1412
- (e: React.DragEvent, pluginId: string) => {
1413
- dragRef.current = pluginId;
1414
- setDraggingId(pluginId);
1415
- e.dataTransfer.effectAllowed = "move";
1416
- e.dataTransfer.setData("text/plain", pluginId);
1417
- },
1418
- [],
1419
- );
1420
-
1421
- const handleDragOver = useCallback((e: React.DragEvent, pluginId: string) => {
1422
- e.preventDefault();
1423
- e.dataTransfer.dropEffect = "move";
1424
- if (dragRef.current && dragRef.current !== pluginId) {
1425
- setDragOverId(pluginId);
1426
- }
1427
- }, []);
1428
-
1429
- const handleDrop = useCallback(
1430
- (e: React.DragEvent, targetId: string) => {
1431
- e.preventDefault();
1432
- const srcId = dragRef.current;
1433
- if (!srcId || srcId === targetId) {
1434
- dragRef.current = null;
1435
- setDraggingId(null);
1436
- setDragOverId(null);
1437
- return;
1438
- }
1439
- // Materialize current sorted order, then splice
1440
- if (!allowCustomOrder) return;
1441
- setPluginOrder(() => {
1442
- // Build full order: items in custom order first, then any new ones
1443
- const allIds = nonDbPlugins.map((p: PluginInfo) => p.id);
1444
- let ids: string[];
1445
- if (pluginOrder.length > 0) {
1446
- const known = new Set(pluginOrder);
1447
- ids = [...pluginOrder, ...allIds.filter((id) => !known.has(id))];
1448
- } else {
1449
- ids = sorted.map((p: PluginInfo) => p.id);
1450
- // Pad with any nonDbPlugins not currently in sorted (due to filters)
1451
- const inSorted = new Set(ids);
1452
- for (const id of allIds) {
1453
- if (!inSorted.has(id)) ids.push(id);
1454
- }
1455
- }
1456
- const fromIdx = ids.indexOf(srcId);
1457
- const toIdx = ids.indexOf(targetId);
1458
- if (fromIdx === -1 || toIdx === -1) return ids;
1459
- ids.splice(fromIdx, 1);
1460
- ids.splice(toIdx, 0, srcId);
1461
- return ids;
1462
- });
1463
- dragRef.current = null;
1464
- setDraggingId(null);
1465
- setDragOverId(null);
1466
- },
1467
- [allowCustomOrder, nonDbPlugins, pluginOrder, sorted],
1468
- );
1469
-
1470
- const handleDragEnd = useCallback(() => {
1471
- dragRef.current = null;
1472
- setDraggingId(null);
1473
- setDragOverId(null);
1474
- }, []);
1475
-
1476
- const handleResetOrder = useCallback(() => {
1477
- setPluginOrder([]);
1478
- localStorage.removeItem("pluginOrder");
1479
- }, []);
1480
-
1481
- const renderResolvedIcon = useCallback(
1482
- (
1483
- plugin: PluginInfo,
1484
- options?: {
1485
- className?: string;
1486
- emojiClassName?: string;
1487
- },
1488
- ) => {
1489
- const icon = resolveIcon(plugin);
1490
- if (!icon) {
1491
- return <span className={options?.emojiClassName ?? "text-sm"}>🧩</span>;
1492
- }
1493
- if (typeof icon === "string") {
1494
- const imageSrc = iconImageSource(icon);
1495
- return imageSrc ? (
1496
- <img
1497
- src={imageSrc}
1498
- alt=""
1499
- className={
1500
- options?.className ?? "w-5 h-5 rounded-sm object-contain"
1501
- }
1502
- onError={(e) => {
1503
- (e.currentTarget as HTMLImageElement).style.display = "none";
1504
- }}
1505
- />
1506
- ) : (
1507
- <span className={options?.emojiClassName ?? "text-sm"}>{icon}</span>
1508
- );
1509
- }
1510
- const IconComponent = icon;
1511
- return <IconComponent className={options?.className ?? "w-5 h-5"} />;
1512
- },
1513
- [],
1514
- );
1515
-
1516
- // ── Card renderers ────────────────────────────────────────────────
1517
-
1518
- const renderPluginCard = (p: PluginInfo) => {
1519
- const hasParams = p.parameters && p.parameters.length > 0;
1520
- const isOpen = pluginSettingsOpen.has(p.id);
1521
- const setCount = hasParams
1522
- ? p.parameters.filter((param: PluginParamDef) => param.isSet).length
1523
- : 0;
1524
- const totalCount = hasParams ? p.parameters.length : 0;
1525
- const allParamsSet = !hasParams || setCount === totalCount;
1526
- const isShowcase = p.id === "__ui-showcase__";
1527
- const categoryLabel = isShowcase
1528
- ? "showcase"
1529
- : p.category === "ai-provider"
1530
- ? "ai provider"
1531
- : p.category;
1532
-
1533
- const enabledBorder = isShowcase
1534
- ? "border-l-[3px] border-l-accent"
1535
- : p.enabled
1536
- ? !allParamsSet && hasParams
1537
- ? "border-l-[3px] border-l-warn"
1538
- : "border-l-[3px] border-l-accent"
1539
- : "";
1540
- const isToggleBusy = togglingPlugins.has(p.id);
1541
- const toggleDisabled =
1542
- isToggleBusy || (hasPluginToggleInFlight && !isToggleBusy);
1543
-
1544
- const isDragging = draggingId === p.id;
1545
- const isDragOver = dragOverId === p.id && draggingId !== p.id;
1546
- const pluginLinks = getPluginResourceLinks(p);
1547
-
1548
- return (
1549
- <li
1550
- key={p.id}
1551
- draggable={allowCustomOrder}
1552
- onDragStart={
1553
- allowCustomOrder ? (e) => handleDragStart(e, p.id) : undefined
1554
- }
1555
- onDragOver={
1556
- allowCustomOrder ? (e) => handleDragOver(e, p.id) : undefined
1557
- }
1558
- onDrop={allowCustomOrder ? (e) => handleDrop(e, p.id) : undefined}
1559
- onDragEnd={allowCustomOrder ? handleDragEnd : undefined}
1560
- className={`border border-border bg-card transition-colors duration-150 flex flex-col ${enabledBorder} ${isOpen ? "ring-1 ring-accent" : "hover:border-accent/40"
1561
- } ${isDragging ? "opacity-30" : ""} ${isDragOver ? "ring-2 ring-accent/60" : ""}`}
1562
- data-plugin-id={p.id}
1563
- >
1564
- {/* Top: drag handle + icon + name + toggle */}
1565
- <div className="flex items-center gap-2 px-3 pt-3 pb-1">
1566
- {allowCustomOrder && (
1567
- <span
1568
- className="text-[10px] text-muted opacity-30 hover:opacity-70 cursor-grab active:cursor-grabbing shrink-0 select-none leading-none"
1569
- title={t("pluginsview.DragToReorder")}
1570
- >
1571
- {t("pluginsview.X2807")}
1572
- </span>
1573
- )}
1574
- <span className="font-bold text-sm flex items-center gap-1.5 min-w-0 truncate flex-1">
1575
- {(() => {
1576
- const icon = resolveIcon(p);
1577
- if (!icon) return null;
1578
- if (typeof icon === "string") {
1579
- const imageSrc = iconImageSource(icon);
1580
- return imageSrc ? (
1581
- <img
1582
- src={imageSrc}
1583
- alt=""
1584
- className="w-5 h-5 rounded-sm object-contain"
1585
- onError={(e) => {
1586
- (e.currentTarget as HTMLImageElement).style.display =
1587
- "none";
1588
- }}
1589
- />
1590
- ) : (
1591
- <span className="text-sm">{icon}</span>
1592
- );
1593
- }
1594
- const IconComponent = icon;
1595
- return <IconComponent className="w-5 h-5" />;
1596
- })()}
1597
- {p.name}
1598
- </span>
1599
- {isShowcase ? (
1600
- <span className="text-[10px] font-bold tracking-wider px-2.5 py-[2px] border border-accent text-txt bg-accent-subtle shrink-0">
1601
- {t("pluginsview.DEMO")}
1602
- </span>
1603
- ) : (
1604
- <button
1605
- type="button"
1606
- data-plugin-toggle={p.id}
1607
- className={`text-[10px] font-bold tracking-wider px-2.5 py-[2px] border transition-colors duration-150 shrink-0 ${p.enabled
1608
- ? "bg-accent text-accent-fg border-accent"
1609
- : "bg-transparent text-muted border-border hover:text-txt"
1610
- } ${toggleDisabled
1611
- ? "opacity-60 cursor-not-allowed"
1612
- : "cursor-pointer"
1613
- }`}
1614
- onClick={(e) => {
1615
- e.stopPropagation();
1616
- void handleTogglePlugin(p.id, !p.enabled);
1617
- }}
1618
- disabled={toggleDisabled}
1619
- >
1620
- {isToggleBusy ? "APPLYING" : p.enabled ? "ON" : "OFF"}
1621
- </button>
1622
- )}
1623
- </div>
1624
-
1625
- {/* Badges: category + version + loaded status */}
1626
- <div className="flex items-center gap-1.5 px-3 pb-1.5">
1627
- <span className="text-[10px] px-1.5 py-px border border-border bg-surface text-muted lowercase tracking-wide whitespace-nowrap">
1628
- {categoryLabel}
1629
- </span>
1630
- {p.version && (
1631
- <span className="text-[10px] font-mono text-muted opacity-70">
1632
- v{p.version}
1633
- </span>
1634
- )}
1635
- {p.enabled && !p.isActive && !isShowcase && (
1636
- <span
1637
- className={`text-[10px] px-1.5 py-px border lowercase tracking-wide whitespace-nowrap ${p.loadError
1638
- ? "border-destructive bg-[rgba(153,27,27,0.04)] text-destructive"
1639
- : "border-warn bg-[rgba(234,179,8,0.06)] text-warn"
1640
- }`}
1641
- title={
1642
- p.loadError || "Plugin is enabled but not loaded in the runtime"
1643
- }
1644
- >
1645
- {p.loadError ? "load failed" : "not installed"}
1646
- </span>
1647
- )}
1648
- {isToggleBusy && (
1649
- <span className="text-[10px] px-1.5 py-px border border-accent bg-accent-subtle text-txt lowercase tracking-wide whitespace-nowrap">
1650
- {t("pluginsview.restarting")}
1651
- </span>
1652
- )}
1653
- </div>
1654
-
1655
- {/* Description — clamped to 3 lines */}
1656
- <p
1657
- className="text-xs text-muted px-3 pb-2 flex-1"
1658
- style={{
1659
- display: "-webkit-box",
1660
- WebkitLineClamp: 3,
1661
- WebkitBoxOrient: "vertical",
1662
- overflow: "hidden",
1663
- }}
1664
- >
1665
- {p.description || "No description available"}
1666
- </p>
1667
-
1668
- {(p.tags?.length ?? 0) > 0 && (
1669
- <div className="flex flex-wrap gap-1.5 px-3 pb-2">
1670
- {p.tags?.slice(0, 4).map((tag) => (
1671
- <span
1672
- key={`${p.id}:${tag}`}
1673
- className="text-[10px] px-1.5 py-px border border-border/50 bg-black/10 text-muted lowercase tracking-wide whitespace-nowrap"
1674
- >
1675
- {tag}
1676
- </span>
1677
- ))}
1678
- </div>
1679
- )}
1680
-
1681
- {pluginLinks.length > 0 && (
1682
- <div className="flex flex-wrap gap-2 px-3 pb-2">
1683
- {pluginLinks.map((link) => (
1684
- <Button
1685
- key={`${p.id}:${link.key}`}
1686
- variant="outline"
1687
- size="sm"
1688
- className="h-6 px-2 text-[10px] font-bold border-border/40 text-muted hover:text-txt hover:border-accent hover:bg-accent/5 backdrop-blur-sm transition-all"
1689
- onClick={(e) => {
1690
- e.stopPropagation();
1691
- void handleOpenPluginExternalUrl(link.url);
1692
- }}
1693
- title={`${link.label}: ${link.url}`}
1694
- >
1695
- {link.label}
1696
- </Button>
1697
- ))}
1698
- </div>
1699
- )}
1700
-
1701
- {/* Bottom bar: config status + settings button */}
1702
- <div className="flex items-center gap-3 px-4 py-3 border-t border-border/40 mt-auto bg-black/5">
1703
- {hasParams && !isShowcase ? (
1704
- <>
1705
- <span
1706
- className={`inline-block w-2 h-2 rounded-full shadow-[0_0_10px_currentColor] shrink-0 ${allParamsSet
1707
- ? "bg-ok text-ok"
1708
- : "bg-destructive text-destructive"
1709
- }`}
1710
- />
1711
- <span className="text-[11px] font-bold tracking-wide text-muted">
1712
- {setCount}/{totalCount} {t("pluginsview.configured")}
1713
- </span>
1714
- </>
1715
- ) : !hasParams && !isShowcase ? (
1716
- <span className="text-[11px] font-bold tracking-wide text-muted/60">
1717
- {t("pluginsview.NoConfigNeeded")}
1718
- </span>
1719
- ) : (
1720
- <span className="text-[11px] font-bold tracking-wide text-muted/60">
1721
- {t("pluginsview.23FieldDemos")}
1722
- </span>
1723
- )}
1724
- <div className="flex-1" />
1725
- {p.enabled &&
1726
- !p.isActive &&
1727
- p.npmName &&
1728
- !isShowcase &&
1729
- !p.loadError && (
1730
- <Button
1731
- variant="default"
1732
- size="sm"
1733
- className="h-7 px-3 text-[10px] font-bold tracking-wide shadow-sm max-w-[140px] truncate"
1734
- disabled={installingPlugins.has(p.id)}
1735
- onClick={(e) => {
1736
- e.stopPropagation();
1737
- handleInstallPlugin(p.id, p.npmName ?? "");
1738
- }}
1739
- >
1740
- {installingPlugins.has(p.id)
1741
- ? installProgress.get(p.npmName ?? "")?.message ||
1742
- "Installing..."
1743
- : "Install"}
1744
- </Button>
1745
- )}
1746
- {hasParams && (
1747
- <Button
1748
- variant="ghost"
1749
- size="sm"
1750
- className={`h-7 px-2.5 text-[11px] font-bold transition-all flex items-center gap-1.5 ${isOpen
1751
- ? "text-txt bg-accent/10 hover:bg-accent/20"
1752
- : "text-muted hover:text-txt hover:bg-white/5"
1753
- }`}
1754
- onClick={(e) => {
1755
- e.stopPropagation();
1756
- toggleSettings(p.id);
1757
- }}
1758
- title={t("pluginsview.Settings")}
1759
- >
1760
- <span className="text-[14px] leading-none">&#9881;</span>
1761
- <span
1762
- className={`inline-block text-[10px] transition-transform duration-200 ${isOpen ? "rotate-90" : ""}`}
1763
- >
1764
- &#9654;
1765
- </span>
1766
- </Button>
1767
- )}
1768
- </div>
1769
-
1770
- {/* Validation errors */}
1771
- {p.enabled && p.validationErrors && p.validationErrors.length > 0 && (
1772
- <div className="px-3 py-1.5 border-t border-destructive bg-[rgba(153,27,27,0.04)] text-xs">
1773
- {p.validationErrors.map(
1774
- (err: { field: string; message: string }) => (
1775
- <div
1776
- key={`${err.field}:${err.message}`}
1777
- className="text-destructive mb-0.5 text-[10px]"
1778
- >
1779
- {err.field}: {err.message}
1780
- </div>
1781
- ),
1782
- )}
1783
- </div>
1784
- )}
1785
-
1786
- {/* Validation warnings */}
1787
- {p.enabled &&
1788
- p.validationWarnings &&
1789
- p.validationWarnings.length > 0 && (
1790
- <div className="px-3 py-1">
1791
- {p.validationWarnings.map(
1792
- (w: { field: string; message: string }) => (
1793
- <div
1794
- key={`${w.field}:${w.message}`}
1795
- className="text-warn text-[10px]"
1796
- >
1797
- {w.message}
1798
- </div>
1799
- ),
1800
- )}
1801
- </div>
1802
- )}
1803
- </li>
1804
- );
1805
- };
1806
-
1807
- /** Render a grid of plugin cards. */
1808
- const renderPluginGrid = (plugins: PluginInfo[]) => (
1809
- <ul className="grid grid-cols-[repeat(auto-fill,minmax(260px,1fr))] gap-3 m-0 p-0 list-none">
1810
- {plugins.map((p: PluginInfo) => renderPluginCard(p))}
1811
- </ul>
1812
- );
1813
-
1814
- // Resolve the plugin whose settings dialog is currently open.
1815
- // Exclude ai-provider plugins — those are configured in Settings.
1816
- const settingsDialogPlugin =
1817
- Array.from(pluginSettingsOpen)
1818
- .map((id) => nonDbPlugins.find((plugin) => plugin.id === id) ?? null)
1819
- .find((plugin) => (plugin?.parameters?.length ?? 0) > 0) ?? null;
1820
-
1821
- // ── Game-modal state ──────────────────────────────────────────────
1822
- const [gameSelectedId, setGameSelectedId] = useState<string | null>(null);
1823
- const [gameMobileDetail, setGameMobileDetail] = useState(false);
1824
- const gameNarrow =
1825
- typeof window !== "undefined" && typeof window.matchMedia === "function"
1826
- ? window.matchMedia("(max-width: 600px)").matches
1827
- : false;
1828
- const [connectorExpandedIds, setConnectorExpandedIds] = useState<Set<string>>(
1829
- () => new Set(),
1830
- );
1831
- const [connectorSelectedId, setConnectorSelectedId] = useState<string | null>(
1832
- null,
1833
- );
1834
- const [desktopConnectorLayout, setDesktopConnectorLayout] = useState(() =>
1835
- typeof window !== "undefined" && typeof window.matchMedia === "function"
1836
- ? window.matchMedia("(min-width: 1024px)").matches
1837
- : false,
1838
- );
1839
- const connectorSectionRefs = useRef<Record<string, HTMLElement | null>>({});
1840
-
1841
- // Auto-select first visible plugin in game modal
1842
- const gameVisiblePlugins = visiblePlugins.filter(
1843
- (p: PluginInfo) => p.id !== "__ui-showcase__",
1844
- );
1845
- const effectiveGameSelected = gameVisiblePlugins.find(
1846
- (p: PluginInfo) => p.id === gameSelectedId,
1847
- )
1848
- ? gameSelectedId
1849
- : (gameVisiblePlugins[0]?.id ?? null);
1850
- const selectedPlugin =
1851
- gameVisiblePlugins.find(
1852
- (p: PluginInfo) => p.id === effectiveGameSelected,
1853
- ) ?? null;
1854
- const selectedPluginLinks = selectedPlugin
1855
- ? getPluginResourceLinks(selectedPlugin)
1856
- : [];
1857
-
1858
- useEffect(() => {
1859
- if (!isSocialMode || !inModal) return;
1860
- if (pluginStatusFilter !== "disabled") return;
1861
- setState("pluginStatusFilter", "all");
1862
- }, [inModal, isSocialMode, pluginStatusFilter, setState]);
1863
-
1864
- useEffect(() => {
1865
- if (!isSocialMode || !inModal) return;
1866
- if (
1867
- typeof window === "undefined" ||
1868
- typeof window.matchMedia !== "function"
1869
- )
1870
- return;
1871
-
1872
- const media = window.matchMedia("(min-width: 1024px)");
1873
- const syncLayout = () => {
1874
- setDesktopConnectorLayout(media.matches);
1875
- };
1876
-
1877
- syncLayout();
1878
- if (typeof media.addEventListener === "function") {
1879
- media.addEventListener("change", syncLayout);
1880
- return () => media.removeEventListener("change", syncLayout);
1881
- }
1882
-
1883
- media.addListener(syncLayout);
1884
- return () => media.removeListener(syncLayout);
1885
- }, [inModal, isSocialMode]);
1886
-
1887
- useEffect(() => {
1888
- if (!isSocialMode || !inModal) return;
1889
- if (visiblePlugins.length === 0) {
1890
- setConnectorSelectedId(null);
1891
- setConnectorExpandedIds(new Set());
1892
- return;
1893
- }
1894
-
1895
- setConnectorSelectedId((prev) => {
1896
- if (visiblePlugins.some((plugin) => plugin.id === prev)) {
1897
- return prev;
1898
- }
1899
- return desktopConnectorLayout ? (visiblePlugins[0]?.id ?? null) : null;
1900
- });
1901
- }, [desktopConnectorLayout, inModal, isSocialMode, visiblePlugins]);
1902
-
1903
- useEffect(() => {
1904
- if (!isSocialMode || !inModal || !desktopConnectorLayout) return;
1905
- if (!connectorSelectedId) return;
1906
- setConnectorExpandedIds(new Set([connectorSelectedId]));
1907
- }, [connectorSelectedId, desktopConnectorLayout, inModal, isSocialMode]);
1908
-
1909
- useEffect(() => {
1910
- if (!isSocialMode || !inModal || desktopConnectorLayout) return;
1911
- setConnectorExpandedIds(new Set());
1912
- }, [desktopConnectorLayout, inModal, isSocialMode]);
1913
-
1914
- const scrollConnectorIntoView = useCallback((pluginId: string) => {
1915
- const element = connectorSectionRefs.current[pluginId];
1916
- if (element && typeof element.scrollIntoView === "function") {
1917
- element.scrollIntoView({ behavior: "smooth", block: "start" });
1918
- }
1919
- }, []);
1920
-
1921
- const handleConnectorSelect = useCallback(
1922
- (pluginId: string) => {
1923
- setConnectorSelectedId(pluginId);
1924
- setConnectorExpandedIds((prev) => {
1925
- if (desktopConnectorLayout) {
1926
- return new Set([pluginId]);
1927
- }
1928
- const next = new Set(prev);
1929
- next.add(pluginId);
1930
- return next;
1931
- });
1932
- scrollConnectorIntoView(pluginId);
1933
- },
1934
- [desktopConnectorLayout, scrollConnectorIntoView],
1935
- );
1936
-
1937
- const handleConnectorSectionToggle = useCallback(
1938
- (pluginId: string) => {
1939
- setConnectorSelectedId(pluginId);
1940
- let shouldScroll = false;
1941
- setConnectorExpandedIds((prev) => {
1942
- if (desktopConnectorLayout) {
1943
- // Accordion: toggle off if already open, otherwise open this one only
1944
- if (prev.has(pluginId)) return new Set();
1945
- shouldScroll = true;
1946
- return new Set([pluginId]);
1947
- }
1948
- const next = new Set(prev);
1949
- if (next.has(pluginId)) next.delete(pluginId);
1950
- else next.add(pluginId);
1951
- return next;
1952
- });
1953
- if (desktopConnectorLayout && shouldScroll) {
1954
- scrollConnectorIntoView(pluginId);
1955
- }
1956
- },
1957
- [desktopConnectorLayout, scrollConnectorIntoView],
1958
- );
1959
-
1960
- // ── Game-modal render ─────────────────────────────────────────────
1961
- if (inModal && isSocialMode) {
1962
- return (
1963
- <div
1964
- data-testid="plugins-view-social"
1965
- className={`flex min-h-full min-w-0 w-full flex-col bg-bg ${desktopConnectorLayout ? "md:flex-row" : ""
1966
- }`}
1967
- >
1968
- {desktopConnectorLayout && (
1969
- <aside
1970
- data-testid="connectors-settings-sidebar"
1971
- className="flex w-[22rem] shrink-0 border-r border-border/50 bg-bg/35 backdrop-blur-xl"
1972
- >
1973
- <div className="flex min-h-full flex-1 flex-col sticky top-0 max-h-screen">
1974
- <div className="border-b border-border/40 px-5 py-5 text-center">
1975
- <div className="text-[11px] font-semibold uppercase tracking-[0.18em] text-muted/80">
1976
- Connectors
1977
- </div>
1978
- <div className="mt-2 text-sm text-muted">
1979
- {enabledCount} enabled of {categoryPlugins.length}
1980
- </div>
1981
- </div>
1982
- <nav className="flex-1 space-y-2 overflow-y-auto px-4 py-4">
1983
- {(desktopConnectorLayout
1984
- ? visiblePlugins.filter((plugin) => {
1985
- return plugin.id === connectorSelectedId;
1986
- })
1987
- : visiblePlugins
1988
- ).map((plugin) => {
1989
- const isSelected = connectorSelectedId === plugin.id;
1990
- const isExpanded = connectorExpandedIds.has(plugin.id);
1991
- const isToggleBusy = togglingPlugins.has(plugin.id);
1992
- const toggleDisabled =
1993
- isToggleBusy || (hasPluginToggleInFlight && !isToggleBusy);
1994
-
1995
- return (
1996
- <div
1997
- key={plugin.id}
1998
- className={`flex items-center gap-2 rounded-2xl border px-3 py-2 transition-all ${isSelected
1999
- ? "border-accent/40 bg-accent/10 text-txt shadow-[0_10px_30px_rgba(var(--accent),0.08)]"
2000
- : "border-transparent bg-transparent text-muted hover:border-border/60 hover:bg-card/55 hover:text-txt"
2001
- }`}
2002
- >
2003
- <button
2004
- type="button"
2005
- className="flex min-w-0 flex-1 items-center gap-3 text-left"
2006
- onClick={() => handleConnectorSelect(plugin.id)}
2007
- aria-current={isSelected ? "page" : undefined}
2008
- >
2009
- <span
2010
- className={`flex h-8 w-8 shrink-0 items-center justify-center rounded-xl border p-1.5 ${isSelected
2011
- ? "border-accent/30 bg-accent/18 text-txt-strong"
2012
- : "border-border/50 bg-bg-accent/80 text-muted"
2013
- }`}
2014
- >
2015
- {renderResolvedIcon(plugin, {
2016
- className:
2017
- "h-4 w-4 shrink-0 rounded-sm object-contain",
2018
- emojiClassName: "text-sm",
2019
- })}
2020
- </span>
2021
- <span className="min-w-0 flex-1 truncate text-sm font-semibold leading-none">
2022
- {plugin.name}
2023
- </span>
2024
- </button>
2025
- <button
2026
- type="button"
2027
- className={`shrink-0 rounded-full border px-2.5 py-1 text-[10px] font-bold tracking-[0.16em] transition-colors ${plugin.enabled
2028
- ? "border-accent bg-accent text-accent-fg"
2029
- : "border-border bg-transparent text-muted hover:border-accent/40 hover:text-txt"
2030
- } ${toggleDisabled
2031
- ? "cursor-not-allowed opacity-60"
2032
- : "cursor-pointer"
2033
- }`}
2034
- onClick={() =>
2035
- void handleTogglePlugin(plugin.id, !plugin.enabled)
2036
- }
2037
- disabled={toggleDisabled}
2038
- >
2039
- {isToggleBusy ? "..." : plugin.enabled ? "ON" : "OFF"}
2040
- </button>
2041
- <span
2042
- className={`shrink-0 text-muted transition-transform ${isExpanded ? "rotate-90" : ""
2043
- }`}
2044
- >
2045
- <ChevronRight className="h-4 w-4" />
2046
- </span>
2047
- </div>
2048
- );
2049
- })}
2050
- </nav>
2051
- </div>
2052
- </aside>
2053
- )}
2054
-
2055
- <div className="min-w-0 flex-1">
2056
- <div className="sticky top-0 z-20 border-b border-border/50 bg-bg/85 px-4 py-4 shadow-[0_12px_30px_rgba(0,0,0,0.14)] backdrop-blur-xl sm:px-6 lg:px-8">
2057
- <div className="mx-auto max-w-5xl">
2058
- <div className="flex flex-col gap-3 sm:flex-row sm:items-center">
2059
- <Input
2060
- type="text"
2061
- className="h-11 w-full rounded-xl border-border/60 bg-card/70 text-sm shadow-sm"
2062
- placeholder="Search connectors..."
2063
- value={pluginSearch}
2064
- onChange={(e) => setState("pluginSearch", e.target.value)}
2065
- />
2066
- <div className="flex shrink-0 gap-1.5 rounded-xl border border-white/5 bg-black/10 p-1">
2067
- {(["all", "enabled"] as const).map((status) => (
2068
- <Button
2069
- key={status}
2070
- variant={
2071
- effectiveStatusFilter === status ? "default" : "ghost"
2072
- }
2073
- size="sm"
2074
- className={`h-8 px-3 text-[11px] font-bold tracking-wide transition-all ${effectiveStatusFilter === status
2075
- ? "shadow-sm"
2076
- : "text-muted hover:bg-white/5 hover:text-txt"
2077
- }`}
2078
- onClick={() =>
2079
- setState("pluginStatusFilter", status as StatusFilter)
2080
- }
2081
- >
2082
- {status === "all"
2083
- ? `All (${categoryPlugins.length})`
2084
- : `Enabled (${enabledCount})`}
2085
- </Button>
2086
- ))}
2087
- </div>
2088
- </div>
2089
- </div>
2090
- </div>
2091
-
2092
- <div className="mx-auto max-w-5xl px-4 py-4 sm:px-6 sm:py-5 lg:px-8 lg:py-6">
2093
- {hasPluginToggleInFlight && (
2094
- <div className="mb-4 rounded-2xl border border-accent bg-accent-subtle px-4 py-3 text-[11px] text-txt">
2095
- {t("pluginsview.ApplyingPluginChan")}
2096
- </div>
2097
- )}
2098
-
2099
- {visiblePlugins.length === 0 ? (
2100
- <div className="rounded-2xl border border-dashed border-border px-5 py-10 text-center text-muted">
2101
- {effectiveSearch
2102
- ? "No connectors match your search."
2103
- : "No connectors match your filters."}
2104
- </div>
2105
- ) : (
2106
- <div
2107
- data-testid="connectors-settings-content"
2108
- className="space-y-4"
2109
- >
2110
- {(desktopConnectorLayout
2111
- ? visiblePlugins.filter((p) => p.id === connectorSelectedId)
2112
- : visiblePlugins
2113
- ).map((plugin) => {
2114
- const hasParams =
2115
- (plugin.parameters?.length ?? 0) > 0 &&
2116
- plugin.id !== "__ui-showcase__";
2117
- const isExpanded = connectorExpandedIds.has(plugin.id);
2118
- const isSelected = connectorSelectedId === plugin.id;
2119
- const setCount = hasParams
2120
- ? plugin.parameters.filter((param) => param.isSet).length
2121
- : 0;
2122
- const totalCount = hasParams ? plugin.parameters.length : 0;
2123
- const allParamsSet = !hasParams || setCount === totalCount;
2124
- const isToggleBusy = togglingPlugins.has(plugin.id);
2125
- const toggleDisabled =
2126
- isToggleBusy || (hasPluginToggleInFlight && !isToggleBusy);
2127
- const isSaving = pluginSaving.has(plugin.id);
2128
- const saveSuccess = pluginSaveSuccess.has(plugin.id);
2129
- const testResult = testResults.get(plugin.id);
2130
- const pluginLinks = getPluginResourceLinks(plugin);
2131
-
2132
- return (
2133
- <section
2134
- key={plugin.id}
2135
- ref={(element) => {
2136
- connectorSectionRefs.current[plugin.id] = element;
2137
- }}
2138
- data-testid={`connector-section-${plugin.id}`}
2139
- className={`overflow-hidden rounded-[1.4rem] border bg-card/90 shadow-sm transition-all ${isSelected
2140
- ? "border-accent/35 shadow-[0_18px_40px_rgba(var(--accent),0.08)]"
2141
- : "border-border/50"
2142
- }`}
2143
- >
2144
- <div className="flex items-start gap-3 px-4 py-4 sm:px-5">
2145
- <button
2146
- type="button"
2147
- data-testid={`connector-header-${plugin.id}`}
2148
- className="flex min-w-0 flex-1 items-start gap-3 text-left"
2149
- onClick={() =>
2150
- handleConnectorSectionToggle(plugin.id)
2151
- }
2152
- >
2153
- <span
2154
- className={`mt-0.5 flex h-11 w-11 shrink-0 items-center justify-center rounded-2xl border p-2.5 ${isSelected
2155
- ? "border-accent/30 bg-accent/18 text-txt-strong"
2156
- : "border-border/50 bg-bg-accent/80 text-muted"
2157
- }`}
2158
- >
2159
- {renderResolvedIcon(plugin, {
2160
- className:
2161
- "h-4 w-4 shrink-0 rounded-sm object-contain",
2162
- emojiClassName: "text-base",
2163
- })}
2164
- </span>
2165
- <span className="min-w-0 flex-1">
2166
- <span className="flex min-w-0 flex-wrap items-center gap-2">
2167
- <span className="truncate text-sm font-semibold text-txt">
2168
- {plugin.name}
2169
- </span>
2170
- <span
2171
- className={`rounded-full border px-2 py-0.5 text-[10px] font-semibold uppercase tracking-[0.14em] ${allParamsSet
2172
- ? "border-ok/30 bg-ok/10 text-ok"
2173
- : "border-warn/30 bg-warn/10 text-warn"
2174
- }`}
2175
- >
2176
- {allParamsSet ? "Ready" : "Needs setup"}
2177
- </span>
2178
- {plugin.version && (
2179
- <span className="text-[11px] font-mono text-muted/80">
2180
- v{plugin.version}
2181
- </span>
2182
- )}
2183
- </span>
2184
- <span className="mt-1 block text-sm text-muted">
2185
- {plugin.description || "No description available"}
2186
- </span>
2187
- <span className="mt-2 flex flex-wrap items-center gap-2 text-[11px] text-muted">
2188
- <span>
2189
- {hasParams
2190
- ? `${setCount}/${totalCount} configured`
2191
- : "No configuration needed"}
2192
- </span>
2193
- {plugin.enabled && !plugin.isActive && (
2194
- <span
2195
- className={`rounded-full border px-2 py-0.5 ${plugin.loadError
2196
- ? "border-danger/30 bg-danger/10 text-danger"
2197
- : "border-warn/30 bg-warn/10 text-warn"
2198
- }`}
2199
- >
2200
- {plugin.loadError
2201
- ? "Load failed"
2202
- : "Not installed"}
2203
- </span>
2204
- )}
2205
- </span>
2206
- </span>
2207
- </button>
2208
-
2209
- <div className="flex shrink-0 items-center gap-2">
2210
- <button
2211
- type="button"
2212
- className={`rounded-full border px-3 py-1.5 text-[10px] font-bold tracking-[0.16em] transition-colors ${plugin.enabled
2213
- ? "border-accent bg-accent text-accent-fg"
2214
- : "border-border bg-transparent text-muted hover:border-accent/40 hover:text-txt"
2215
- } ${toggleDisabled
2216
- ? "cursor-not-allowed opacity-60"
2217
- : "cursor-pointer"
2218
- }`}
2219
- onClick={() =>
2220
- void handleTogglePlugin(
2221
- plugin.id,
2222
- !plugin.enabled,
2223
- )
2224
- }
2225
- disabled={toggleDisabled}
2226
- >
2227
- {isToggleBusy
2228
- ? "..."
2229
- : plugin.enabled
2230
- ? "ON"
2231
- : "OFF"}
2232
- </button>
2233
- <button
2234
- type="button"
2235
- className={`flex items-center gap-1 rounded-full border px-3 py-1.5 text-[11px] font-semibold transition-colors ${isExpanded
2236
- ? "border-accent/40 bg-accent/10 text-txt"
2237
- : "border-border/50 text-muted hover:border-accent/40 hover:text-txt"
2238
- }`}
2239
- onClick={() =>
2240
- handleConnectorSectionToggle(plugin.id)
2241
- }
2242
- aria-expanded={isExpanded}
2243
- aria-label={`${isExpanded ? "Collapse" : "Expand"} ${plugin.name}`}
2244
- >
2245
- <span>{isExpanded ? "Collapse" : "Expand"}</span>
2246
- <ChevronRight
2247
- className={`h-4 w-4 transition-transform ${isExpanded ? "rotate-90" : ""
2248
- }`}
2249
- />
2250
- </button>
2251
- </div>
2252
- </div>
2253
-
2254
- {isExpanded && (
2255
- <div className="border-t border-border/40 bg-black/5 px-4 py-4 sm:px-5">
2256
- {plugin.validationErrors &&
2257
- plugin.validationErrors.length > 0 && (
2258
- <div className="mb-4 rounded-2xl border border-danger/30 bg-danger/10 px-4 py-3 text-sm text-danger">
2259
- {plugin.validationErrors.map((error) => (
2260
- <div
2261
- key={`${plugin.id}:${error.field}:${error.message}`}
2262
- >
2263
- {error.field}: {error.message}
2264
- </div>
2265
- ))}
2266
- </div>
2267
- )}
2268
-
2269
- {plugin.validationWarnings &&
2270
- plugin.validationWarnings.length > 0 && (
2271
- <div className="mb-4 rounded-2xl border border-warn/30 bg-warn/10 px-4 py-3 text-sm text-warn">
2272
- {plugin.validationWarnings.map((warning) => (
2273
- <div
2274
- key={`${plugin.id}:${warning.field}:${warning.message}`}
2275
- >
2276
- {warning.message}
2277
- </div>
2278
- ))}
2279
- </div>
2280
- )}
2281
-
2282
- {pluginLinks.length > 0 && (
2283
- <div className="mb-4 flex flex-wrap gap-2">
2284
- {pluginLinks.map((link) => (
2285
- <Button
2286
- key={`${plugin.id}:${link.key}`}
2287
- variant="outline"
2288
- size="sm"
2289
- className="h-8 rounded-xl border-border/40 bg-card/40 px-3 text-[11px] font-semibold text-muted transition-all hover:border-accent hover:bg-accent/5 hover:text-txt"
2290
- onClick={() => {
2291
- void handleOpenPluginExternalUrl(link.url);
2292
- }}
2293
- title={`${link.label}: ${link.url}`}
2294
- >
2295
- {link.label}
2296
- </Button>
2297
- ))}
2298
- </div>
2299
- )}
2300
-
2301
- {plugin.enabled &&
2302
- !plugin.isActive &&
2303
- plugin.npmName &&
2304
- !plugin.loadError && (
2305
- <div className="mb-4 rounded-2xl border border-warn/30 bg-warn/10 px-4 py-3 text-sm text-txt">
2306
- <div className="flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
2307
- <div>
2308
- Install this connector to activate it in the
2309
- runtime.
2310
- </div>
2311
- <Button
2312
- variant="default"
2313
- size="sm"
2314
- className="h-8 rounded-xl px-4 text-[11px] font-bold"
2315
- disabled={installingPlugins.has(plugin.id)}
2316
- onClick={() =>
2317
- handleInstallPlugin(
2318
- plugin.id,
2319
- plugin.npmName ?? "",
2320
- )
2321
- }
2322
- >
2323
- {installingPlugins.has(plugin.id)
2324
- ? installProgress.get(
2325
- plugin.npmName ?? "",
2326
- )?.message || "Installing..."
2327
- : "Install Plugin"}
2328
- </Button>
2329
- </div>
2330
- </div>
2331
- )}
2332
-
2333
- {hasParams ? (
2334
- <div className="space-y-4">
2335
- <PluginConfigForm
2336
- plugin={plugin}
2337
- pluginConfigs={pluginConfigs}
2338
- onParamChange={handleParamChange}
2339
- />
2340
- {plugin.id === "whatsapp" && (
2341
- <WhatsAppQrOverlay accountId="default" />
2342
- )}
2343
- </div>
2344
- ) : (
2345
- <div className="rounded-2xl border border-border/40 bg-card/40 px-4 py-3 text-sm text-muted">
2346
- No configuration needed.
2347
- </div>
2348
- )}
2349
-
2350
- <div className="mt-4 flex flex-wrap items-center gap-2">
2351
- {plugin.isActive && (
2352
- <Button
2353
- variant={
2354
- testResult?.success
2355
- ? "default"
2356
- : testResult?.error
2357
- ? "destructive"
2358
- : "outline"
2359
- }
2360
- size="sm"
2361
- className={`h-8 rounded-xl px-4 text-[11px] font-bold transition-all ${testResult?.loading
2362
- ? "cursor-wait opacity-70"
2363
- : testResult?.success
2364
- ? "border-ok bg-ok text-ok-fg hover:bg-ok/90"
2365
- : testResult?.error
2366
- ? "border-danger bg-danger text-danger-fg hover:bg-danger/90"
2367
- : "border-border/40 bg-card/40 hover:border-accent/40"
2368
- }`}
2369
- disabled={testResult?.loading}
2370
- onClick={() =>
2371
- void handleTestConnection(plugin.id)
2372
- }
2373
- >
2374
- {testResult?.loading
2375
- ? "Testing..."
2376
- : testResult?.success
2377
- ? `OK (${testResult.durationMs}ms)`
2378
- : testResult?.error
2379
- ? `Failed: ${testResult.error}`
2380
- : "Test Connection"}
2381
- </Button>
2382
- )}
2383
- {hasParams && (
2384
- <>
2385
- <Button
2386
- variant="ghost"
2387
- size="sm"
2388
- className="h-8 rounded-xl px-4 text-[11px] font-semibold text-muted hover:text-txt"
2389
- onClick={() => handleConfigReset(plugin.id)}
2390
- >
2391
- Reset
2392
- </Button>
2393
- <Button
2394
- variant={
2395
- saveSuccess ? "default" : "secondary"
2396
- }
2397
- size="sm"
2398
- className={`h-8 rounded-xl px-4 text-[11px] font-bold transition-all ${saveSuccess
2399
- ? "bg-ok text-ok-fg hover:bg-ok/90"
2400
- : "bg-accent text-accent-fg hover:bg-accent/90"
2401
- }`}
2402
- onClick={() =>
2403
- void handleConfigSave(plugin.id)
2404
- }
2405
- disabled={isSaving}
2406
- >
2407
- {isSaving
2408
- ? "Saving..."
2409
- : saveSuccess
2410
- ? "Saved"
2411
- : "Save Settings"}
2412
- </Button>
2413
- </>
2414
- )}
2415
- </div>
2416
- </div>
2417
- )}
2418
- </section>
2419
- );
2420
- })}
2421
- </div>
2422
- )}
2423
- </div>
2424
- </div>
2425
- </div>
2426
- );
2427
- }
2428
-
2429
- if (inModal) {
2430
- const sectionTitle =
2431
- mode === "social"
2432
- ? "Connectors"
2433
- : mode === "connectors"
2434
- ? "Connectors"
2435
- : label;
2436
- return (
2437
- <div className="plugins-game-modal plugins-game-modal--inline">
2438
- <div
2439
- className={`plugins-game-list-panel${gameNarrow && gameMobileDetail ? " is-hidden" : ""
2440
- }`}
2441
- >
2442
- <div className="plugins-game-list-head">
2443
- <div className="plugins-game-section-title">{sectionTitle}</div>
2444
- </div>
2445
- <div className="plugins-game-list-scroll">
2446
- {gameVisiblePlugins.length === 0 ? (
2447
- <div className="plugins-game-list-empty">
2448
- No {resultLabel} {t("pluginsview.found")}
2449
- </div>
2450
- ) : (
2451
- gameVisiblePlugins.map((p: PluginInfo) => (
2452
- <button
2453
- key={p.id}
2454
- type="button"
2455
- className={`plugins-game-card${effectiveGameSelected === p.id ? " is-selected" : ""
2456
- }${!p.enabled ? " is-disabled" : ""}`}
2457
- onClick={() => {
2458
- setGameSelectedId(p.id);
2459
- if (gameNarrow) setGameMobileDetail(true);
2460
- }}
2461
- >
2462
- <div className="plugins-game-card-icon-shell">
2463
- <span className="plugins-game-card-icon">
2464
- {(() => {
2465
- const icon = resolveIcon(p);
2466
- if (!icon) return "🧩";
2467
- if (typeof icon === "string") {
2468
- const imageSrc = iconImageSource(icon);
2469
- return imageSrc ? (
2470
- <img
2471
- src={imageSrc}
2472
- alt=""
2473
- className="plugins-game-card-icon"
2474
- style={{ objectFit: "contain" }}
2475
- />
2476
- ) : (
2477
- icon
2478
- );
2479
- }
2480
- const IconComponent = icon;
2481
- return <IconComponent className="w-5 h-5" />;
2482
- })()}
2483
- </span>
2484
- </div>
2485
- <div className="plugins-game-card-body">
2486
- <div className="plugins-game-card-name">{p.name}</div>
2487
- <div className="plugins-game-card-meta">
2488
- <span
2489
- className={`plugins-game-badge ${p.enabled ? "is-on" : "is-off"
2490
- }`}
2491
- >
2492
- {p.enabled ? "ON" : "OFF"}
2493
- </span>
2494
- </div>
2495
- </div>
2496
- </button>
2497
- ))
2498
- )}
2499
- </div>
2500
- </div>
2501
- <div
2502
- className={`plugins-game-detail-panel${gameNarrow && !gameMobileDetail ? " is-hidden" : ""
2503
- }`}
2504
- >
2505
- {selectedPlugin ? (
2506
- <>
2507
- <div className="plugins-game-detail-head">
2508
- {gameNarrow && (
2509
- <button
2510
- type="button"
2511
- className="plugins-game-back-btn"
2512
- onClick={() => setGameMobileDetail(false)}
2513
- >
2514
- {t("pluginsview.Back")}
2515
- </button>
2516
- )}
2517
- <div className="plugins-game-detail-title-row">
2518
- <div className="plugins-game-detail-icon-shell">
2519
- <span className="plugins-game-detail-icon">
2520
- {(() => {
2521
- const icon = resolveIcon(selectedPlugin);
2522
- if (!icon) return "🧩";
2523
- if (typeof icon === "string") {
2524
- const imageSrc = iconImageSource(icon);
2525
- return imageSrc ? (
2526
- <img
2527
- src={imageSrc}
2528
- alt=""
2529
- className="plugins-game-detail-icon"
2530
- />
2531
- ) : (
2532
- icon
2533
- );
2534
- }
2535
- const IconComponent = icon;
2536
- return <IconComponent className="w-6 h-6" />;
2537
- })()}
2538
- </span>
2539
- </div>
2540
- <div className="plugins-game-detail-main">
2541
- <div className="plugins-game-detail-name">
2542
- {selectedPlugin.name}
2543
- </div>
2544
- {selectedPlugin.version && (
2545
- <span className="plugins-game-version">
2546
- v{selectedPlugin.version}
2547
- </span>
2548
- )}
2549
- </div>
2550
- <button
2551
- type="button"
2552
- className={`plugins-game-toggle ${selectedPlugin.enabled ? "is-on" : "is-off"
2553
- }`}
2554
- onClick={() =>
2555
- void handleTogglePlugin(
2556
- selectedPlugin.id,
2557
- !selectedPlugin.enabled,
2558
- )
2559
- }
2560
- disabled={togglingPlugins.has(selectedPlugin.id)}
2561
- >
2562
- {selectedPlugin.enabled ? "ON" : "OFF"}
2563
- </button>
2564
- </div>
2565
- </div>
2566
- <div className="plugins-game-detail-description">
2567
- {selectedPlugin.description}
2568
- </div>
2569
- {(selectedPlugin.tags?.length ?? 0) > 0 && (
2570
- <div className="flex flex-wrap gap-1.5 px-3 pb-3">
2571
- {selectedPlugin.tags?.map((tag) => (
2572
- <span
2573
- key={`${selectedPlugin.id}:${tag}`}
2574
- className="text-[10px] px-1.5 py-px border border-border bg-black/10 text-muted lowercase tracking-wide whitespace-nowrap"
2575
- >
2576
- {tag}
2577
- </span>
2578
- ))}
2579
- </div>
2580
- )}
2581
- {selectedPluginLinks.length > 0 && (
2582
- <div className="plugins-game-detail-links flex flex-wrap gap-2 px-3 pb-3">
2583
- {selectedPluginLinks.map((link) => (
2584
- <button
2585
- key={`${selectedPlugin.id}:${link.key}`}
2586
- type="button"
2587
- className="plugins-game-link-btn border border-border bg-transparent px-2.5 py-1 text-[11px] text-muted transition-colors hover:border-accent hover:text-txt"
2588
- onClick={() => {
2589
- void handleOpenPluginExternalUrl(link.url);
2590
- }}
2591
- >
2592
- {link.label}
2593
- </button>
2594
- ))}
2595
- </div>
2596
- )}
2597
- {selectedPlugin.parameters &&
2598
- selectedPlugin.parameters.length > 0 && (
2599
- <div className="plugins-game-detail-config">
2600
- {selectedPlugin.parameters.map((param: PluginParamDef) => (
2601
- <div key={param.key} id={`field-${param.key}`}>
2602
- <label
2603
- htmlFor={`input-${param.key}`}
2604
- className="text-[11px] tracking-wider text-muted block mb-1"
2605
- >
2606
- {param.key}
2607
- </label>
2608
- <input
2609
- id={`input-${param.key}`}
2610
- type={param.sensitive ? "password" : "text"}
2611
- className="w-full px-2 py-1 text-[12px]"
2612
- placeholder={param.description}
2613
- value={
2614
- pluginConfigs[selectedPlugin.id]?.[param.key] ??
2615
- param.currentValue ??
2616
- ""
2617
- }
2618
- onChange={(e) =>
2619
- handleParamChange(
2620
- selectedPlugin.id,
2621
- param.key,
2622
- e.target.value,
2623
- )
2624
- }
2625
- />
2626
- </div>
2627
- ))}
2628
- </div>
2629
- )}
2630
- <div className="plugins-game-detail-actions">
2631
- <button
2632
- type="button"
2633
- className="plugins-game-action-btn"
2634
- onClick={() => void handleTestConnection(selectedPlugin.id)}
2635
- >
2636
- {t("pluginsview.TestConnection")}
2637
- </button>
2638
- <button
2639
- type="button"
2640
- className={`plugins-game-action-btn plugins-game-save-btn${pluginSaveSuccess.has(selectedPlugin.id) ? " is-saved" : ""
2641
- }`}
2642
- onClick={() => void handleConfigSave(selectedPlugin.id)}
2643
- disabled={pluginSaving.has(selectedPlugin.id)}
2644
- >
2645
- {pluginSaving.has(selectedPlugin.id)
2646
- ? "Saving..."
2647
- : pluginSaveSuccess.has(selectedPlugin.id)
2648
- ? "Saved!"
2649
- : "Save"}
2650
- </button>
2651
- </div>
2652
- </>
2653
- ) : (
2654
- <div className="plugins-game-detail-empty">
2655
- <span className="plugins-game-detail-empty-icon">🧩</span>
2656
- <span className="plugins-game-detail-empty-text">
2657
- {t("pluginsview.SelectA")}{" "}
2658
- {isConnectorLikeMode ? "connector" : "plugin"}{" "}
2659
- {t("pluginsview.toC")}
2660
- </span>
2661
- </div>
2662
- )}
2663
- </div>
2664
- </div>
2665
- );
2666
- }
2667
-
2668
- // ── Main render ────────────────────────────────────────────────────
2669
-
2670
- return (
2671
- <div
2672
- data-testid={mode === "social" ? "plugins-view-social" : undefined}
2673
- className={`relative min-h-0 ${showDesktopSubgroupSidebar ? "md:pl-[18rem]" : ""}`}
2674
- >
2675
- {showDesktopSubgroupSidebar && (
2676
- <aside
2677
- className="hidden md:absolute md:left-0 md:top-0 md:block md:w-64"
2678
- data-testid="plugins-subgroup-sidebar"
2679
- >
2680
- <div className="sticky top-0 rounded-[28px] border border-border/50 bg-bg/35 p-5 backdrop-blur-xl shadow-sm">
2681
- <div className="mb-4 text-[11px] font-semibold uppercase tracking-[0.18em] text-muted/80">
2682
- Plugin Types
2683
- </div>
2684
- <nav className="flex flex-col gap-2">
2685
- {subgroupTags.map((tag) =>
2686
- renderSubgroupFilterButton(tag, { sidebar: true }),
2687
- )}
2688
- </nav>
2689
- </div>
2690
- </aside>
2691
- )}
2692
-
2693
- <div className="min-w-0">
2694
- {showToolbar && (
2695
- <div className="flex items-center gap-3 mb-4 flex-wrap">
2696
- <div className="relative flex-1 min-w-[220px]">
2697
- <Input
2698
- type="text"
2699
- name="plugin-search"
2700
- autoComplete="off"
2701
- data-1p-ignore
2702
- data-lpignore="true"
2703
- className="w-full bg-card/60 backdrop-blur-md shadow-inner pr-8 h-9 rounded-xl focus-visible:ring-accent border-border/40"
2704
- placeholder={searchPlaceholder}
2705
- value={pluginSearch}
2706
- onChange={(e) => setState("pluginSearch", e.target.value)}
2707
- />
2708
- {pluginSearch && (
2709
- <Button
2710
- variant="ghost"
2711
- size="icon"
2712
- className="absolute right-1 top-1/2 -translate-y-1/2 w-6 h-6 text-muted hover:text-txt rounded-full"
2713
- onClick={() => setState("pluginSearch", "")}
2714
- title={t("pluginsview.ClearSearch")}
2715
- >
2716
-
2717
- </Button>
2718
- )}
2719
- </div>
2720
-
2721
- <div className="flex gap-1.5 shrink-0 bg-black/10 p-1 rounded-xl border border-white/5">
2722
- {(["all", "enabled"] as const).map((s) => (
2723
- <Button
2724
- key={s}
2725
- variant={pluginStatusFilter === s ? "default" : "ghost"}
2726
- size="sm"
2727
- className={`h-7 px-3 text-[11px] font-bold tracking-wide rounded-lg transition-all ${pluginStatusFilter === s
2728
- ? "shadow-sm"
2729
- : "text-muted hover:text-txt hover:bg-white/5"
2730
- }`}
2731
- onClick={() =>
2732
- setState("pluginStatusFilter", s as StatusFilter)
2733
- }
2734
- >
2735
- {s === "all"
2736
- ? `All (${categoryPlugins.length})`
2737
- : `Enabled (${enabledCount})`}
2738
- </Button>
2739
- ))}
2740
- </div>
2741
-
2742
- {allowCustomOrder && pluginOrder.length > 0 && (
2743
- <Button
2744
- variant="outline"
2745
- size="sm"
2746
- className="h-8 px-3 text-[11px] font-bold border-border/40 bg-card/40 backdrop-blur-md shadow-sm rounded-xl shrink-0"
2747
- onClick={handleResetOrder}
2748
- title={t("pluginsview.ResetToDefaultSor")}
2749
- >
2750
- {t("pluginsview.ResetOrder")}
2751
- </Button>
2752
- )}
2753
-
2754
- {showPluginManagementActions && (
2755
- <Button
2756
- variant="secondary"
2757
- size="sm"
2758
- className="h-8 px-4 text-[11px] font-bold tracking-wide border border-accent/30 text-txt bg-accent/10 hover:bg-accent/20 hover:border-accent/50 shadow-sm rounded-xl shrink-0 transition-all"
2759
- onClick={() => setAddDirOpen(true)}
2760
- >
2761
- {t("pluginsview.AddPlugin")}
2762
- </Button>
2763
- )}
2764
- </div>
2765
- )}
2766
-
2767
- {hasPluginToggleInFlight && (
2768
- <div className="mb-3 px-3 py-2 border border-accent bg-accent-subtle text-[11px] text-txt">
2769
- {t("pluginsview.ApplyingPluginChan")}
2770
- </div>
2771
- )}
2772
-
2773
- {showSubgroupFilters && (
2774
- <div
2775
- className="flex items-center gap-2 mb-5 flex-wrap md:hidden"
2776
- data-testid="plugins-subgroup-chips"
2777
- >
2778
- {subgroupTags.map((tag) => renderSubgroupFilterButton(tag))}
2779
- </div>
2780
- )}
2781
-
2782
- {/* Plugin grid */}
2783
- <div className="overflow-y-auto">
2784
- {sorted.length === 0 ? (
2785
- <div className="text-center py-10 px-5 text-muted border border-dashed border-border">
2786
- {effectiveSearch
2787
- ? `No ${resultLabel} match your search.`
2788
- : `No ${resultLabel} available.`}
2789
- </div>
2790
- ) : visiblePlugins.length === 0 ? (
2791
- <div className="text-center py-10 px-5 text-muted border border-dashed border-border">
2792
- {showSubgroupFilters
2793
- ? "No plugins match this tag filter."
2794
- : `No ${resultLabel} match your filters.`}
2795
- </div>
2796
- ) : (
2797
- renderPluginGrid(visiblePlugins)
2798
- )}
2799
- </div>
2800
- </div>
2801
-
2802
- {/* Settings dialog */}
2803
- {settingsDialogPlugin &&
2804
- (() => {
2805
- const p = settingsDialogPlugin;
2806
- const isShowcase = p.id === "__ui-showcase__";
2807
- const isSaving = pluginSaving.has(p.id);
2808
- const saveSuccess = pluginSaveSuccess.has(p.id);
2809
- const categoryLabel = isShowcase
2810
- ? "showcase"
2811
- : p.category === "ai-provider"
2812
- ? "ai provider"
2813
- : p.category;
2814
- return (
2815
- <div
2816
- className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-6 animate-in fade-in duration-200"
2817
- onClick={(e) => {
2818
- if (e.target === e.currentTarget) toggleSettings(p.id);
2819
- }}
2820
- onKeyDown={(e) => {
2821
- if (e.key === "Escape" || e.key === "Enter" || e.key === " ") {
2822
- e.preventDefault();
2823
- toggleSettings(p.id);
2824
- }
2825
- }}
2826
- role="dialog"
2827
- aria-modal="true"
2828
- >
2829
- <div className="w-full max-w-2xl max-h-[85vh] border border-border/50 bg-card/90 shadow-2xl flex flex-col overflow-hidden rounded-2xl backdrop-blur-xl">
2830
- {/* Dialog header */}
2831
- <div className="flex items-center gap-3 px-5 py-4 border-b border-border/30 bg-black/10 shrink-0">
2832
- <span className="font-bold text-base flex items-center gap-2 flex-1 min-w-0 tracking-wide text-txt">
2833
- {(() => {
2834
- const icon = resolveIcon(p);
2835
- if (!icon) return null;
2836
- if (typeof icon === "string") {
2837
- const imageSrc = iconImageSource(icon);
2838
- return imageSrc ? (
2839
- <img
2840
- src={imageSrc}
2841
- alt=""
2842
- className="w-6 h-6 rounded-md object-contain"
2843
- onError={(e) => {
2844
- (
2845
- e.currentTarget as HTMLImageElement
2846
- ).style.display = "none";
2847
- }}
2848
- />
2849
- ) : (
2850
- <span className="text-base">{icon}</span>
2851
- );
2852
- }
2853
- const IconComponent = icon;
2854
- return <IconComponent className="w-6 h-6 text-txt" />;
2855
- })()}
2856
- {p.name}
2857
- </span>
2858
- <span className="text-[10px] px-2 py-0.5 rounded-full border border-border/40 bg-black/20 text-muted lowercase tracking-widest font-bold">
2859
- {categoryLabel}
2860
- </span>
2861
- {p.version && (
2862
- <span className="text-[10px] font-mono text-muted/70">
2863
- v{p.version}
2864
- </span>
2865
- )}
2866
- {isShowcase && (
2867
- <span className="text-[10px] font-bold tracking-widest px-2.5 py-[2px] border border-accent/30 text-txt bg-accent/10 rounded-full">
2868
- {t("pluginsview.DEMO")}
2869
- </span>
2870
- )}
2871
- <Button
2872
- variant="ghost"
2873
- size="icon"
2874
- className="h-8 w-8 text-muted hover:bg-white/10 hover:text-txt rounded-full transition-all shrink-0 ml-2"
2875
- onClick={() => toggleSettings(p.id)}
2876
- >
2877
-
2878
- </Button>
2879
- </div>
2880
-
2881
- {/* Dialog body — scrollable */}
2882
- <div className="overflow-y-auto flex-1 scrollbar-thin scrollbar-thumb-white/10 scrollbar-track-transparent">
2883
- {/* Plugin details */}
2884
- <div className="px-5 pt-4 pb-1 flex items-center gap-3 flex-wrap text-xs text-muted">
2885
- {p.description && (
2886
- <span className="text-[12px] text-muted leading-relaxed">
2887
- {p.description}
2888
- </span>
2889
- )}
2890
- {(p.tags?.length ?? 0) > 0 && (
2891
- <span className="flex items-center gap-1.5 flex-wrap">
2892
- {p.tags?.map((tag) => (
2893
- <span
2894
- key={`${p.id}:${tag}:settings`}
2895
- className="text-[10px] px-1.5 py-px border border-border/40 bg-black/10 text-muted lowercase tracking-wide whitespace-nowrap"
2896
- >
2897
- {tag}
2898
- </span>
2899
- ))}
2900
- </span>
2901
- )}
2902
- </div>
2903
- {(p.npmName || (p.pluginDeps && p.pluginDeps.length > 0)) && (
2904
- <div className="px-5 pb-2 flex items-center gap-3 flex-wrap">
2905
- {p.npmName && (
2906
- <span className="font-mono text-[10px] text-muted opacity-50">
2907
- {p.npmName}
2908
- </span>
2909
- )}
2910
- {p.pluginDeps && p.pluginDeps.length > 0 && (
2911
- <span className="flex items-center gap-1 flex-wrap">
2912
- <span className="text-[10px] text-muted opacity-60">
2913
- {t("pluginsview.dependsOn")}
2914
- </span>
2915
- {p.pluginDeps.map((dep: string) => (
2916
- <span
2917
- key={dep}
2918
- className="text-[10px] px-1.5 py-px border border-border bg-accent-subtle text-muted rounded-sm"
2919
- >
2920
- {dep}
2921
- </span>
2922
- ))}
2923
- </span>
2924
- )}
2925
- </div>
2926
- )}
2927
-
2928
- <div className="px-5 py-3">
2929
- <PluginConfigForm
2930
- plugin={p}
2931
- pluginConfigs={pluginConfigs}
2932
- onParamChange={handleParamChange}
2933
- />
2934
- {p.id === "whatsapp" && (
2935
- <WhatsAppQrOverlay accountId="default" />
2936
- )}
2937
- </div>
2938
- </div>
2939
-
2940
- {/* Dialog footer — actions (hidden for showcase) */}
2941
- {!isShowcase && (
2942
- <div className="flex justify-end gap-3 px-5 py-4 border-t border-border/30 shrink-0 bg-black/10">
2943
- {p.enabled && !p.isActive && p.npmName && !p.loadError && (
2944
- <Button
2945
- variant="default"
2946
- size="sm"
2947
- className="h-8 px-4 text-[11px] font-bold tracking-wide shadow-sm"
2948
- disabled={installingPlugins.has(p.id)}
2949
- onClick={() =>
2950
- handleInstallPlugin(p.id, p.npmName ?? "")
2951
- }
2952
- >
2953
- {installingPlugins.has(p.id)
2954
- ? installProgress.get(p.npmName ?? "")?.message ||
2955
- "Installing..."
2956
- : "Install Plugin"}
2957
- </Button>
2958
- )}
2959
- {p.loadError && (
2960
- <span
2961
- className="px-3 py-1.5 text-[11px] text-danger font-bold tracking-wide"
2962
- title={p.loadError}
2963
- >
2964
- {t("pluginsview.PackageBrokenMis")}
2965
- </span>
2966
- )}
2967
- {p.isActive && (
2968
- <Button
2969
- variant={
2970
- testResults.get(p.id)?.success
2971
- ? "default"
2972
- : testResults.get(p.id)?.error
2973
- ? "destructive"
2974
- : "outline"
2975
- }
2976
- size="sm"
2977
- className={`h-8 px-4 text-[11px] font-bold tracking-wide transition-all ${testResults.get(p.id)?.loading
2978
- ? "opacity-70 cursor-wait"
2979
- : testResults.get(p.id)?.success
2980
- ? "bg-ok text-ok-fg border-ok hover:bg-ok/90"
2981
- : testResults.get(p.id)?.error
2982
- ? "bg-danger text-danger-fg border-danger hover:bg-danger/90"
2983
- : "border-border/40 bg-card/40 backdrop-blur-md shadow-sm hover:border-accent/40"
2984
- }`}
2985
- disabled={testResults.get(p.id)?.loading}
2986
- onClick={() => handleTestConnection(p.id)}
2987
- >
2988
- {testResults.get(p.id)?.loading
2989
- ? "Testing..."
2990
- : testResults.get(p.id)?.success
2991
- ? `\u2713 OK (${testResults.get(p.id)?.durationMs}ms)`
2992
- : testResults.get(p.id)?.error
2993
- ? `\u2715 ${testResults.get(p.id)?.error}`
2994
- : "Test Connection"}
2995
- </Button>
2996
- )}
2997
- <Button
2998
- variant="ghost"
2999
- size="sm"
3000
- className="h-8 px-4 text-[12px] font-bold text-muted hover:text-txt transition-all"
3001
- onClick={() => handleConfigReset(p.id)}
3002
- >
3003
- {t("pluginsview.Reset")}
3004
- </Button>
3005
- <Button
3006
- variant={saveSuccess ? "default" : "secondary"}
3007
- size="sm"
3008
- className={`h-8 px-5 text-[12px] font-bold tracking-wide transition-all ${saveSuccess
3009
- ? "bg-ok text-ok-fg hover:bg-ok/90"
3010
- : "bg-accent text-accent-fg hover:bg-accent/90 shadow-lg shadow-accent/20"
3011
- }`}
3012
- onClick={() => handleConfigSave(p.id)}
3013
- disabled={isSaving}
3014
- >
3015
- {isSaving
3016
- ? "Saving..."
3017
- : saveSuccess
3018
- ? "\u2713 Saved"
3019
- : "Save Settings"}
3020
- </Button>
3021
- </div>
3022
- )}
3023
- </div>
3024
- </div>
3025
- );
3026
- })()}
3027
-
3028
- {/* Add from directory modal */}
3029
- {addDirOpen && (
3030
- <div
3031
- className="fixed inset-0 z-50 flex items-center justify-center bg-black/60 backdrop-blur-sm p-6 duration-200 animate-in fade-in"
3032
- onClick={(e) => {
3033
- if (e.target === e.currentTarget) {
3034
- setAddDirOpen(false);
3035
- setAddDirPath("");
3036
- }
3037
- }}
3038
- onKeyDown={(e) => {
3039
- if (e.key === "Escape" || e.key === "Enter" || e.key === " ") {
3040
- e.preventDefault();
3041
- setAddDirOpen(false);
3042
- setAddDirPath("");
3043
- }
3044
- }}
3045
- role="dialog"
3046
- aria-modal="true"
3047
- >
3048
- <div className="w-full max-w-md border border-border/50 bg-card/90 backdrop-blur-xl p-6 rounded-2xl shadow-2xl">
3049
- <div className="flex items-center justify-between mb-5">
3050
- <div className="font-bold text-base tracking-wide text-txt">
3051
- {t("pluginsview.AddPlugin1")}
3052
- </div>
3053
- <Button
3054
- variant="ghost"
3055
- size="icon"
3056
- className="h-8 w-8 text-muted hover:bg-white/10 hover:text-txt rounded-full transition-all shrink-0 ml-2"
3057
- onClick={() => {
3058
- setAddDirOpen(false);
3059
- setAddDirPath("");
3060
- }}
3061
- >
3062
-
3063
- </Button>
3064
- </div>
3065
-
3066
- <p className="text-sm font-medium tracking-wide text-muted mb-4">
3067
- {t("pluginsview.EnterThePathToA")}
3068
- </p>
3069
-
3070
- <Input
3071
- type="text"
3072
- className="w-full h-10 px-3 border border-border/40 bg-black/20 text-txt text-[13px] font-mono transition-all duration-150 focus-visible:ring-accent rounded-xl shadow-inner placeholder:text-muted/50"
3073
- placeholder={t("pluginsview.PathToPluginOrP")}
3074
- value={addDirPath}
3075
- onChange={(e) => setAddDirPath(e.target.value)}
3076
- onKeyDown={(e) => {
3077
- if (e.key === "Enter") void handleAddFromDirectory();
3078
- }}
3079
- />
3080
-
3081
- <div className="flex justify-end gap-3 mt-6">
3082
- <Button
3083
- variant="ghost"
3084
- size="sm"
3085
- className="h-8 px-4 text-[12px] font-bold text-muted hover:text-txt transition-all"
3086
- onClick={() => {
3087
- setAddDirOpen(false);
3088
- setAddDirPath("");
3089
- }}
3090
- >
3091
- {t("pluginsview.Cancel")}
3092
- </Button>
3093
- <Button
3094
- variant="default"
3095
- size="sm"
3096
- className="h-8 px-6 text-[12px] font-bold tracking-wide shadow-sm"
3097
- onClick={handleAddFromDirectory}
3098
- disabled={addDirLoading || !addDirPath.trim()}
3099
- >
3100
- {addDirLoading ? "Adding..." : "Add"}
3101
- </Button>
3102
- </div>
3103
- </div>
3104
- </div>
3105
- )}
3106
- </div>
3107
- );
3108
- }
3109
-
3110
- /* ── Exported views ────────────────────────────────────────────────── */
3111
-
3112
- /** Unified plugins view — tag-filtered plugin list. */
3113
- export function PluginsView({
3114
- mode = "all",
3115
- inModal,
3116
- }: {
3117
- mode?: PluginsViewMode;
3118
- inModal?: boolean;
3119
- }) {
3120
- const label =
3121
- mode === "social"
3122
- ? "Connectors"
3123
- : mode === "connectors"
3124
- ? "Connectors"
3125
- : mode === "streaming"
3126
- ? "Streaming"
3127
- : "Plugins";
3128
- return <PluginListView label={label} mode={mode} inModal={inModal} />;
3129
- }