@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,481 @@
1
+ /**
2
+ * Synthetic showcase plugin that demonstrates all 23 field renderers.
3
+ * Extracted from PluginsView.tsx to reduce file size.
4
+ */
5
+
6
+ import type { PluginInfo } from "../../api";
7
+
8
+ export const SHOWCASE_PLUGIN: PluginInfo = {
9
+ id: "__ui-showcase__",
10
+ name: "UI Field Showcase",
11
+ description:
12
+ "Interactive reference of all 23 field renderers. Not a real plugin — expand to see every UI component in action.",
13
+ enabled: false,
14
+ configured: true,
15
+ envKey: null,
16
+ category: "feature",
17
+ source: "bundled",
18
+ validationErrors: [],
19
+ validationWarnings: [],
20
+ version: "1.0.0",
21
+ icon: "🧩",
22
+ parameters: [
23
+ // 1. text
24
+ {
25
+ key: "DISPLAY_NAME",
26
+ type: "string",
27
+ description: "A simple single-line text input for names or short values.",
28
+ required: true,
29
+ sensitive: false,
30
+ currentValue: null,
31
+ isSet: false,
32
+ },
33
+ // 2. password
34
+ {
35
+ key: "SECRET_TOKEN",
36
+ type: "string",
37
+ description:
38
+ "Masked password input with show/hide toggle and server-backed reveal.",
39
+ required: true,
40
+ sensitive: true,
41
+ currentValue: null,
42
+ isSet: false,
43
+ },
44
+ // 3. number
45
+ {
46
+ key: "SERVER_PORT",
47
+ type: "number",
48
+ description: "Numeric input with min/max range and step control.",
49
+ required: false,
50
+ sensitive: false,
51
+ default: "3000",
52
+ currentValue: null,
53
+ isSet: false,
54
+ },
55
+ // 4. boolean
56
+ {
57
+ key: "ENABLE_LOGGING",
58
+ type: "boolean",
59
+ description: "Toggle switch — on/off. Auto-detected from ENABLE_ prefix.",
60
+ required: false,
61
+ sensitive: false,
62
+ default: "true",
63
+ currentValue: null,
64
+ isSet: false,
65
+ },
66
+ // 5. url
67
+ {
68
+ key: "WEBHOOK_URL",
69
+ type: "string",
70
+ description:
71
+ "URL input with format validation. Auto-detected from _URL suffix.",
72
+ required: false,
73
+ sensitive: false,
74
+ currentValue: null,
75
+ isSet: false,
76
+ },
77
+ // 6. select
78
+ {
79
+ key: "DEPLOY_REGION",
80
+ type: "string",
81
+ description:
82
+ "Dropdown selector populated from hint.options. Auto-detected for region/zone keys.",
83
+ required: false,
84
+ sensitive: false,
85
+ currentValue: null,
86
+ isSet: false,
87
+ },
88
+ // 7. textarea
89
+ {
90
+ key: "SYSTEM_PROMPT",
91
+ type: "string",
92
+ description:
93
+ "Multi-line text input for long values like prompts or templates. Auto-detected from _PROMPT suffix.",
94
+ required: false,
95
+ sensitive: false,
96
+ currentValue: null,
97
+ isSet: false,
98
+ },
99
+ // 8. email
100
+ {
101
+ key: "CONTACT_EMAIL",
102
+ type: "string",
103
+ description: "Email input with format validation. Renders type=email.",
104
+ required: false,
105
+ sensitive: false,
106
+ currentValue: null,
107
+ isSet: false,
108
+ },
109
+ // 9. color
110
+ {
111
+ key: "THEME_COLOR",
112
+ type: "string",
113
+ description: "Color picker with hex value text input side-by-side.",
114
+ required: false,
115
+ sensitive: false,
116
+ default: "#4a90d9",
117
+ currentValue: null,
118
+ isSet: false,
119
+ },
120
+ // 10. radio
121
+ {
122
+ key: "AUTH_MODE",
123
+ type: "string",
124
+ description:
125
+ "Radio button group — best for 2-3 mutually exclusive options. Uses 'basic' or 'oauth'.",
126
+ required: false,
127
+ sensitive: false,
128
+ currentValue: null,
129
+ isSet: false,
130
+ },
131
+ // 11. multiselect
132
+ {
133
+ key: "ENABLED_FEATURES",
134
+ type: "string",
135
+ description:
136
+ "Checkbox group for selecting multiple values from a fixed set.",
137
+ required: false,
138
+ sensitive: false,
139
+ currentValue: null,
140
+ isSet: false,
141
+ },
142
+ // 12. date
143
+ {
144
+ key: "START_DATE",
145
+ type: "string",
146
+ description: "Date picker input. Auto-detected from _DATE suffix.",
147
+ required: false,
148
+ sensitive: false,
149
+ currentValue: null,
150
+ isSet: false,
151
+ },
152
+ // 13. datetime
153
+ {
154
+ key: "SCHEDULED_AT",
155
+ type: "string",
156
+ description: "Combined date and time picker for scheduling.",
157
+ required: false,
158
+ sensitive: false,
159
+ currentValue: null,
160
+ isSet: false,
161
+ },
162
+ // 14. json
163
+ {
164
+ key: "METADATA_CONFIG",
165
+ type: "string",
166
+ description:
167
+ "JSON editor with syntax validation. Shows parse errors inline.",
168
+ required: false,
169
+ sensitive: false,
170
+ currentValue: null,
171
+ isSet: false,
172
+ },
173
+ // 15. code
174
+ {
175
+ key: "RESPONSE_TEMPLATE",
176
+ type: "string",
177
+ description:
178
+ "Code editor with monospaced font for templates and snippets.",
179
+ required: false,
180
+ sensitive: false,
181
+ currentValue: null,
182
+ isSet: false,
183
+ },
184
+ // 16. array
185
+ {
186
+ key: "ALLOWED_ORIGINS",
187
+ type: "string",
188
+ description:
189
+ "Comma-separated list of origins with add/remove UI for each item.",
190
+ required: false,
191
+ sensitive: false,
192
+ currentValue: null,
193
+ isSet: false,
194
+ },
195
+ // 17. keyvalue
196
+ {
197
+ key: "CUSTOM_HEADERS",
198
+ type: "string",
199
+ description: "Key-value pair editor with add/remove rows.",
200
+ required: false,
201
+ sensitive: false,
202
+ currentValue: null,
203
+ isSet: false,
204
+ },
205
+ // 18. file
206
+ {
207
+ key: "CERT_FILE",
208
+ type: "string",
209
+ description: "File path input for certificates, configs, or data files.",
210
+ required: false,
211
+ sensitive: false,
212
+ currentValue: null,
213
+ isSet: false,
214
+ },
215
+ // 19. custom
216
+ {
217
+ key: "CUSTOM_COMPONENT",
218
+ type: "string",
219
+ description: "Placeholder for plugin-provided custom React components.",
220
+ required: false,
221
+ sensitive: false,
222
+ currentValue: null,
223
+ isSet: false,
224
+ },
225
+ // 20. markdown
226
+ {
227
+ key: "RELEASE_NOTES",
228
+ type: "string",
229
+ description:
230
+ "Markdown editor with Edit/Preview toggle for rich text content.",
231
+ required: false,
232
+ sensitive: false,
233
+ currentValue: null,
234
+ isSet: false,
235
+ },
236
+ // 21. checkbox-group
237
+ {
238
+ key: "NOTIFICATION_CHANNELS",
239
+ type: "string",
240
+ description:
241
+ "Checkbox group with per-option descriptions — similar to multiselect but with checkbox UX.",
242
+ required: false,
243
+ sensitive: false,
244
+ currentValue: null,
245
+ isSet: false,
246
+ },
247
+ // 22. group
248
+ {
249
+ key: "CONNECTION_GROUP",
250
+ type: "string",
251
+ description:
252
+ "Fieldset container for visually grouping related configuration fields.",
253
+ required: false,
254
+ sensitive: false,
255
+ currentValue: null,
256
+ isSet: false,
257
+ },
258
+ // 23. table
259
+ {
260
+ key: "ROUTE_TABLE",
261
+ type: "string",
262
+ description:
263
+ "Tabular data editor with add/remove rows and column headers.",
264
+ required: false,
265
+ sensitive: false,
266
+ currentValue: null,
267
+ isSet: false,
268
+ },
269
+ ],
270
+ configUiHints: {
271
+ DISPLAY_NAME: {
272
+ label: "Display Name",
273
+ group: "Basic Fields",
274
+ width: "half",
275
+ help: "Renderer: text — single-line text input",
276
+ },
277
+ SECRET_TOKEN: {
278
+ label: "Secret Token",
279
+ group: "Basic Fields",
280
+ width: "half",
281
+ help: "Renderer: password — masked with show/hide toggle",
282
+ },
283
+ SERVER_PORT: {
284
+ label: "Server Port",
285
+ group: "Basic Fields",
286
+ width: "third",
287
+ min: 1,
288
+ max: 65535,
289
+ unit: "port",
290
+ help: "Renderer: number — with min/max range and unit label",
291
+ },
292
+ ENABLE_LOGGING: {
293
+ label: "Enable Logging",
294
+ group: "Basic Fields",
295
+ width: "third",
296
+ help: "Renderer: boolean — pill-shaped toggle switch",
297
+ },
298
+ WEBHOOK_URL: {
299
+ label: "Webhook URL",
300
+ group: "Basic Fields",
301
+ width: "full",
302
+ placeholder: "https://example.com/webhook",
303
+ help: "Renderer: url — URL input with format validation",
304
+ },
305
+ DEPLOY_REGION: {
306
+ label: "Deploy Region",
307
+ group: "Selection Fields",
308
+ width: "half",
309
+ type: "select",
310
+ options: [
311
+ { value: "us-east-1", label: "US East (Virginia)" },
312
+ { value: "us-west-2", label: "US West (Oregon)" },
313
+ { value: "eu-west-1", label: "EU (Ireland)" },
314
+ { value: "ap-southeast-1", label: "Asia Pacific (Singapore)" },
315
+ ],
316
+ help: "Renderer: select — dropdown with enhanced option labels",
317
+ },
318
+ SYSTEM_PROMPT: {
319
+ label: "System Prompt",
320
+ group: "Text Fields",
321
+ width: "full",
322
+ help: "Renderer: textarea — multi-line text input for long content",
323
+ },
324
+ CONTACT_EMAIL: {
325
+ label: "Contact Email",
326
+ group: "Text Fields",
327
+ width: "half",
328
+ type: "email",
329
+ placeholder: "admin@example.com",
330
+ help: "Renderer: email — email input with format validation",
331
+ },
332
+ THEME_COLOR: {
333
+ label: "Theme Color",
334
+ group: "Selection Fields",
335
+ width: "third",
336
+ type: "color",
337
+ help: "Renderer: color — color picker swatch + hex input",
338
+ },
339
+ AUTH_MODE: {
340
+ label: "Auth Mode",
341
+ group: "Selection Fields",
342
+ width: "half",
343
+ type: "radio",
344
+ options: [
345
+ {
346
+ value: "basic",
347
+ label: "Basic Auth",
348
+ description: "Username and password",
349
+ },
350
+ {
351
+ value: "oauth",
352
+ label: "OAuth 2.0",
353
+ description: "Token-based authentication",
354
+ },
355
+ {
356
+ value: "apikey",
357
+ label: "API Key",
358
+ description: "Header-based API key",
359
+ },
360
+ ],
361
+ help: "Renderer: radio — radio button group with descriptions",
362
+ },
363
+ ENABLED_FEATURES: {
364
+ label: "Enabled Features",
365
+ group: "Selection Fields",
366
+ width: "full",
367
+ type: "multiselect",
368
+ options: [
369
+ { value: "auth", label: "Authentication" },
370
+ { value: "logging", label: "Logging" },
371
+ { value: "caching", label: "Caching" },
372
+ { value: "webhooks", label: "Webhooks" },
373
+ { value: "ratelimit", label: "Rate Limiting" },
374
+ ],
375
+ help: "Renderer: multiselect — checkbox group for multiple selections",
376
+ },
377
+ START_DATE: {
378
+ label: "Start Date",
379
+ group: "Date & Time",
380
+ width: "half",
381
+ type: "date",
382
+ help: "Renderer: date — native date picker",
383
+ },
384
+ SCHEDULED_AT: {
385
+ label: "Scheduled At",
386
+ group: "Date & Time",
387
+ width: "half",
388
+ type: "datetime",
389
+ help: "Renderer: datetime — date + time picker",
390
+ },
391
+ METADATA_CONFIG: {
392
+ label: "Metadata Config",
393
+ group: "Structured Data",
394
+ width: "full",
395
+ type: "json",
396
+ help: "Renderer: json — JSON editor with inline validation",
397
+ },
398
+ RESPONSE_TEMPLATE: {
399
+ label: "Response Template",
400
+ group: "Structured Data",
401
+ width: "full",
402
+ type: "code",
403
+ help: "Renderer: code — monospaced code editor",
404
+ },
405
+ ALLOWED_ORIGINS: {
406
+ label: "Allowed Origins",
407
+ group: "Structured Data",
408
+ width: "full",
409
+ type: "array",
410
+ help: "Renderer: array — add/remove items list",
411
+ },
412
+ CUSTOM_HEADERS: {
413
+ label: "Custom Headers",
414
+ group: "Structured Data",
415
+ width: "full",
416
+ type: "keyvalue",
417
+ help: "Renderer: keyvalue — key-value pair editor",
418
+ },
419
+ CERT_FILE: {
420
+ label: "Certificate File",
421
+ group: "File Paths",
422
+ width: "full",
423
+ type: "file",
424
+ help: "Renderer: file — file path input",
425
+ },
426
+ CUSTOM_COMPONENT: {
427
+ label: "Custom Component",
428
+ group: "File Paths",
429
+ width: "full",
430
+ type: "custom",
431
+ help: "Renderer: custom — placeholder for plugin-provided React components",
432
+ advanced: true,
433
+ },
434
+ RELEASE_NOTES: {
435
+ label: "Release Notes",
436
+ group: "Text Fields",
437
+ width: "full",
438
+ type: "markdown",
439
+ help: "Renderer: markdown — textarea with Edit/Preview toggle",
440
+ },
441
+ NOTIFICATION_CHANNELS: {
442
+ label: "Notification Channels",
443
+ group: "Selection Fields",
444
+ width: "full",
445
+ type: "checkbox-group",
446
+ options: [
447
+ {
448
+ value: "email",
449
+ label: "Email",
450
+ description: "Send notifications via email",
451
+ },
452
+ {
453
+ value: "slack",
454
+ label: "Slack",
455
+ description: "Post to Slack channels",
456
+ },
457
+ {
458
+ value: "webhook",
459
+ label: "Webhook",
460
+ description: "HTTP POST to configured URL",
461
+ },
462
+ { value: "sms", label: "SMS", description: "Text message alerts" },
463
+ ],
464
+ help: "Renderer: checkbox-group — vertical checkbox list with descriptions",
465
+ },
466
+ CONNECTION_GROUP: {
467
+ label: "Connection Settings",
468
+ group: "Structured Data",
469
+ width: "full",
470
+ type: "group",
471
+ help: "Renderer: group — fieldset container with legend",
472
+ },
473
+ ROUTE_TABLE: {
474
+ label: "Route Table",
475
+ group: "Structured Data",
476
+ width: "full",
477
+ type: "table",
478
+ help: "Renderer: table — tabular data editor with add/remove rows",
479
+ },
480
+ },
481
+ };
@@ -0,0 +1,193 @@
1
+ import { LanguageDropdown, ThemeToggle } from "@elizaos/app-core/components";
2
+ import type { UiLanguage } from "@elizaos/app-core/i18n";
3
+ import type { ShellView, UiTheme } from "@elizaos/app-core/state";
4
+ import {
5
+ type LucideIcon,
6
+ Monitor,
7
+ Smartphone,
8
+ UserRound,
9
+ Users,
10
+ } from "lucide-react";
11
+ import { type ReactNode, useEffect, useState } from "react";
12
+
13
+ export const HEADER_ICON_BUTTON_CLASSNAME =
14
+ "inline-flex items-center justify-center w-11 h-11 min-w-[44px] min-h-[44px] border border-border/50 bg-bg/50 backdrop-blur-md cursor-pointer text-sm leading-none hover:border-accent hover:text-txt font-medium hover:-translate-y-0.5 transition-all duration-300 hover:shadow-[0_0_15px_rgba(var(--accent),0.5)] active:scale-95 rounded-xl text-txt shadow-sm";
15
+
16
+ type ShellHeaderTranslator = (key: string) => string;
17
+
18
+ const SHELL_MODE_MOBILE_BREAKPOINT = 768;
19
+
20
+ function useIsMobileShellViewport(): boolean {
21
+ const [isMobileViewport, setIsMobileViewport] = useState(() =>
22
+ typeof window !== "undefined"
23
+ ? window.innerWidth <= SHELL_MODE_MOBILE_BREAKPOINT
24
+ : false,
25
+ );
26
+
27
+ useEffect(() => {
28
+ if (
29
+ typeof window === "undefined" ||
30
+ typeof window.matchMedia !== "function"
31
+ ) {
32
+ return;
33
+ }
34
+
35
+ const mediaQuery = window.matchMedia(
36
+ `(max-width: ${SHELL_MODE_MOBILE_BREAKPOINT}px)`,
37
+ );
38
+ const syncViewport = () => {
39
+ setIsMobileViewport(mediaQuery.matches);
40
+ };
41
+ syncViewport();
42
+
43
+ if (typeof mediaQuery.addEventListener === "function") {
44
+ mediaQuery.addEventListener("change", syncViewport);
45
+ return () => mediaQuery.removeEventListener("change", syncViewport);
46
+ }
47
+
48
+ mediaQuery.addListener(syncViewport);
49
+ return () => mediaQuery.removeListener(syncViewport);
50
+ }, []);
51
+
52
+ return isMobileViewport;
53
+ }
54
+
55
+ interface ShellHeaderControlsProps {
56
+ activeShellView: ShellView;
57
+ onShellViewChange: (view: ShellView) => void;
58
+ uiLanguage: UiLanguage;
59
+ setUiLanguage: (language: UiLanguage) => void;
60
+ uiTheme: UiTheme;
61
+ setUiTheme: (theme: UiTheme) => void;
62
+ t: ShellHeaderTranslator;
63
+ children?: ReactNode;
64
+ rightExtras?: ReactNode;
65
+ trailingExtras?: ReactNode;
66
+ className?: string;
67
+ controlsVariant?: "native" | "companion";
68
+ languageDropdownClassName?: string;
69
+ languageDropdownWrapperTestId?: string;
70
+ themeToggleClassName?: string;
71
+ themeToggleWrapperClassName?: string;
72
+ themeToggleWrapperTestId?: string;
73
+ }
74
+
75
+ export function ShellHeaderControls({
76
+ activeShellView,
77
+ onShellViewChange,
78
+ uiLanguage,
79
+ setUiLanguage,
80
+ uiTheme,
81
+ setUiTheme,
82
+ t,
83
+ children,
84
+ rightExtras,
85
+ trailingExtras,
86
+ className,
87
+ controlsVariant = "native",
88
+ languageDropdownClassName,
89
+ languageDropdownWrapperTestId,
90
+ themeToggleClassName,
91
+ themeToggleWrapperClassName,
92
+ themeToggleWrapperTestId,
93
+ }: ShellHeaderControlsProps) {
94
+ const isMobileViewport = useIsMobileShellViewport();
95
+ const shellOptions: Array<{
96
+ view: ShellView;
97
+ label: string;
98
+ Icon: LucideIcon;
99
+ }> = [
100
+ {
101
+ view: "companion",
102
+ label: t("header.companionMode"),
103
+ Icon: UserRound,
104
+ },
105
+ {
106
+ view: "character",
107
+ label: t("nav.character"),
108
+ Icon: Users,
109
+ },
110
+ {
111
+ view: "desktop",
112
+ label: t("header.nativeMode"),
113
+ Icon: isMobileViewport ? Smartphone : Monitor,
114
+ },
115
+ ];
116
+
117
+ return (
118
+ <div
119
+ className={`flex min-w-0 items-center gap-3 w-full ${className ?? ""}`}
120
+ >
121
+ <div className="flex shrink-0 items-center">
122
+ <fieldset
123
+ className="inline-flex items-center gap-0.5 rounded-xl border border-border/60 bg-transparent p-0.5 shadow-sm dark:border-border/70 dark:bg-transparent"
124
+ data-testid="ui-shell-toggle"
125
+ aria-label="Switch shell view"
126
+ >
127
+ <legend className="sr-only">Switch shell view</legend>
128
+ {shellOptions.map(({ view, label, Icon }, index) => {
129
+ const selected = activeShellView === view;
130
+ const edgeClass =
131
+ index === 0
132
+ ? "rounded-l-xl rounded-r-none"
133
+ : index === shellOptions.length - 1
134
+ ? "rounded-l-none rounded-r-xl"
135
+ : "rounded-none";
136
+ return (
137
+ <button
138
+ key={view}
139
+ type="button"
140
+ onClick={() => onShellViewChange(view)}
141
+ className={`inline-flex h-9 min-w-[44px] items-center justify-center px-3 transition-all duration-200 ${edgeClass} ${
142
+ selected
143
+ ? "border border-[#d8a108]/30 bg-bg/55 text-[#8a6500] shadow-sm dark:border-accent/25 dark:bg-bg/85 dark:text-[#f0b232]"
144
+ : "border border-transparent bg-transparent text-muted-strong hover:border-border/70 hover:bg-bg/85 hover:text-txt dark:text-muted dark:hover:border-border/60 dark:hover:bg-bg-hover/80 dark:hover:text-txt"
145
+ }`}
146
+ aria-label={label}
147
+ aria-pressed={selected}
148
+ title={label}
149
+ data-testid={`ui-shell-toggle-${view}`}
150
+ >
151
+ <Icon className="h-4 w-4" />
152
+ </button>
153
+ );
154
+ })}
155
+ </fieldset>
156
+ </div>
157
+
158
+ <div className="min-w-0 flex-1">{children}</div>
159
+
160
+ <div
161
+ className="flex shrink-0 items-center justify-end gap-2"
162
+ data-testid="shell-header-right-controls"
163
+ >
164
+ {rightExtras}
165
+ <div
166
+ className={`shrink-0 ${languageDropdownClassName ?? ""}`}
167
+ data-testid={languageDropdownWrapperTestId}
168
+ >
169
+ <LanguageDropdown
170
+ uiLanguage={uiLanguage}
171
+ setUiLanguage={setUiLanguage}
172
+ t={t}
173
+ variant={controlsVariant}
174
+ triggerClassName="!h-10 !min-h-10 !rounded-xl !px-3.5 sm:!px-3.5 leading-none"
175
+ />
176
+ </div>
177
+ <div
178
+ className={`shrink-0 ${themeToggleWrapperClassName ?? ""}`}
179
+ data-testid={themeToggleWrapperTestId}
180
+ >
181
+ <ThemeToggle
182
+ uiTheme={uiTheme}
183
+ setUiTheme={setUiTheme}
184
+ t={t}
185
+ variant={controlsVariant}
186
+ className={`!h-10 !w-10 !min-h-10 !min-w-10 ${themeToggleClassName ?? ""}`}
187
+ />
188
+ </div>
189
+ {trailingExtras}
190
+ </div>
191
+ </div>
192
+ );
193
+ }
@@ -0,0 +1,15 @@
1
+ /**
2
+ * Shared context for the companion scene.
3
+ *
4
+ * Extracted into its own module so consumers can import
5
+ * `useSharedCompanionScene` without pulling in the heavy 3D stack
6
+ * (three / @pixiv/three-vrm / @sparkjsdev/spark) that lives in
7
+ * CompanionSceneHost.
8
+ */
9
+ import { createContext, useContext } from "react";
10
+
11
+ export const SharedCompanionSceneContext = createContext(false);
12
+
13
+ export function useSharedCompanionScene(): boolean {
14
+ return useContext(SharedCompanionSceneContext);
15
+ }