@elizaos/app-core 2.0.0-alpha.10

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 (399) hide show
  1. package/LICENSE +21 -0
  2. package/package.json +90 -0
  3. package/src/App.tsx +472 -0
  4. package/src/actions/character.test.ts +139 -0
  5. package/src/actions/character.ts +152 -0
  6. package/src/actions/chat-helpers.ts +100 -0
  7. package/src/actions/cloud.ts +59 -0
  8. package/src/actions/index.ts +12 -0
  9. package/src/actions/lifecycle.ts +175 -0
  10. package/src/actions/onboarding.ts +46 -0
  11. package/src/actions/triggers.ts +190 -0
  12. package/src/ambient.d.ts +16 -0
  13. package/src/api/client.ts +5516 -0
  14. package/src/api/index.ts +1 -0
  15. package/src/autonomy/index.ts +477 -0
  16. package/src/bridge/capacitor-bridge.ts +295 -0
  17. package/src/bridge/electrobun-rpc.ts +58 -0
  18. package/src/bridge/electrobun-runtime.ts +28 -0
  19. package/src/bridge/index.ts +5 -0
  20. package/src/bridge/native-plugins.ts +134 -0
  21. package/src/bridge/plugin-bridge.ts +352 -0
  22. package/src/bridge/storage-bridge.ts +162 -0
  23. package/src/chat/index.ts +250 -0
  24. package/src/coding/index.ts +43 -0
  25. package/src/components/AdvancedPageView.tsx +362 -0
  26. package/src/components/AgentActivityBox.tsx +49 -0
  27. package/src/components/ApiKeyConfig.tsx +224 -0
  28. package/src/components/AppsPageView.tsx +52 -0
  29. package/src/components/AppsView.tsx +293 -0
  30. package/src/components/AvatarLoader.tsx +86 -0
  31. package/src/components/AvatarSelector.tsx +223 -0
  32. package/src/components/BscTradePanel.tsx +549 -0
  33. package/src/components/BugReportModal.tsx +499 -0
  34. package/src/components/CharacterView.tsx +1645 -0
  35. package/src/components/ChatAvatar.test.ts +96 -0
  36. package/src/components/ChatAvatar.tsx +147 -0
  37. package/src/components/ChatComposer.tsx +330 -0
  38. package/src/components/ChatMessage.tsx +448 -0
  39. package/src/components/ChatModalView.test.tsx +118 -0
  40. package/src/components/ChatModalView.tsx +125 -0
  41. package/src/components/ChatView.tsx +992 -0
  42. package/src/components/CloudSourceControls.tsx +80 -0
  43. package/src/components/CodingAgentSettingsSection.tsx +536 -0
  44. package/src/components/CommandPalette.tsx +284 -0
  45. package/src/components/CompanionSceneHost.tsx +497 -0
  46. package/src/components/CompanionShell.tsx +31 -0
  47. package/src/components/CompanionView.tsx +109 -0
  48. package/src/components/ConfigPageView.tsx +758 -0
  49. package/src/components/ConfigSaveFooter.tsx +41 -0
  50. package/src/components/ConfirmModal.tsx +379 -0
  51. package/src/components/ConnectionFailedBanner.tsx +91 -0
  52. package/src/components/ConnectorsPageView.tsx +13 -0
  53. package/src/components/ConversationsSidebar.tsx +279 -0
  54. package/src/components/CustomActionEditor.tsx +1125 -0
  55. package/src/components/CustomActionsPanel.tsx +288 -0
  56. package/src/components/CustomActionsView.tsx +322 -0
  57. package/src/components/DatabasePageView.tsx +55 -0
  58. package/src/components/DatabaseView.tsx +814 -0
  59. package/src/components/ElizaCloudDashboard.tsx +1696 -0
  60. package/src/components/EmotePicker.tsx +529 -0
  61. package/src/components/ErrorBoundary.tsx +76 -0
  62. package/src/components/FineTuningView.tsx +1077 -0
  63. package/src/components/GameView.tsx +552 -0
  64. package/src/components/GameViewOverlay.tsx +133 -0
  65. package/src/components/GlobalEmoteOverlay.tsx +155 -0
  66. package/src/components/Header.test.tsx +413 -0
  67. package/src/components/Header.tsx +403 -0
  68. package/src/components/HeartbeatsView.tsx +1003 -0
  69. package/src/components/InventoryView.tsx +385 -0
  70. package/src/components/KnowledgeView.tsx +1128 -0
  71. package/src/components/LanguageDropdown.tsx +188 -0
  72. package/src/components/LifoMonitorPanel.tsx +196 -0
  73. package/src/components/LifoSandboxView.tsx +499 -0
  74. package/src/components/LoadingScreen.tsx +77 -0
  75. package/src/components/LogsPageView.tsx +17 -0
  76. package/src/components/LogsView.tsx +239 -0
  77. package/src/components/MediaGalleryView.tsx +433 -0
  78. package/src/components/MediaSettingsSection.tsx +893 -0
  79. package/src/components/MessageContent.tsx +815 -0
  80. package/src/components/OnboardingWizard.test.tsx +107 -0
  81. package/src/components/OnboardingWizard.tsx +189 -0
  82. package/src/components/PairingView.tsx +110 -0
  83. package/src/components/PermissionsSection.tsx +1186 -0
  84. package/src/components/PluginsPageView.tsx +9 -0
  85. package/src/components/PluginsView.tsx +3157 -0
  86. package/src/components/ProviderSwitcher.tsx +908 -0
  87. package/src/components/RestartBanner.tsx +76 -0
  88. package/src/components/RuntimeView.tsx +460 -0
  89. package/src/components/SaveCommandModal.tsx +211 -0
  90. package/src/components/SecretsView.tsx +569 -0
  91. package/src/components/SettingsView.tsx +825 -0
  92. package/src/components/ShellOverlays.tsx +41 -0
  93. package/src/components/ShortcutsOverlay.tsx +155 -0
  94. package/src/components/SkillsView.tsx +1435 -0
  95. package/src/components/StartupFailureView.tsx +63 -0
  96. package/src/components/StreamView.tsx +483 -0
  97. package/src/components/StripeEmbeddedCheckout.tsx +155 -0
  98. package/src/components/SubscriptionStatus.tsx +640 -0
  99. package/src/components/SystemWarningBanner.tsx +71 -0
  100. package/src/components/ThemeToggle.tsx +100 -0
  101. package/src/components/TrajectoriesView.tsx +526 -0
  102. package/src/components/TrajectoryDetailView.tsx +426 -0
  103. package/src/components/TriggersView.tsx +1 -0
  104. package/src/components/VectorBrowserView.tsx +1633 -0
  105. package/src/components/VoiceConfigView.tsx +675 -0
  106. package/src/components/VrmStage.test.ts +219 -0
  107. package/src/components/VrmStage.tsx +432 -0
  108. package/src/components/WhatsAppQrOverlay.tsx +230 -0
  109. package/src/components/__tests__/chainConfig.test.ts +220 -0
  110. package/src/components/apps/AppDetailPane.tsx +242 -0
  111. package/src/components/apps/AppsCatalogGrid.tsx +137 -0
  112. package/src/components/apps/extensions/HyperscapeAppDetailPanel.tsx +577 -0
  113. package/src/components/apps/extensions/registry.ts +16 -0
  114. package/src/components/apps/extensions/types.ts +9 -0
  115. package/src/components/apps/helpers.ts +44 -0
  116. package/src/components/avatar/VrmAnimationLoader.test.ts +164 -0
  117. package/src/components/avatar/VrmAnimationLoader.ts +151 -0
  118. package/src/components/avatar/VrmBlinkController.ts +118 -0
  119. package/src/components/avatar/VrmCameraManager.ts +407 -0
  120. package/src/components/avatar/VrmEngine.ts +2678 -0
  121. package/src/components/avatar/VrmFootShadow.ts +96 -0
  122. package/src/components/avatar/VrmViewer.tsx +421 -0
  123. package/src/components/avatar/__tests__/VrmCameraManager.test.ts +168 -0
  124. package/src/components/avatar/__tests__/VrmEngine.test.ts +1574 -0
  125. package/src/components/avatar/mixamoVRMRigMap.ts +62 -0
  126. package/src/components/avatar/retargetMixamoFbxToVrm.ts +144 -0
  127. package/src/components/avatar/retargetMixamoGltfToVrm.ts +119 -0
  128. package/src/components/chainConfig.ts +380 -0
  129. package/src/components/companion/CompanionHeader.tsx +47 -0
  130. package/src/components/companion/CompanionSceneHost.tsx +1 -0
  131. package/src/components/companion/VrmStage.tsx +2 -0
  132. package/src/components/companion/__tests__/walletUtils.test.ts +742 -0
  133. package/src/components/companion/walletUtils.ts +290 -0
  134. package/src/components/companion-shell-styles.test.ts +142 -0
  135. package/src/components/companion-shell-styles.ts +270 -0
  136. package/src/components/confirm-delete-control.tsx +69 -0
  137. package/src/components/conversations/ConversationListItem.tsx +185 -0
  138. package/src/components/conversations/conversation-utils.ts +151 -0
  139. package/src/components/format.ts +131 -0
  140. package/src/components/index.ts +94 -0
  141. package/src/components/inventory/CopyableAddress.tsx +41 -0
  142. package/src/components/inventory/InventoryToolbar.tsx +142 -0
  143. package/src/components/inventory/NftGrid.tsx +99 -0
  144. package/src/components/inventory/TokenLogo.tsx +71 -0
  145. package/src/components/inventory/TokensTable.tsx +216 -0
  146. package/src/components/inventory/constants.ts +170 -0
  147. package/src/components/inventory/index.ts +29 -0
  148. package/src/components/inventory/media-url.test.ts +38 -0
  149. package/src/components/inventory/media-url.ts +36 -0
  150. package/src/components/inventory/useInventoryData.ts +460 -0
  151. package/src/components/knowledge-upload-image.ts +215 -0
  152. package/src/components/labels.ts +46 -0
  153. package/src/components/onboarding/ActivateStep.tsx +30 -0
  154. package/src/components/onboarding/ConnectionStep.tsx +1530 -0
  155. package/src/components/onboarding/IdentityStep.tsx +147 -0
  156. package/src/components/onboarding/OnboardingPanel.tsx +39 -0
  157. package/src/components/onboarding/OnboardingStepNav.tsx +31 -0
  158. package/src/components/onboarding/PermissionsStep.tsx +20 -0
  159. package/src/components/onboarding/RpcStep.tsx +402 -0
  160. package/src/components/onboarding/WakeUpStep.tsx +184 -0
  161. package/src/components/permissions/PermissionIcon.tsx +25 -0
  162. package/src/components/permissions/StreamingPermissions.tsx +413 -0
  163. package/src/components/plugins/showcase-data.ts +481 -0
  164. package/src/components/shared/ShellHeaderControls.tsx +193 -0
  165. package/src/components/shared-companion-scene-context.ts +15 -0
  166. package/src/components/skeletons.tsx +88 -0
  167. package/src/components/stream/ActivityFeed.tsx +113 -0
  168. package/src/components/stream/AvatarPip.tsx +10 -0
  169. package/src/components/stream/ChatContent.tsx +126 -0
  170. package/src/components/stream/ChatTicker.tsx +55 -0
  171. package/src/components/stream/IdleContent.tsx +73 -0
  172. package/src/components/stream/StatusBar.tsx +469 -0
  173. package/src/components/stream/StreamSettings.tsx +506 -0
  174. package/src/components/stream/StreamTerminal.tsx +94 -0
  175. package/src/components/stream/StreamVoiceConfig.tsx +160 -0
  176. package/src/components/stream/helpers.ts +134 -0
  177. package/src/components/stream/overlays/OverlayLayer.tsx +75 -0
  178. package/src/components/stream/overlays/built-in/ActionTickerWidget.tsx +64 -0
  179. package/src/components/stream/overlays/built-in/AlertPopupWidget.tsx +87 -0
  180. package/src/components/stream/overlays/built-in/BrandingWidget.tsx +51 -0
  181. package/src/components/stream/overlays/built-in/CustomHtmlWidget.tsx +105 -0
  182. package/src/components/stream/overlays/built-in/PeonGlassWidget.tsx +265 -0
  183. package/src/components/stream/overlays/built-in/PeonHudWidget.tsx +247 -0
  184. package/src/components/stream/overlays/built-in/PeonSakuraWidget.tsx +278 -0
  185. package/src/components/stream/overlays/built-in/ThoughtBubbleWidget.tsx +77 -0
  186. package/src/components/stream/overlays/built-in/ViewerCountWidget.tsx +46 -0
  187. package/src/components/stream/overlays/built-in/index.ts +13 -0
  188. package/src/components/stream/overlays/registry.ts +22 -0
  189. package/src/components/stream/overlays/types.ts +90 -0
  190. package/src/components/stream/overlays/useOverlayLayout.ts +218 -0
  191. package/src/components/trajectory-format.ts +50 -0
  192. package/src/components/ui-badges.tsx +109 -0
  193. package/src/components/ui-switch.tsx +57 -0
  194. package/src/components/vector-browser-three.ts +27 -0
  195. package/src/config/config-catalog.ts +1092 -0
  196. package/src/config/config-field.tsx +1901 -0
  197. package/src/config/config-renderer.tsx +730 -0
  198. package/src/config/index.ts +11 -0
  199. package/src/config/ui-renderer.tsx +1751 -0
  200. package/src/config/ui-spec.ts +256 -0
  201. package/src/events/index.ts +89 -0
  202. package/src/hooks/index.ts +13 -0
  203. package/src/hooks/useBugReport.tsx +43 -0
  204. package/src/hooks/useCanvasWindow.ts +372 -0
  205. package/src/hooks/useChatAvatarVoice.ts +111 -0
  206. package/src/hooks/useContextMenu.ts +127 -0
  207. package/src/hooks/useKeyboardShortcuts.ts +86 -0
  208. package/src/hooks/useLifoSync.ts +143 -0
  209. package/src/hooks/useMemoryMonitor.ts +334 -0
  210. package/src/hooks/useRenderGuard.ts +43 -0
  211. package/src/hooks/useRetakeCapture.ts +67 -0
  212. package/src/hooks/useStreamPopoutNavigation.ts +27 -0
  213. package/src/hooks/useTimeout.ts +37 -0
  214. package/src/hooks/useVoiceChat.ts +1441 -0
  215. package/src/hooks/useWhatsAppPairing.ts +123 -0
  216. package/src/i18n/index.ts +76 -0
  217. package/src/i18n/locales/en.json +1194 -0
  218. package/src/i18n/locales/es.json +1194 -0
  219. package/src/i18n/locales/ko.json +1194 -0
  220. package/src/i18n/locales/pt.json +1194 -0
  221. package/src/i18n/locales/zh-CN.json +1194 -0
  222. package/src/i18n/messages.ts +21 -0
  223. package/src/index.ts +6 -0
  224. package/src/navigation/index.ts +282 -0
  225. package/src/navigation.test.ts +189 -0
  226. package/src/onboarding-config.test.ts +104 -0
  227. package/src/onboarding-config.ts +114 -0
  228. package/src/platform/browser-launch.test.ts +94 -0
  229. package/src/platform/browser-launch.ts +149 -0
  230. package/src/platform/index.ts +58 -0
  231. package/src/platform/init.ts +236 -0
  232. package/src/platform/lifo.ts +215 -0
  233. package/src/providers/index.ts +99 -0
  234. package/src/state/AppContext.tsx +5846 -0
  235. package/src/state/index.ts +6 -0
  236. package/src/state/internal.ts +86 -0
  237. package/src/state/onboarding-resume.test.ts +135 -0
  238. package/src/state/onboarding-resume.ts +263 -0
  239. package/src/state/parsers.test.ts +124 -0
  240. package/src/state/parsers.ts +308 -0
  241. package/src/state/persistence.ts +321 -0
  242. package/src/state/shell-routing.ts +32 -0
  243. package/src/state/types.ts +701 -0
  244. package/src/state/ui-preferences.ts +3 -0
  245. package/src/state/useApp.ts +23 -0
  246. package/src/state/vrm.ts +76 -0
  247. package/src/stories/AppMockProvider.tsx +32 -0
  248. package/src/stories/ChatEmptyState.stories.tsx +27 -0
  249. package/src/stories/ChatMessage.stories.tsx +115 -0
  250. package/src/stories/CompanionHeader.stories.tsx +74 -0
  251. package/src/stories/CompanionView.stories.tsx +33 -0
  252. package/src/stories/ConversationListItem.stories.tsx +102 -0
  253. package/src/stories/TypingIndicator.stories.tsx +28 -0
  254. package/src/styles/anime.css +6324 -0
  255. package/src/styles/base.css +196 -0
  256. package/src/styles/onboarding-game.css +738 -0
  257. package/src/styles/styles.css +2087 -0
  258. package/src/styles/xterm.css +241 -0
  259. package/src/types/index.ts +715 -0
  260. package/src/types/react-test-renderer.d.ts +45 -0
  261. package/src/utils/asset-url.ts +110 -0
  262. package/src/utils/assistant-text.ts +172 -0
  263. package/src/utils/clipboard.ts +41 -0
  264. package/src/utils/desktop-dialogs.ts +80 -0
  265. package/src/utils/index.ts +6 -0
  266. package/src/utils/number-parsing.ts +125 -0
  267. package/src/utils/openExternalUrl.ts +20 -0
  268. package/src/utils/spoken-text.ts +65 -0
  269. package/src/utils/streaming-text.ts +120 -0
  270. package/src/voice/index.ts +1 -0
  271. package/src/voice/types.ts +197 -0
  272. package/src/wallet-rpc.ts +176 -0
  273. package/test/app/AppContext.pty-sessions.test.tsx +143 -0
  274. package/test/app/MessageContent.test.tsx +326 -0
  275. package/test/app/PermissionsOnboarding.test.tsx +356 -0
  276. package/test/app/PermissionsSection.test.tsx +573 -0
  277. package/test/app/advanced-trajectory-fine-tuning.e2e.test.ts +393 -0
  278. package/test/app/agent-activity-box.test.tsx +132 -0
  279. package/test/app/agent-transfer-lock.test.ts +274 -0
  280. package/test/app/api-client-electron-fallback.test.ts +139 -0
  281. package/test/app/api-client-timeout.test.ts +75 -0
  282. package/test/app/api-client-ws.test.ts +98 -0
  283. package/test/app/api-client.ws-max-reconnect.test.ts +139 -0
  284. package/test/app/api-client.ws-reconnect.test.ts +157 -0
  285. package/test/app/app-context-autonomy-events.test.ts +478 -0
  286. package/test/app/apps-page-view.test.ts +114 -0
  287. package/test/app/apps-view.test.ts +769 -0
  288. package/test/app/autonomous-workflows.e2e.test.ts +765 -0
  289. package/test/app/autonomy-events.test.ts +150 -0
  290. package/test/app/avatar-selector.test.tsx +52 -0
  291. package/test/app/bsc-trade-panel.test.tsx +134 -0
  292. package/test/app/bug-report-modal.test.tsx +353 -0
  293. package/test/app/character-customization.e2e.test.ts +1199 -0
  294. package/test/app/chat-advanced-features.e2e.test.ts +706 -0
  295. package/test/app/chat-composer.test.tsx +181 -0
  296. package/test/app/chat-language-header.test.ts +64 -0
  297. package/test/app/chat-message.test.tsx +222 -0
  298. package/test/app/chat-modal-view.test.tsx +191 -0
  299. package/test/app/chat-routine-filter.test.ts +96 -0
  300. package/test/app/chat-send-lock.test.ts +1465 -0
  301. package/test/app/chat-stream-api-client.test.tsx +390 -0
  302. package/test/app/chat-view-game-modal.test.tsx +661 -0
  303. package/test/app/chat-view.test.tsx +877 -0
  304. package/test/app/cloud-api.e2e.test.ts +258 -0
  305. package/test/app/cloud-login-flow.e2e.test.ts +494 -0
  306. package/test/app/cloud-login-lock.test.ts +411 -0
  307. package/test/app/command-palette.test.tsx +184 -0
  308. package/test/app/command-registry.test.ts +75 -0
  309. package/test/app/companion-greeting-wave.test.tsx +425 -0
  310. package/test/app/companion-stale-conversation.test.tsx +447 -0
  311. package/test/app/companion-view.test.tsx +686 -0
  312. package/test/app/confirm-delete-control.test.ts +79 -0
  313. package/test/app/confirm-modal.test.tsx +219 -0
  314. package/test/app/connectors-ui.e2e.test.ts +508 -0
  315. package/test/app/conversations-sidebar-game-modal.test.tsx +260 -0
  316. package/test/app/conversations-sidebar.test.tsx +160 -0
  317. package/test/app/custom-actions-smoke.test.ts +387 -0
  318. package/test/app/custom-avatar-api-client.test.ts +207 -0
  319. package/test/app/desktop-utils.test.ts +145 -0
  320. package/test/app/electrobun-rpc-bridge.test.ts +83 -0
  321. package/test/app/events.test.ts +88 -0
  322. package/test/app/export-import-flows.e2e.test.ts +700 -0
  323. package/test/app/fine-tuning-view.test.ts +471 -0
  324. package/test/app/game-view-auth-session.test.tsx +186 -0
  325. package/test/app/game-view.test.ts +444 -0
  326. package/test/app/global-emote-overlay.test.tsx +106 -0
  327. package/test/app/header-status.test.tsx +149 -0
  328. package/test/app/i18n.test.ts +152 -0
  329. package/test/app/inventory-bsc-view.test.ts +940 -0
  330. package/test/app/knowledge-ui.e2e.test.ts +762 -0
  331. package/test/app/knowledge-upload-helpers.test.ts +124 -0
  332. package/test/app/lifecycle-lock.test.ts +267 -0
  333. package/test/app/lifo-popout-utils.test.ts +208 -0
  334. package/test/app/lifo-safe-endpoint.test.ts +34 -0
  335. package/test/app/loading-screen.test.tsx +45 -0
  336. package/test/app/memory-monitor.test.ts +332 -0
  337. package/test/app/navigation.test.tsx +22 -0
  338. package/test/app/onboarding-finish-lock.test.ts +663 -0
  339. package/test/app/onboarding-language.test.tsx +160 -0
  340. package/test/app/onboarding-steps.test.tsx +375 -0
  341. package/test/app/open-external-url.test.ts +65 -0
  342. package/test/app/pages-navigation-smoke.e2e.test.ts +633 -0
  343. package/test/app/pairing-lock.test.ts +260 -0
  344. package/test/app/pairing-view.test.tsx +74 -0
  345. package/test/app/permissions-section.test.ts +432 -0
  346. package/test/app/plugin-bridge.test.ts +109 -0
  347. package/test/app/plugins-ui.e2e.test.ts +605 -0
  348. package/test/app/plugins-view-game-modal.test.tsx +650 -0
  349. package/test/app/plugins-view-toggle-restart.test.ts +129 -0
  350. package/test/app/provider-dropdown-default.test.tsx +302 -0
  351. package/test/app/restart-banner.test.tsx +197 -0
  352. package/test/app/retake-capture.test.ts +84 -0
  353. package/test/app/sandbox-api-client.test.ts +108 -0
  354. package/test/app/save-command-modal.test.tsx +109 -0
  355. package/test/app/secrets-view.test.tsx +92 -0
  356. package/test/app/settings-control-styles.test.tsx +142 -0
  357. package/test/app/settings-reset.e2e.test.ts +726 -0
  358. package/test/app/settings-sections.e2e.test.ts +614 -0
  359. package/test/app/shared-format.test.ts +44 -0
  360. package/test/app/shared-switch.test.ts +69 -0
  361. package/test/app/shell-mode-switching.e2e.test.ts +829 -0
  362. package/test/app/shell-mode-tab-memory.test.tsx +58 -0
  363. package/test/app/shell-overlays.test.tsx +50 -0
  364. package/test/app/shortcuts-overlay.test.tsx +111 -0
  365. package/test/app/sse-interruption.test.ts +122 -0
  366. package/test/app/startup-asset-missing.e2e.test.ts +126 -0
  367. package/test/app/startup-backend-missing.e2e.test.ts +118 -0
  368. package/test/app/startup-chat.e2e.test.ts +305 -0
  369. package/test/app/startup-conversation-restore.test.tsx +344 -0
  370. package/test/app/startup-failure-view.test.tsx +103 -0
  371. package/test/app/startup-onboarding.e2e.test.ts +618 -0
  372. package/test/app/startup-timeout.test.tsx +80 -0
  373. package/test/app/startup-token-401.e2e.test.ts +103 -0
  374. package/test/app/stream-helpers.test.ts +46 -0
  375. package/test/app/stream-popout-navigation.test.tsx +41 -0
  376. package/test/app/stream-status-bar.test.tsx +89 -0
  377. package/test/app/theme-toggle.test.tsx +33 -0
  378. package/test/app/training-api-client.test.ts +128 -0
  379. package/test/app/trajectories-view.test.tsx +220 -0
  380. package/test/app/triggers-api-client.test.ts +77 -0
  381. package/test/app/triggers-navigation.test.ts +113 -0
  382. package/test/app/triggers-view.e2e.test.ts +674 -0
  383. package/test/app/update-channel-lock.test.ts +259 -0
  384. package/test/app/vector-browser.async-cleanup.test.tsx +367 -0
  385. package/test/app/vector-browser.e2e.test.ts +653 -0
  386. package/test/app/vrm-stage.test.tsx +351 -0
  387. package/test/app/vrm-viewer.test.tsx +298 -0
  388. package/test/app/wallet-api-save-lock.test.ts +298 -0
  389. package/test/app/wallet-hooks.test.ts +405 -0
  390. package/test/app/wallet-ui-flows.e2e.test.ts +556 -0
  391. package/test/avatar/asset-url.test.ts +90 -0
  392. package/test/avatar/avatar-selector.test.ts +173 -0
  393. package/test/avatar/mixamo-vrm-rig-map.test.ts +111 -0
  394. package/test/avatar/voice-chat-streaming-text.test.ts +96 -0
  395. package/test/avatar/voice-chat.test.ts +391 -0
  396. package/test/ui/command-palette-commands.test.ts +57 -0
  397. package/test/ui/ui-renderer.test.ts +39 -0
  398. package/tsconfig.build.json +19 -0
  399. package/tsconfig.json +20 -0
@@ -0,0 +1,188 @@
1
+ /**
2
+ * LanguageDropdown — language selector used in the app header and settings.
3
+ *
4
+ * Fully props-driven; no app context dependency. Takes the current language
5
+ * and a setter from the caller. Works in both "native" and "companion"
6
+ * visual variants.
7
+ */
8
+
9
+ import { Check, ChevronDown } from "lucide-react";
10
+ import { useCallback, useEffect, useRef, useState } from "react";
11
+ import { createPortal } from "react-dom";
12
+ import type { UiLanguage } from "../i18n/messages";
13
+
14
+ /** Minimal translator function type. Receive key, return string. */
15
+ export type TranslatorFn = (key: string) => string;
16
+
17
+ /** Language metadata with flag emoji and native label. */
18
+ export const LANGUAGES: { id: UiLanguage; flag: string; label: string }[] = [
19
+ { id: "en", flag: "🇺🇸", label: "English" },
20
+ { id: "zh-CN", flag: "🇨🇳", label: "中文" },
21
+ { id: "ko", flag: "🇰🇷", label: "한국어" },
22
+ { id: "es", flag: "🇪🇸", label: "Español" },
23
+ { id: "pt", flag: "🇧🇷", label: "Português" },
24
+ ];
25
+
26
+ export interface LanguageDropdownProps {
27
+ uiLanguage: UiLanguage;
28
+ setUiLanguage: (language: UiLanguage) => void;
29
+ /** Optional translator for ARIA labels */
30
+ t?: TranslatorFn;
31
+ /** Optional extra className on the root */
32
+ className?: string;
33
+ /** Optional extra className on the trigger button */
34
+ triggerClassName?: string;
35
+ variant?: "native" | "companion";
36
+ menuPlacement?: "bottom-end" | "top-end";
37
+ }
38
+
39
+ export function LanguageDropdown({
40
+ uiLanguage,
41
+ setUiLanguage,
42
+ t,
43
+ className,
44
+ triggerClassName,
45
+ variant = "native",
46
+ menuPlacement = "bottom-end",
47
+ }: LanguageDropdownProps) {
48
+ const [open, setOpen] = useState(false);
49
+ const rootRef = useRef<HTMLDivElement>(null);
50
+ const triggerRef = useRef<HTMLButtonElement>(null);
51
+ const [menuPos, setMenuPos] = useState<{
52
+ top?: number;
53
+ bottom?: number;
54
+ right: number;
55
+ } | null>(null);
56
+
57
+ // Compute dropdown position from trigger button rect (for companion portal)
58
+ const updateMenuPos = useCallback(() => {
59
+ if (variant !== "companion" || !triggerRef.current) return;
60
+ const rect = triggerRef.current.getBoundingClientRect();
61
+ if (menuPlacement === "top-end") {
62
+ setMenuPos({
63
+ bottom: window.innerHeight - rect.top + 4,
64
+ right: window.innerWidth - rect.right,
65
+ });
66
+ return;
67
+ }
68
+ setMenuPos({
69
+ top: rect.bottom + 4,
70
+ right: window.innerWidth - rect.right,
71
+ });
72
+ }, [menuPlacement, variant]);
73
+
74
+ // Close on outside click
75
+ useEffect(() => {
76
+ if (!open) return;
77
+ const handler = (e: MouseEvent) => {
78
+ if (rootRef.current && !rootRef.current.contains(e.target as Node)) {
79
+ // Also check if clicked inside the portaled menu
80
+ const portalMenu = document.getElementById("lang-dropdown-portal");
81
+ if (portalMenu?.contains(e.target as Node)) return;
82
+ setOpen(false);
83
+ }
84
+ };
85
+ document.addEventListener("mousedown", handler);
86
+ return () => document.removeEventListener("mousedown", handler);
87
+ }, [open]);
88
+
89
+ // Close on Escape
90
+ useEffect(() => {
91
+ if (!open) return;
92
+ const handler = (e: KeyboardEvent) => {
93
+ if (e.key === "Escape") setOpen(false);
94
+ };
95
+ document.addEventListener("keydown", handler);
96
+ return () => document.removeEventListener("keydown", handler);
97
+ }, [open]);
98
+
99
+ // Update position when opening
100
+ useEffect(() => {
101
+ if (open) updateMenuPos();
102
+ }, [open, updateMenuPos]);
103
+
104
+ const current = LANGUAGES.find((l) => l.id === uiLanguage) ?? LANGUAGES[0];
105
+ const triggerClass = `inline-flex items-center gap-1.5 h-9 px-2 sm:px-3 border border-border/50 bg-bg/50 backdrop-blur-md text-[11px] sm:text-xs font-medium cursor-pointer transition-all duration-300 text-txt hover:border-accent hover:text-txt rounded-md shadow-sm ${open ? "border-accent text-txt bg-accent/5" : ""} ${triggerClassName ?? ""}`;
106
+ const optionClass = (selected: boolean) =>
107
+ `w-full flex items-center justify-between px-3 py-2 text-sm transition-colors hover:bg-bg-hover cursor-pointer ${selected ? "text-txt bg-accent/5 font-medium" : "text-txt"}`;
108
+ const inlineMenuPositionClass =
109
+ menuPlacement === "top-end"
110
+ ? "absolute bottom-full right-0 mb-1 z-50"
111
+ : "absolute top-full right-0 mt-1 z-50";
112
+
113
+ const menuContent = open && (
114
+ <ul
115
+ id="lang-dropdown-portal"
116
+ className={`w-36 rounded-lg border border-border/50 bg-bg/50 shadow-xl overflow-hidden py-1 backdrop-blur-md ${variant === "companion" ? "fixed" : inlineMenuPositionClass}`}
117
+ style={
118
+ variant === "companion" && menuPos
119
+ ? {
120
+ ...(menuPos.top !== undefined ? { top: menuPos.top } : {}),
121
+ ...(menuPos.bottom !== undefined
122
+ ? { bottom: menuPos.bottom }
123
+ : {}),
124
+ right: menuPos.right,
125
+ zIndex: 10001,
126
+ backdropFilter: "blur(24px)",
127
+ WebkitBackdropFilter: "blur(24px)",
128
+ boxShadow: "var(--shadow-lg)",
129
+ }
130
+ : undefined
131
+ }
132
+ aria-label={t?.("settings.language") ?? "Language"}
133
+ >
134
+ {LANGUAGES.map((lang) => (
135
+ <li key={lang.id} role="presentation">
136
+ <button
137
+ type="button"
138
+ role="option"
139
+ aria-selected={lang.id === uiLanguage}
140
+ className={optionClass(lang.id === uiLanguage)}
141
+ onClick={() => {
142
+ setUiLanguage(lang.id);
143
+ setOpen(false);
144
+ }}
145
+ data-testid={`language-option-${lang.id}`}
146
+ >
147
+ <div className="flex items-center gap-2">
148
+ <span>{lang.flag}</span>
149
+ <span>{lang.label}</span>
150
+ </div>
151
+ {lang.id === uiLanguage && <Check className="w-4 h-4" />}
152
+ </button>
153
+ </li>
154
+ ))}
155
+ </ul>
156
+ );
157
+
158
+ return (
159
+ <div
160
+ ref={rootRef}
161
+ className={`relative inline-flex shrink-0 ${className ?? ""}`}
162
+ data-testid="language-dropdown"
163
+ >
164
+ <button
165
+ ref={triggerRef}
166
+ type="button"
167
+ className={triggerClass}
168
+ onClick={() => setOpen((v) => !v)}
169
+ aria-haspopup="listbox"
170
+ aria-expanded={open}
171
+ aria-label={t?.("settings.language") ?? "Language"}
172
+ data-testid="language-dropdown-trigger"
173
+ >
174
+ <span className="text-sm leading-none">{current.flag}</span>
175
+ <span className="hidden sm:inline uppercase tracking-widest opacity-80">
176
+ {current.id}
177
+ </span>
178
+ <ChevronDown
179
+ className={`w-3.5 h-3.5 opacity-60 transition-transform ${open ? "rotate-180" : ""}`}
180
+ />
181
+ </button>
182
+
183
+ {variant === "companion" && menuContent
184
+ ? createPortal(menuContent, document.body)
185
+ : menuContent}
186
+ </div>
187
+ );
188
+ }
@@ -0,0 +1,196 @@
1
+ import { Button } from "@elizaos/ui";
2
+ import type { SandboxBrowserEndpoints, SandboxWindowInfo } from "../api/client";
3
+ import { useApp } from "../state";
4
+
5
+ interface LifoMonitorPanelProps {
6
+ monitorOnline: boolean;
7
+ monitorError: string | null;
8
+ monitorUpdatedAt: number | null;
9
+ noVncActive: boolean;
10
+ safeNoVncEndpoint: string | null;
11
+ noVncFailed: boolean;
12
+ setNoVncFailed: React.Dispatch<React.SetStateAction<boolean>>;
13
+ screenPreviewUrl: string | null;
14
+ browserEndpoints: SandboxBrowserEndpoints | null;
15
+ sandboxWindows: SandboxWindowInfo[];
16
+ noVncEndpoint: string | null;
17
+ refreshMonitorMeta: () => Promise<void>;
18
+ refreshScreenPreview: () => Promise<void>;
19
+ setMonitorOnline: React.Dispatch<React.SetStateAction<boolean>>;
20
+ setMonitorError: React.Dispatch<React.SetStateAction<string | null>>;
21
+ }
22
+
23
+ export function LifoMonitorPanel({
24
+ monitorOnline,
25
+ monitorError,
26
+ monitorUpdatedAt,
27
+ noVncActive,
28
+ safeNoVncEndpoint,
29
+ noVncFailed,
30
+ setNoVncFailed,
31
+ screenPreviewUrl,
32
+ browserEndpoints,
33
+ sandboxWindows,
34
+ noVncEndpoint,
35
+ refreshMonitorMeta,
36
+ refreshScreenPreview,
37
+ setMonitorOnline,
38
+ setMonitorError,
39
+ }: LifoMonitorPanelProps) {
40
+ const { t } = useApp();
41
+ return (
42
+ <div className="grid grid-cols-1 xl:grid-cols-[2fr_1fr] gap-3">
43
+ <div className="rounded-xl border border-border overflow-hidden bg-panel min-h-[320px]">
44
+ <div className="px-3 py-2 border-b border-border flex items-center justify-between gap-2">
45
+ <div>
46
+ <div className="text-xs font-semibold text-txt">
47
+ {t("lifomonitorpanel.LifoComputerUseSu")}
48
+ </div>
49
+ <div className="text-[11px] text-muted">
50
+ {t("lifomonitorpanel.WatchOnlyDesktopM")}
51
+ </div>
52
+ </div>
53
+ <div className="flex items-center gap-2">
54
+ <span
55
+ className={`rounded-full px-2 py-1 text-[11px] font-medium ${
56
+ monitorOnline ? "bg-ok/20 text-ok" : "bg-warn/20 text-warn"
57
+ }`}
58
+ >
59
+ {monitorOnline ? "live" : "offline"}
60
+ </span>
61
+ <Button
62
+ variant="outline"
63
+ size="sm"
64
+ onClick={() => {
65
+ setNoVncFailed(false);
66
+ void refreshMonitorMeta();
67
+ void refreshScreenPreview();
68
+ }}
69
+ className="h-7 px-2.5 py-1 text-[11px] shadow-sm hover:border-accent hover:text-txt"
70
+ >
71
+ {t("appsview.Refresh")}
72
+ </Button>
73
+ </div>
74
+ </div>
75
+
76
+ <div className="h-[320px] bg-black/90 flex items-center justify-center overflow-hidden">
77
+ {noVncActive && safeNoVncEndpoint ? (
78
+ <iframe
79
+ src={safeNoVncEndpoint}
80
+ title={t("lifomonitorpanel.SandboxLiveNoVNCS")}
81
+ className="h-full w-full border-0"
82
+ sandbox="allow-scripts allow-forms allow-pointer-lock"
83
+ onLoad={() => {
84
+ setMonitorOnline(true);
85
+ setMonitorError(null);
86
+ }}
87
+ onError={() => {
88
+ setNoVncFailed(true);
89
+ setMonitorOnline(false);
90
+ setMonitorError(
91
+ "Live noVNC surface unavailable. Falling back to screenshots.",
92
+ );
93
+ }}
94
+ />
95
+ ) : screenPreviewUrl ? (
96
+ <img
97
+ src={screenPreviewUrl}
98
+ alt="Sandbox computer-use surface"
99
+ className="h-full w-full object-contain"
100
+ />
101
+ ) : (
102
+ <p className="px-4 text-center text-xs text-muted">
103
+ {t("lifomonitorpanel.WaitingForSandbox")}
104
+ </p>
105
+ )}
106
+ </div>
107
+
108
+ <div className="px-3 py-2 border-t border-border text-[11px] text-muted">
109
+ {monitorUpdatedAt
110
+ ? `Last frame: ${new Date(monitorUpdatedAt).toLocaleTimeString()}`
111
+ : "No frames captured yet"}
112
+ </div>
113
+ </div>
114
+
115
+ <div className="rounded-xl border border-border overflow-hidden bg-panel min-h-[320px]">
116
+ <div className="px-3 py-2 border-b border-border">
117
+ <div className="text-xs font-semibold text-txt">
118
+ {t("lifomonitorpanel.BrowserSandboxCo")}
119
+ </div>
120
+ <div className="text-[11px] text-muted">
121
+ {t("lifomonitorpanel.AgentControlsBrows")}
122
+ </div>
123
+ </div>
124
+
125
+ <div className="p-3 space-y-3 text-[11px]">
126
+ <div>
127
+ <div className="text-muted uppercase tracking-wide text-[10px]">
128
+ {t("lifomonitorpanel.LiveSurface")}
129
+ </div>
130
+ <div className="mt-1 rounded border border-border bg-card px-2 py-1 text-txt break-all">
131
+ {noVncEndpoint && !noVncFailed
132
+ ? "noVNC"
133
+ : noVncEndpoint
134
+ ? "noVNC failed -> screenshot fallback"
135
+ : "Screenshot fallback"}
136
+ </div>
137
+ </div>
138
+
139
+ <div>
140
+ <div className="text-muted uppercase tracking-wide text-[10px]">
141
+ {t("lifomonitorpanel.CDPEndpoint")}
142
+ </div>
143
+ <div className="mt-1 rounded border border-border bg-card px-2 py-1 text-txt break-all">
144
+ {browserEndpoints?.cdpEndpoint ?? "Unavailable"}
145
+ </div>
146
+ </div>
147
+
148
+ <div>
149
+ <div className="text-muted uppercase tracking-wide text-[10px]">
150
+ {t("lifomonitorpanel.WSEndpoint")}
151
+ </div>
152
+ <div className="mt-1 rounded border border-border bg-card px-2 py-1 text-txt break-all">
153
+ {browserEndpoints?.wsEndpoint ?? "Unavailable"}
154
+ </div>
155
+ </div>
156
+
157
+ <div>
158
+ <div className="text-muted uppercase tracking-wide text-[10px]">
159
+ {t("lifomonitorpanel.noVNCEndpoint")}
160
+ </div>
161
+ <div className="mt-1 rounded border border-border bg-card px-2 py-1 text-txt break-all">
162
+ {browserEndpoints?.noVncEndpoint ?? "Unavailable"}
163
+ </div>
164
+ </div>
165
+
166
+ <div>
167
+ <div className="text-muted uppercase tracking-wide text-[10px]">
168
+ {t("lifomonitorpanel.VisibleWindows")}
169
+ {sandboxWindows.length})
170
+ </div>
171
+ <div className="mt-1 max-h-[154px] overflow-auto rounded border border-border bg-card p-2 space-y-1">
172
+ {sandboxWindows.length > 0 ? (
173
+ sandboxWindows.slice(0, 20).map((windowInfo) => (
174
+ <div key={windowInfo.id} className="text-txt">
175
+ <span className="text-muted">{windowInfo.app}:</span>{" "}
176
+ {windowInfo.title || "(untitled)"}
177
+ </div>
178
+ ))
179
+ ) : (
180
+ <div className="text-muted">
181
+ {t("lifomonitorpanel.NoActiveWindowsRe")}
182
+ </div>
183
+ )}
184
+ </div>
185
+ </div>
186
+
187
+ {monitorError && (
188
+ <div className="rounded border border-danger/40 bg-danger/10 px-2 py-1 text-danger">
189
+ {monitorError}
190
+ </div>
191
+ )}
192
+ </div>
193
+ </div>
194
+ </div>
195
+ );
196
+ }