@elizaos/app-core 2.0.0-alpha.73 → 2.0.0-alpha.75

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 (1143) hide show
  1. package/App.d.ts +5 -0
  2. package/App.d.ts.map +1 -0
  3. package/App.js +220 -0
  4. package/actions/character.d.ts +39 -0
  5. package/actions/character.d.ts.map +1 -0
  6. package/actions/character.js +247 -0
  7. package/actions/chat-helpers.d.ts +47 -0
  8. package/actions/chat-helpers.d.ts.map +1 -0
  9. package/actions/chat-helpers.js +79 -0
  10. package/actions/cloud.d.ts +17 -0
  11. package/actions/cloud.d.ts.map +1 -0
  12. package/actions/cloud.js +43 -0
  13. package/actions/index.d.ts +12 -0
  14. package/actions/index.d.ts.map +1 -0
  15. package/actions/index.js +11 -0
  16. package/actions/lifecycle.d.ts +43 -0
  17. package/actions/lifecycle.d.ts.map +1 -0
  18. package/actions/lifecycle.js +118 -0
  19. package/actions/onboarding.d.ts +12 -0
  20. package/actions/onboarding.d.ts.map +1 -0
  21. package/actions/onboarding.js +26 -0
  22. package/actions/triggers.d.ts +23 -0
  23. package/actions/triggers.d.ts.map +1 -0
  24. package/actions/triggers.js +148 -0
  25. package/api/client.d.ts +2736 -0
  26. package/api/client.d.ts.map +1 -0
  27. package/api/client.js +2492 -0
  28. package/api/index.d.ts +2 -0
  29. package/api/index.d.ts.map +1 -0
  30. package/autonomy/index.d.ts +48 -0
  31. package/autonomy/index.d.ts.map +1 -0
  32. package/autonomy/index.js +330 -0
  33. package/bridge/capacitor-bridge.d.ts +153 -0
  34. package/bridge/capacitor-bridge.d.ts.map +1 -0
  35. package/bridge/capacitor-bridge.js +193 -0
  36. package/bridge/electrobun-rpc.d.ts +28 -0
  37. package/bridge/electrobun-rpc.d.ts.map +1 -0
  38. package/bridge/electrobun-rpc.js +35 -0
  39. package/bridge/electrobun-runtime.d.ts +3 -0
  40. package/bridge/electrobun-runtime.d.ts.map +1 -0
  41. package/bridge/electrobun-runtime.js +17 -0
  42. package/bridge/index.d.ts +6 -0
  43. package/bridge/index.d.ts.map +1 -0
  44. package/bridge/native-plugins.d.ts +82 -0
  45. package/bridge/native-plugins.d.ts.map +1 -0
  46. package/bridge/native-plugins.js +39 -0
  47. package/bridge/plugin-bridge.d.ts +116 -0
  48. package/bridge/plugin-bridge.d.ts.map +1 -0
  49. package/bridge/plugin-bridge.js +203 -0
  50. package/bridge/storage-bridge.d.ts +39 -0
  51. package/bridge/storage-bridge.d.ts.map +1 -0
  52. package/bridge/storage-bridge.js +135 -0
  53. package/chat/index.d.ts +57 -0
  54. package/chat/index.d.ts.map +1 -0
  55. package/chat/index.js +160 -0
  56. package/coding/index.d.ts +25 -0
  57. package/coding/index.d.ts.map +1 -0
  58. package/coding/index.js +25 -0
  59. package/components/AdvancedPageView.d.ts +17 -0
  60. package/components/AdvancedPageView.d.ts.map +1 -0
  61. package/components/AdvancedPageView.js +146 -0
  62. package/components/AgentActivityBox.d.ts +7 -0
  63. package/components/AgentActivityBox.d.ts.map +1 -0
  64. package/components/AgentActivityBox.js +25 -0
  65. package/components/ApiKeyConfig.d.ts +26 -0
  66. package/components/ApiKeyConfig.d.ts.map +1 -0
  67. package/components/ApiKeyConfig.js +119 -0
  68. package/components/AppsPageView.d.ts +7 -0
  69. package/components/AppsPageView.d.ts.map +1 -0
  70. package/components/AppsPageView.js +31 -0
  71. package/components/AppsView.d.ts +8 -0
  72. package/components/AppsView.d.ts.map +1 -0
  73. package/components/AppsView.js +149 -0
  74. package/components/AvatarLoader.d.ts +13 -0
  75. package/components/AvatarLoader.d.ts.map +1 -0
  76. package/components/AvatarLoader.js +53 -0
  77. package/components/AvatarSelector.d.ts +23 -0
  78. package/components/AvatarSelector.d.ts.map +1 -0
  79. package/components/AvatarSelector.js +105 -0
  80. package/components/BscTradePanel.d.ts +22 -0
  81. package/components/BscTradePanel.d.ts.map +1 -0
  82. package/components/BscTradePanel.js +221 -0
  83. package/components/BugReportModal.d.ts +2 -0
  84. package/components/BugReportModal.d.ts.map +1 -0
  85. package/components/BugReportModal.js +219 -0
  86. package/components/CharacterRoster.d.ts +31 -0
  87. package/components/CharacterRoster.d.ts.map +1 -0
  88. package/components/CharacterRoster.js +41 -0
  89. package/components/CharacterView.d.ts +8 -0
  90. package/components/CharacterView.d.ts.map +1 -0
  91. package/components/CharacterView.js +685 -0
  92. package/components/ChatAvatar.d.ts +8 -0
  93. package/components/ChatAvatar.d.ts.map +1 -0
  94. package/components/ChatAvatar.js +89 -0
  95. package/components/ChatComposer.d.ts +37 -0
  96. package/components/ChatComposer.d.ts.map +1 -0
  97. package/components/ChatComposer.js +136 -0
  98. package/components/ChatMessage.d.ts +24 -0
  99. package/components/ChatMessage.d.ts.map +1 -0
  100. package/components/ChatMessage.js +167 -0
  101. package/components/ChatModalView.d.ts +10 -0
  102. package/components/ChatModalView.d.ts.map +1 -0
  103. package/components/ChatModalView.js +57 -0
  104. package/components/ChatView.d.ts +14 -0
  105. package/components/ChatView.d.ts.map +1 -0
  106. package/components/ChatView.js +526 -0
  107. package/components/CloudOnboarding.d.ts +7 -0
  108. package/components/CloudOnboarding.d.ts.map +1 -0
  109. package/components/CloudOnboarding.js +22 -0
  110. package/components/CloudSourceControls.d.ts +13 -0
  111. package/components/CloudSourceControls.d.ts.map +1 -0
  112. package/components/CloudSourceControls.js +16 -0
  113. package/components/CodingAgentSettingsSection.d.ts +2 -0
  114. package/components/CodingAgentSettingsSection.d.ts.map +1 -0
  115. package/components/CodingAgentSettingsSection.js +270 -0
  116. package/components/CommandPalette.d.ts +2 -0
  117. package/components/CommandPalette.d.ts.map +1 -0
  118. package/components/CommandPalette.js +181 -0
  119. package/components/CompanionSceneHost.d.ts +14 -0
  120. package/components/CompanionSceneHost.d.ts.map +1 -0
  121. package/components/CompanionSceneHost.js +360 -0
  122. package/components/CompanionShell.d.ts +17 -0
  123. package/components/CompanionShell.d.ts.map +1 -0
  124. package/components/CompanionShell.js +15 -0
  125. package/components/CompanionView.d.ts +2 -0
  126. package/components/CompanionView.d.ts.map +1 -0
  127. package/components/CompanionView.js +22 -0
  128. package/components/ConfigPageView.d.ts +11 -0
  129. package/components/ConfigPageView.d.ts.map +1 -0
  130. package/components/ConfigPageView.js +303 -0
  131. package/components/ConfigSaveFooter.d.ts +8 -0
  132. package/components/ConfigSaveFooter.d.ts.map +1 -0
  133. package/components/ConfigSaveFooter.js +10 -0
  134. package/components/ConfirmModal.d.ts +61 -0
  135. package/components/ConfirmModal.d.ts.map +1 -0
  136. package/components/ConfirmModal.js +164 -0
  137. package/components/ConnectionFailedBanner.d.ts +6 -0
  138. package/components/ConnectionFailedBanner.d.ts.map +1 -0
  139. package/components/ConnectionFailedBanner.js +22 -0
  140. package/components/ConnectorsPageView.d.ts +7 -0
  141. package/components/ConnectorsPageView.d.ts.map +1 -0
  142. package/components/ConnectorsPageView.js +8 -0
  143. package/components/ConversationsSidebar.d.ts +9 -0
  144. package/components/ConversationsSidebar.d.ts.map +1 -0
  145. package/components/ConversationsSidebar.js +116 -0
  146. package/components/CustomActionEditor.d.ts +10 -0
  147. package/components/CustomActionEditor.d.ts.map +1 -0
  148. package/components/CustomActionEditor.js +578 -0
  149. package/components/CustomActionsPanel.d.ts +9 -0
  150. package/components/CustomActionsPanel.d.ts.map +1 -0
  151. package/components/CustomActionsPanel.js +107 -0
  152. package/components/CustomActionsView.d.ts +2 -0
  153. package/components/CustomActionsView.d.ts.map +1 -0
  154. package/components/CustomActionsView.js +134 -0
  155. package/components/DatabasePageView.d.ts +5 -0
  156. package/components/DatabasePageView.d.ts.map +1 -0
  157. package/components/DatabasePageView.js +28 -0
  158. package/components/DatabaseView.d.ts +9 -0
  159. package/components/DatabaseView.d.ts.map +1 -0
  160. package/components/DatabaseView.js +311 -0
  161. package/components/ElizaCloudDashboard.d.ts +2 -0
  162. package/components/ElizaCloudDashboard.d.ts.map +1 -0
  163. package/components/ElizaCloudDashboard.js +657 -0
  164. package/components/EmotePicker.d.ts +2 -0
  165. package/components/EmotePicker.d.ts.map +1 -0
  166. package/components/EmotePicker.js +343 -0
  167. package/components/ErrorBoundary.d.ts +22 -0
  168. package/components/ErrorBoundary.d.ts.map +1 -0
  169. package/components/ErrorBoundary.js +31 -0
  170. package/components/FineTuningView.d.ts +2 -0
  171. package/components/FineTuningView.d.ts.map +1 -0
  172. package/components/FineTuningView.js +433 -0
  173. package/components/FlaminaGuide.d.ts +10 -0
  174. package/components/FlaminaGuide.d.ts.map +1 -0
  175. package/components/FlaminaGuide.js +64 -0
  176. package/components/GameView.d.ts +11 -0
  177. package/components/GameView.d.ts.map +1 -0
  178. package/components/GameView.js +294 -0
  179. package/components/GameViewOverlay.d.ts +8 -0
  180. package/components/GameViewOverlay.d.ts.map +1 -0
  181. package/components/GameViewOverlay.js +70 -0
  182. package/components/GlobalEmoteOverlay.d.ts +2 -0
  183. package/components/GlobalEmoteOverlay.d.ts.map +1 -0
  184. package/components/GlobalEmoteOverlay.js +112 -0
  185. package/components/Header.d.ts +9 -0
  186. package/components/Header.d.ts.map +1 -0
  187. package/components/Header.js +123 -0
  188. package/components/HeartbeatsView.d.ts +2 -0
  189. package/components/HeartbeatsView.d.ts.map +1 -0
  190. package/components/HeartbeatsView.js +378 -0
  191. package/components/InventoryView.d.ts +10 -0
  192. package/components/InventoryView.d.ts.map +1 -0
  193. package/components/InventoryView.js +176 -0
  194. package/components/KnowledgeView.d.ts +20 -0
  195. package/components/KnowledgeView.d.ts.map +1 -0
  196. package/components/KnowledgeView.js +480 -0
  197. package/components/LanguageDropdown.d.ts +30 -0
  198. package/components/LanguageDropdown.d.ts.map +1 -0
  199. package/components/LanguageDropdown.js +99 -0
  200. package/components/LifoMonitorPanel.d.ts +21 -0
  201. package/components/LifoMonitorPanel.d.ts.map +1 -0
  202. package/components/LifoMonitorPanel.js +24 -0
  203. package/components/LifoSandboxView.d.ts +5 -0
  204. package/components/LifoSandboxView.d.ts.map +1 -0
  205. package/components/LifoSandboxView.js +333 -0
  206. package/components/LoadingScreen.d.ts +13 -0
  207. package/components/LoadingScreen.d.ts.map +1 -0
  208. package/components/LoadingScreen.js +70 -0
  209. package/components/LogsPageView.d.ts +2 -0
  210. package/components/LogsPageView.d.ts.map +1 -0
  211. package/components/LogsPageView.js +7 -0
  212. package/components/LogsView.d.ts +5 -0
  213. package/components/LogsView.d.ts.map +1 -0
  214. package/components/LogsView.js +71 -0
  215. package/components/MediaGalleryView.d.ts +9 -0
  216. package/components/MediaGalleryView.d.ts.map +1 -0
  217. package/components/MediaGalleryView.js +236 -0
  218. package/components/MediaSettingsSection.d.ts +11 -0
  219. package/components/MediaSettingsSection.d.ts.map +1 -0
  220. package/components/MediaSettingsSection.js +329 -0
  221. package/components/MessageContent.d.ts +51 -0
  222. package/components/MessageContent.d.ts.map +1 -0
  223. package/components/MessageContent.js +553 -0
  224. package/components/OnboardingWizard.d.ts +2 -0
  225. package/components/OnboardingWizard.d.ts.map +1 -0
  226. package/components/OnboardingWizard.js +96 -0
  227. package/components/PairingView.d.ts +5 -0
  228. package/components/PairingView.d.ts.map +1 -0
  229. package/components/PairingView.js +29 -0
  230. package/components/PermissionsSection.d.ts +20 -0
  231. package/components/PermissionsSection.d.ts.map +1 -0
  232. package/components/PermissionsSection.js +573 -0
  233. package/components/PluginsPageView.d.ts +5 -0
  234. package/components/PluginsPageView.d.ts.map +1 -0
  235. package/components/PluginsPageView.js +8 -0
  236. package/components/PluginsView.d.ts +21 -0
  237. package/components/PluginsView.d.ts.map +1 -0
  238. package/components/PluginsView.js +1534 -0
  239. package/components/ProviderSwitcher.d.ts +42 -0
  240. package/components/ProviderSwitcher.d.ts.map +1 -0
  241. package/components/ProviderSwitcher.js +493 -0
  242. package/components/RestartBanner.d.ts +2 -0
  243. package/components/RestartBanner.d.ts.map +1 -0
  244. package/components/RestartBanner.js +36 -0
  245. package/components/RuntimeView.d.ts +10 -0
  246. package/components/RuntimeView.d.ts.map +1 -0
  247. package/components/RuntimeView.js +165 -0
  248. package/components/SaveCommandModal.d.ts +12 -0
  249. package/components/SaveCommandModal.d.ts.map +1 -0
  250. package/components/SaveCommandModal.js +84 -0
  251. package/components/SecretsView.d.ts +9 -0
  252. package/components/SecretsView.d.ts.map +1 -0
  253. package/components/SecretsView.js +249 -0
  254. package/components/SettingsView.d.ts +9 -0
  255. package/components/SettingsView.d.ts.map +1 -0
  256. package/components/SettingsView.js +230 -0
  257. package/components/ShellOverlays.d.ts +8 -0
  258. package/components/ShellOverlays.d.ts.map +1 -0
  259. package/components/ShellOverlays.js +10 -0
  260. package/components/ShortcutsOverlay.d.ts +2 -0
  261. package/components/ShortcutsOverlay.d.ts.map +1 -0
  262. package/components/ShortcutsOverlay.js +79 -0
  263. package/components/SkillsView.d.ts +11 -0
  264. package/components/SkillsView.d.ts.map +1 -0
  265. package/components/SkillsView.js +358 -0
  266. package/components/StartupFailureView.d.ts +8 -0
  267. package/components/StartupFailureView.d.ts.map +1 -0
  268. package/components/StartupFailureView.js +16 -0
  269. package/components/StreamView.d.ts +16 -0
  270. package/components/StreamView.d.ts.map +1 -0
  271. package/components/StreamView.js +300 -0
  272. package/components/StripeEmbeddedCheckout.d.ts +24 -0
  273. package/components/StripeEmbeddedCheckout.d.ts.map +1 -0
  274. package/components/StripeEmbeddedCheckout.js +101 -0
  275. package/components/SubscriptionStatus.d.ts +23 -0
  276. package/components/SubscriptionStatus.d.ts.map +1 -0
  277. package/components/SubscriptionStatus.js +301 -0
  278. package/components/SystemWarningBanner.d.ts +6 -0
  279. package/components/SystemWarningBanner.d.ts.map +1 -0
  280. package/components/SystemWarningBanner.js +46 -0
  281. package/components/ThemeToggle.d.ts +21 -0
  282. package/components/ThemeToggle.d.ts.map +1 -0
  283. package/components/ThemeToggle.js +24 -0
  284. package/components/TrajectoriesView.d.ts +12 -0
  285. package/components/TrajectoriesView.d.ts.map +1 -0
  286. package/components/TrajectoriesView.js +183 -0
  287. package/components/TrajectoryDetailView.d.ts +13 -0
  288. package/components/TrajectoryDetailView.d.ts.map +1 -0
  289. package/components/TrajectoryDetailView.js +112 -0
  290. package/components/TriggersView.d.ts +2 -0
  291. package/components/TriggersView.d.ts.map +1 -0
  292. package/components/VectorBrowserView.d.ts +10 -0
  293. package/components/VectorBrowserView.d.ts.map +1 -0
  294. package/components/VectorBrowserView.js +997 -0
  295. package/components/VoiceConfigView.d.ts +11 -0
  296. package/components/VoiceConfigView.d.ts.map +1 -0
  297. package/components/VoiceConfigView.js +329 -0
  298. package/components/VrmStage.d.ts +28 -0
  299. package/components/VrmStage.d.ts.map +1 -0
  300. package/components/VrmStage.js +178 -0
  301. package/components/WhatsAppQrOverlay.d.ts +8 -0
  302. package/components/WhatsAppQrOverlay.d.ts.map +1 -0
  303. package/components/WhatsAppQrOverlay.js +63 -0
  304. package/components/apps/AppDetailPane.d.ts +15 -0
  305. package/components/apps/AppDetailPane.d.ts.map +1 -0
  306. package/components/apps/AppDetailPane.js +13 -0
  307. package/components/apps/AppsCatalogGrid.d.ts +20 -0
  308. package/components/apps/AppsCatalogGrid.d.ts.map +1 -0
  309. package/components/apps/AppsCatalogGrid.js +18 -0
  310. package/components/apps/extensions/registry.d.ts +4 -0
  311. package/components/apps/extensions/registry.d.ts.map +1 -0
  312. package/components/apps/extensions/registry.js +7 -0
  313. package/components/apps/extensions/types.d.ts +7 -0
  314. package/components/apps/extensions/types.d.ts.map +1 -0
  315. package/components/apps/extensions/types.js +1 -0
  316. package/components/apps/helpers.d.ts +7 -0
  317. package/components/apps/helpers.d.ts.map +1 -0
  318. package/components/apps/helpers.js +44 -0
  319. package/components/avatar/VrmAnimationLoader.d.ts +30 -0
  320. package/components/avatar/VrmAnimationLoader.d.ts.map +1 -0
  321. package/components/avatar/VrmAnimationLoader.js +99 -0
  322. package/components/avatar/VrmBlinkController.d.ts +37 -0
  323. package/components/avatar/VrmBlinkController.d.ts.map +1 -0
  324. package/components/avatar/VrmBlinkController.js +98 -0
  325. package/components/avatar/VrmCameraManager.d.ts +57 -0
  326. package/components/avatar/VrmCameraManager.d.ts.map +1 -0
  327. package/components/avatar/VrmCameraManager.js +277 -0
  328. package/components/avatar/VrmEngine.d.ts +246 -0
  329. package/components/avatar/VrmEngine.d.ts.map +1 -0
  330. package/components/avatar/VrmEngine.js +2076 -0
  331. package/components/avatar/VrmFootShadow.d.ts +18 -0
  332. package/components/avatar/VrmFootShadow.d.ts.map +1 -0
  333. package/components/avatar/VrmFootShadow.js +83 -0
  334. package/components/avatar/VrmViewer.d.ts +60 -0
  335. package/components/avatar/VrmViewer.d.ts.map +1 -0
  336. package/components/avatar/VrmViewer.js +396 -0
  337. package/components/avatar/mixamoVRMRigMap.d.ts +3 -0
  338. package/components/avatar/mixamoVRMRigMap.d.ts.map +1 -0
  339. package/components/avatar/mixamoVRMRigMap.js +56 -0
  340. package/components/avatar/retargetMixamoFbxToVrm.d.ts +9 -0
  341. package/components/avatar/retargetMixamoFbxToVrm.d.ts.map +1 -0
  342. package/components/avatar/retargetMixamoFbxToVrm.js +88 -0
  343. package/components/avatar/retargetMixamoGltfToVrm.d.ts +11 -0
  344. package/components/avatar/retargetMixamoGltfToVrm.d.ts.map +1 -0
  345. package/components/avatar/retargetMixamoGltfToVrm.js +80 -0
  346. package/components/chainConfig.d.ts +89 -0
  347. package/components/chainConfig.d.ts.map +1 -0
  348. package/components/chainConfig.js +287 -0
  349. package/components/companion/CompanionHeader.d.ts +15 -0
  350. package/components/companion/CompanionHeader.d.ts.map +1 -0
  351. package/components/companion/CompanionHeader.js +7 -0
  352. package/components/companion/CompanionSceneHost.d.ts +2 -0
  353. package/components/companion/CompanionSceneHost.d.ts.map +1 -0
  354. package/components/companion/CompanionSceneHost.js +1 -0
  355. package/components/companion/VrmStage.d.ts +3 -0
  356. package/components/companion/VrmStage.d.ts.map +1 -0
  357. package/components/companion/VrmStage.js +1 -0
  358. package/components/companion/index.d.ts +18 -0
  359. package/components/companion/index.d.ts.map +1 -0
  360. package/components/companion/index.js +17 -0
  361. package/components/companion/walletUtils.d.ts +95 -0
  362. package/components/companion/walletUtils.d.ts.map +1 -0
  363. package/components/companion/walletUtils.js +167 -0
  364. package/components/companion-shell-styles.d.ts +38 -0
  365. package/components/companion-shell-styles.d.ts.map +1 -0
  366. package/components/companion-shell-styles.js +248 -0
  367. package/components/confirm-delete-control.d.ts +16 -0
  368. package/components/confirm-delete-control.d.ts.map +1 -0
  369. package/components/confirm-delete-control.js +12 -0
  370. package/components/conversations/ConversationListItem.d.ts +31 -0
  371. package/components/conversations/ConversationListItem.d.ts.map +1 -0
  372. package/components/conversations/ConversationListItem.js +52 -0
  373. package/components/conversations/conversation-utils.d.ts +9 -0
  374. package/components/conversations/conversation-utils.d.ts.map +1 -0
  375. package/components/conversations/conversation-utils.js +138 -0
  376. package/components/format.d.ts +54 -0
  377. package/components/format.d.ts.map +1 -0
  378. package/components/format.js +82 -0
  379. package/components/index.d.ts +96 -0
  380. package/components/index.d.ts.map +1 -0
  381. package/components/index.js +95 -0
  382. package/components/inventory/CopyableAddress.d.ts +8 -0
  383. package/components/inventory/CopyableAddress.d.ts.map +1 -0
  384. package/components/inventory/CopyableAddress.js +18 -0
  385. package/components/inventory/InventoryToolbar.d.ts +25 -0
  386. package/components/inventory/InventoryToolbar.d.ts.map +1 -0
  387. package/components/inventory/InventoryToolbar.js +28 -0
  388. package/components/inventory/NftGrid.d.ts +13 -0
  389. package/components/inventory/NftGrid.d.ts.map +1 -0
  390. package/components/inventory/NftGrid.js +29 -0
  391. package/components/inventory/TokenLogo.d.ts +12 -0
  392. package/components/inventory/TokenLogo.d.ts.map +1 -0
  393. package/components/inventory/TokenLogo.js +33 -0
  394. package/components/inventory/TokensTable.d.ts +24 -0
  395. package/components/inventory/TokensTable.d.ts.map +1 -0
  396. package/components/inventory/TokensTable.js +26 -0
  397. package/components/inventory/constants.d.ts +52 -0
  398. package/components/inventory/constants.d.ts.map +1 -0
  399. package/components/inventory/constants.js +121 -0
  400. package/components/inventory/index.d.ts +9 -0
  401. package/components/inventory/index.d.ts.map +1 -0
  402. package/components/inventory/index.js +8 -0
  403. package/components/inventory/media-url.d.ts +6 -0
  404. package/components/inventory/media-url.d.ts.map +1 -0
  405. package/components/inventory/media-url.js +28 -0
  406. package/components/inventory/useInventoryData.d.ts +53 -0
  407. package/components/inventory/useInventoryData.d.ts.map +1 -0
  408. package/components/inventory/useInventoryData.js +332 -0
  409. package/components/knowledge-upload-image.d.ts +27 -0
  410. package/components/knowledge-upload-image.d.ts.map +1 -0
  411. package/components/knowledge-upload-image.js +146 -0
  412. package/components/labels.d.ts +6 -0
  413. package/components/labels.d.ts.map +1 -0
  414. package/components/labels.js +40 -0
  415. package/components/onboarding/ActivateStep.d.ts +2 -0
  416. package/components/onboarding/ActivateStep.d.ts.map +1 -0
  417. package/components/onboarding/ActivateStep.js +10 -0
  418. package/components/onboarding/ConnectionStep.d.ts +2 -0
  419. package/components/onboarding/ConnectionStep.d.ts.map +1 -0
  420. package/components/onboarding/ConnectionStep.js +609 -0
  421. package/components/onboarding/IdentityStep.d.ts +2 -0
  422. package/components/onboarding/IdentityStep.d.ts.map +1 -0
  423. package/components/onboarding/IdentityStep.js +102 -0
  424. package/components/onboarding/OnboardingPanel.d.ts +9 -0
  425. package/components/onboarding/OnboardingPanel.d.ts.map +1 -0
  426. package/components/onboarding/OnboardingPanel.js +24 -0
  427. package/components/onboarding/OnboardingStepNav.d.ts +2 -0
  428. package/components/onboarding/OnboardingStepNav.d.ts.map +1 -0
  429. package/components/onboarding/OnboardingStepNav.js +23 -0
  430. package/components/onboarding/PermissionsStep.d.ts +2 -0
  431. package/components/onboarding/PermissionsStep.d.ts.map +1 -0
  432. package/components/onboarding/PermissionsStep.js +7 -0
  433. package/components/onboarding/RpcStep.d.ts +2 -0
  434. package/components/onboarding/RpcStep.d.ts.map +1 -0
  435. package/components/onboarding/RpcStep.js +125 -0
  436. package/components/permissions/PermissionIcon.d.ts +4 -0
  437. package/components/permissions/PermissionIcon.d.ts.map +1 -0
  438. package/components/permissions/PermissionIcon.js +12 -0
  439. package/components/permissions/StreamingPermissions.d.ts +20 -0
  440. package/components/permissions/StreamingPermissions.d.ts.map +1 -0
  441. package/components/permissions/StreamingPermissions.js +177 -0
  442. package/components/plugins/showcase-data.d.ts +7 -0
  443. package/components/plugins/showcase-data.d.ts.map +1 -0
  444. package/components/plugins/showcase-data.js +464 -0
  445. package/components/shared/ShellHeaderControls.d.ts +27 -0
  446. package/components/shared/ShellHeaderControls.d.ts.map +1 -0
  447. package/components/shared/ShellHeaderControls.js +60 -0
  448. package/components/shared-companion-scene-context.d.ts +3 -0
  449. package/components/shared-companion-scene-context.d.ts.map +1 -0
  450. package/components/shared-companion-scene-context.js +13 -0
  451. package/components/skeletons.d.ts +17 -0
  452. package/components/skeletons.d.ts.map +1 -0
  453. package/components/skeletons.js +22 -0
  454. package/components/stream/ActivityFeed.d.ts +5 -0
  455. package/components/stream/ActivityFeed.d.ts.map +1 -0
  456. package/components/stream/ActivityFeed.js +57 -0
  457. package/components/stream/AvatarPip.d.ts +5 -0
  458. package/components/stream/AvatarPip.d.ts.map +1 -0
  459. package/components/stream/AvatarPip.js +6 -0
  460. package/components/stream/ChatContent.d.ts +6 -0
  461. package/components/stream/ChatContent.d.ts.map +1 -0
  462. package/components/stream/ChatContent.js +69 -0
  463. package/components/stream/ChatTicker.d.ts +5 -0
  464. package/components/stream/ChatTicker.d.ts.map +1 -0
  465. package/components/stream/ChatTicker.js +34 -0
  466. package/components/stream/IdleContent.d.ts +5 -0
  467. package/components/stream/IdleContent.d.ts.map +1 -0
  468. package/components/stream/IdleContent.js +17 -0
  469. package/components/stream/StatusBar.d.ts +36 -0
  470. package/components/stream/StatusBar.d.ts.map +1 -0
  471. package/components/stream/StatusBar.js +140 -0
  472. package/components/stream/StreamSettings.d.ts +33 -0
  473. package/components/stream/StreamSettings.d.ts.map +1 -0
  474. package/components/stream/StreamSettings.js +99 -0
  475. package/components/stream/StreamTerminal.d.ts +2 -0
  476. package/components/stream/StreamTerminal.d.ts.map +1 -0
  477. package/components/stream/StreamTerminal.js +52 -0
  478. package/components/stream/StreamVoiceConfig.d.ts +10 -0
  479. package/components/stream/StreamVoiceConfig.d.ts.map +1 -0
  480. package/components/stream/StreamVoiceConfig.js +88 -0
  481. package/components/stream/helpers.d.ts +32 -0
  482. package/components/stream/helpers.d.ts.map +1 -0
  483. package/components/stream/helpers.js +110 -0
  484. package/components/stream/overlays/OverlayLayer.d.ts +20 -0
  485. package/components/stream/overlays/OverlayLayer.d.ts.map +1 -0
  486. package/components/stream/overlays/OverlayLayer.js +24 -0
  487. package/components/stream/overlays/built-in/ActionTickerWidget.d.ts +8 -0
  488. package/components/stream/overlays/built-in/ActionTickerWidget.d.ts.map +1 -0
  489. package/components/stream/overlays/built-in/ActionTickerWidget.js +44 -0
  490. package/components/stream/overlays/built-in/AlertPopupWidget.d.ts +7 -0
  491. package/components/stream/overlays/built-in/AlertPopupWidget.d.ts.map +1 -0
  492. package/components/stream/overlays/built-in/AlertPopupWidget.js +62 -0
  493. package/components/stream/overlays/built-in/BrandingWidget.d.ts +7 -0
  494. package/components/stream/overlays/built-in/BrandingWidget.d.ts.map +1 -0
  495. package/components/stream/overlays/built-in/BrandingWidget.js +36 -0
  496. package/components/stream/overlays/built-in/CustomHtmlWidget.d.ts +26 -0
  497. package/components/stream/overlays/built-in/CustomHtmlWidget.d.ts.map +1 -0
  498. package/components/stream/overlays/built-in/CustomHtmlWidget.js +78 -0
  499. package/components/stream/overlays/built-in/PeonGlassWidget.d.ts +11 -0
  500. package/components/stream/overlays/built-in/PeonGlassWidget.d.ts.map +1 -0
  501. package/components/stream/overlays/built-in/PeonGlassWidget.js +188 -0
  502. package/components/stream/overlays/built-in/PeonHudWidget.d.ts +10 -0
  503. package/components/stream/overlays/built-in/PeonHudWidget.d.ts.map +1 -0
  504. package/components/stream/overlays/built-in/PeonHudWidget.js +168 -0
  505. package/components/stream/overlays/built-in/PeonSakuraWidget.d.ts +11 -0
  506. package/components/stream/overlays/built-in/PeonSakuraWidget.d.ts.map +1 -0
  507. package/components/stream/overlays/built-in/PeonSakuraWidget.js +213 -0
  508. package/components/stream/overlays/built-in/ThoughtBubbleWidget.d.ts +8 -0
  509. package/components/stream/overlays/built-in/ThoughtBubbleWidget.d.ts.map +1 -0
  510. package/components/stream/overlays/built-in/ThoughtBubbleWidget.js +59 -0
  511. package/components/stream/overlays/built-in/ViewerCountWidget.d.ts +7 -0
  512. package/components/stream/overlays/built-in/ViewerCountWidget.d.ts.map +1 -0
  513. package/components/stream/overlays/built-in/ViewerCountWidget.js +34 -0
  514. package/components/stream/overlays/built-in/index.d.ts +13 -0
  515. package/components/stream/overlays/built-in/index.d.ts.map +1 -0
  516. package/components/stream/overlays/built-in/index.js +12 -0
  517. package/components/stream/overlays/registry.d.ts +11 -0
  518. package/components/stream/overlays/registry.d.ts.map +1 -0
  519. package/components/stream/overlays/registry.js +16 -0
  520. package/components/stream/overlays/types.d.ts +67 -0
  521. package/components/stream/overlays/types.d.ts.map +1 -0
  522. package/components/stream/overlays/types.js +7 -0
  523. package/components/stream/overlays/useOverlayLayout.d.ts +27 -0
  524. package/components/stream/overlays/useOverlayLayout.d.ts.map +1 -0
  525. package/components/stream/overlays/useOverlayLayout.js +162 -0
  526. package/components/trajectory-format.d.ts +6 -0
  527. package/components/trajectory-format.d.ts.map +1 -0
  528. package/components/trajectory-format.js +43 -0
  529. package/components/ui-badges.d.ts +23 -0
  530. package/components/ui-badges.d.ts.map +1 -0
  531. package/components/ui-badges.js +38 -0
  532. package/components/ui-switch.d.ts +14 -0
  533. package/components/ui-switch.d.ts.map +1 -0
  534. package/components/ui-switch.js +15 -0
  535. package/components/vector-browser-three.d.ts +4 -0
  536. package/components/vector-browser-three.d.ts.map +1 -0
  537. package/components/vector-browser-three.js +21 -0
  538. package/config/branding.d.ts +49 -0
  539. package/config/branding.d.ts.map +1 -0
  540. package/config/branding.js +16 -0
  541. package/config/config-catalog.d.ts +376 -0
  542. package/config/config-catalog.d.ts.map +1 -0
  543. package/config/config-catalog.js +724 -0
  544. package/config/config-field.d.ts +68 -0
  545. package/config/config-field.d.ts.map +1 -0
  546. package/config/config-field.js +840 -0
  547. package/config/config-renderer.d.ts +176 -0
  548. package/config/config-renderer.d.ts.map +1 -0
  549. package/config/config-renderer.js +405 -0
  550. package/config/index.d.ts +6 -0
  551. package/config/index.d.ts.map +1 -0
  552. package/config/index.js +5 -0
  553. package/config/ui-renderer.d.ts +26 -0
  554. package/config/ui-renderer.d.ts.map +1 -0
  555. package/config/ui-renderer.js +815 -0
  556. package/config/ui-spec.d.ts +164 -0
  557. package/config/ui-spec.d.ts.map +1 -0
  558. package/config/ui-spec.js +13 -0
  559. package/events/index.d.ts +47 -0
  560. package/events/index.d.ts.map +1 -0
  561. package/events/index.js +43 -0
  562. package/hooks/index.d.ts +15 -0
  563. package/hooks/index.d.ts.map +1 -0
  564. package/hooks/useBugReport.d.ts +14 -0
  565. package/hooks/useBugReport.d.ts.map +1 -0
  566. package/hooks/useBugReport.js +18 -0
  567. package/hooks/useCanvasWindow.d.ts +38 -0
  568. package/hooks/useCanvasWindow.d.ts.map +1 -0
  569. package/hooks/useCanvasWindow.js +273 -0
  570. package/hooks/useChatAvatarVoice.d.ts +10 -0
  571. package/hooks/useChatAvatarVoice.d.ts.map +1 -0
  572. package/hooks/useChatAvatarVoice.js +71 -0
  573. package/hooks/useClickOutside.d.ts +6 -0
  574. package/hooks/useClickOutside.d.ts.map +1 -0
  575. package/hooks/useClickOutside.js +25 -0
  576. package/hooks/useContextMenu.d.ts +17 -0
  577. package/hooks/useContextMenu.d.ts.map +1 -0
  578. package/hooks/useContextMenu.js +100 -0
  579. package/hooks/useKeyboardShortcuts.d.ts +17 -0
  580. package/hooks/useKeyboardShortcuts.d.ts.map +1 -0
  581. package/hooks/useKeyboardShortcuts.js +67 -0
  582. package/hooks/useLifoSync.d.ts +18 -0
  583. package/hooks/useLifoSync.d.ts.map +1 -0
  584. package/hooks/useLifoSync.js +113 -0
  585. package/hooks/useMemoryMonitor.d.ts +87 -0
  586. package/hooks/useMemoryMonitor.d.ts.map +1 -0
  587. package/hooks/useMemoryMonitor.js +209 -0
  588. package/hooks/useRenderGuard.d.ts +17 -0
  589. package/hooks/useRenderGuard.d.ts.map +1 -0
  590. package/hooks/useRenderGuard.js +36 -0
  591. package/hooks/useRetakeCapture.d.ts +12 -0
  592. package/hooks/useRetakeCapture.d.ts.map +1 -0
  593. package/hooks/useRetakeCapture.js +60 -0
  594. package/hooks/useStreamPopoutNavigation.d.ts +3 -0
  595. package/hooks/useStreamPopoutNavigation.d.ts.map +1 -0
  596. package/hooks/useStreamPopoutNavigation.js +17 -0
  597. package/hooks/useTimeout.d.ts +11 -0
  598. package/hooks/useTimeout.d.ts.map +1 -0
  599. package/hooks/useTimeout.js +32 -0
  600. package/hooks/useVoiceChat.d.ts +94 -0
  601. package/hooks/useVoiceChat.d.ts.map +1 -0
  602. package/hooks/useVoiceChat.js +1074 -0
  603. package/hooks/useWhatsAppPairing.d.ts +11 -0
  604. package/hooks/useWhatsAppPairing.d.ts.map +1 -0
  605. package/hooks/useWhatsAppPairing.js +95 -0
  606. package/i18n/index.d.ts +7 -0
  607. package/i18n/index.d.ts.map +1 -0
  608. package/i18n/index.js +53 -0
  609. package/i18n/locales/en.json +1239 -0
  610. package/i18n/locales/es.json +1236 -0
  611. package/i18n/locales/ko.json +1236 -0
  612. package/i18n/locales/pt.json +1236 -0
  613. package/i18n/locales/zh-CN.json +1236 -0
  614. package/i18n/messages.d.ts +6 -0
  615. package/i18n/messages.d.ts.map +1 -0
  616. package/i18n/messages.js +14 -0
  617. package/index.d.ts +5 -0
  618. package/index.d.ts.map +1 -0
  619. package/navigation/index.d.ts +27 -0
  620. package/navigation/index.d.ts.map +1 -0
  621. package/navigation/index.js +232 -0
  622. package/onboarding-config.d.ts +25 -0
  623. package/onboarding-config.d.ts.map +1 -0
  624. package/onboarding-config.js +76 -0
  625. package/package.json +143 -53
  626. package/platform/browser-launch.d.ts +2 -0
  627. package/platform/browser-launch.d.ts.map +1 -0
  628. package/platform/browser-launch.js +109 -0
  629. package/platform/index.d.ts +14 -0
  630. package/platform/index.d.ts.map +1 -0
  631. package/platform/index.js +24 -0
  632. package/platform/init.d.ts +40 -0
  633. package/platform/init.d.ts.map +1 -0
  634. package/platform/init.js +160 -0
  635. package/platform/lifo.d.ts +51 -0
  636. package/platform/lifo.d.ts.map +1 -0
  637. package/platform/lifo.js +138 -0
  638. package/providers/index.d.ts +19 -0
  639. package/providers/index.d.ts.map +1 -0
  640. package/providers/index.js +80 -0
  641. package/shell-params.d.ts +12 -0
  642. package/shell-params.d.ts.map +1 -0
  643. package/shell-params.js +19 -0
  644. package/state/AppContext.d.ts +12 -0
  645. package/state/AppContext.d.ts.map +1 -0
  646. package/state/AppContext.js +5060 -0
  647. package/state/index.d.ts +7 -0
  648. package/state/index.d.ts.map +1 -0
  649. package/state/internal.d.ts +7 -0
  650. package/state/internal.d.ts.map +1 -0
  651. package/state/internal.js +6 -0
  652. package/state/onboarding-resume.d.ts +11 -0
  653. package/state/onboarding-resume.d.ts.map +1 -0
  654. package/state/onboarding-resume.js +189 -0
  655. package/state/parsers.d.ts +26 -0
  656. package/state/parsers.d.ts.map +1 -0
  657. package/state/parsers.js +255 -0
  658. package/state/persistence.d.ts +59 -0
  659. package/state/persistence.d.ts.map +1 -0
  660. package/state/persistence.js +326 -0
  661. package/state/shell-routing.d.ts +12 -0
  662. package/state/shell-routing.d.ts.map +1 -0
  663. package/state/shell-routing.js +25 -0
  664. package/state/types.d.ts +421 -0
  665. package/state/types.d.ts.map +1 -0
  666. package/state/types.js +75 -0
  667. package/state/ui-preferences.d.ts +3 -0
  668. package/state/ui-preferences.d.ts.map +1 -0
  669. package/state/ui-preferences.js +1 -0
  670. package/state/useApp.d.ts +4 -0
  671. package/state/useApp.d.ts.map +1 -0
  672. package/state/useApp.js +22 -0
  673. package/state/vrm.d.ts +30 -0
  674. package/state/vrm.d.ts.map +1 -0
  675. package/state/vrm.js +82 -0
  676. package/styles/anime.css +6321 -0
  677. package/styles/onboarding-game.css +1092 -0
  678. package/types/index.d.ts +657 -0
  679. package/types/index.d.ts.map +1 -0
  680. package/types/index.js +1 -0
  681. package/utils/asset-url.d.ts +26 -0
  682. package/utils/asset-url.d.ts.map +1 -0
  683. package/utils/asset-url.js +99 -0
  684. package/utils/assistant-text.d.ts +2 -0
  685. package/utils/assistant-text.d.ts.map +1 -0
  686. package/utils/assistant-text.js +161 -0
  687. package/utils/clipboard.d.ts +2 -0
  688. package/utils/clipboard.d.ts.map +1 -0
  689. package/utils/clipboard.js +38 -0
  690. package/utils/desktop-dialogs.d.ts +19 -0
  691. package/utils/desktop-dialogs.d.ts.map +1 -0
  692. package/utils/desktop-dialogs.js +50 -0
  693. package/utils/eliza-globals.d.ts +11 -0
  694. package/utils/eliza-globals.d.ts.map +1 -0
  695. package/utils/eliza-globals.js +33 -0
  696. package/utils/index.d.ts +8 -0
  697. package/utils/index.d.ts.map +1 -0
  698. package/utils/number-parsing.d.ts +44 -0
  699. package/utils/number-parsing.d.ts.map +1 -0
  700. package/utils/number-parsing.js +56 -0
  701. package/utils/openExternalUrl.d.ts +2 -0
  702. package/utils/openExternalUrl.d.ts.map +1 -0
  703. package/utils/openExternalUrl.js +17 -0
  704. package/utils/spoken-text.d.ts +2 -0
  705. package/utils/spoken-text.d.ts.map +1 -0
  706. package/utils/spoken-text.js +56 -0
  707. package/utils/streaming-text.d.ts +3 -0
  708. package/utils/streaming-text.d.ts.map +1 -0
  709. package/utils/streaming-text.js +87 -0
  710. package/voice/index.d.ts +2 -0
  711. package/voice/index.d.ts.map +1 -0
  712. package/voice/types.d.ts +25 -0
  713. package/voice/types.d.ts.map +1 -0
  714. package/voice/types.js +166 -0
  715. package/wallet-rpc.d.ts +8 -0
  716. package/wallet-rpc.d.ts.map +1 -0
  717. package/wallet-rpc.js +131 -0
  718. package/.turbo/turbo-build.log +0 -5
  719. package/src/App.tsx +0 -504
  720. package/src/actions/character.test.ts +0 -139
  721. package/src/actions/character.ts +0 -334
  722. package/src/actions/chat-helpers.ts +0 -100
  723. package/src/actions/cloud.ts +0 -59
  724. package/src/actions/index.ts +0 -12
  725. package/src/actions/lifecycle.ts +0 -175
  726. package/src/actions/onboarding.ts +0 -38
  727. package/src/actions/triggers.ts +0 -190
  728. package/src/ambient.d.ts +0 -33
  729. package/src/api/client.ts +0 -5659
  730. package/src/autonomy/index.ts +0 -477
  731. package/src/bridge/capacitor-bridge.ts +0 -295
  732. package/src/bridge/electrobun-rpc.ts +0 -78
  733. package/src/bridge/electrobun-runtime.ts +0 -28
  734. package/src/bridge/native-plugins.ts +0 -138
  735. package/src/bridge/plugin-bridge.ts +0 -352
  736. package/src/bridge/storage-bridge.ts +0 -162
  737. package/src/chat/index.ts +0 -250
  738. package/src/coding/index.ts +0 -43
  739. package/src/components/AdvancedPageView.tsx +0 -382
  740. package/src/components/AgentActivityBox.tsx +0 -49
  741. package/src/components/ApiKeyConfig.tsx +0 -222
  742. package/src/components/AppsPageView.tsx +0 -52
  743. package/src/components/AppsView.tsx +0 -293
  744. package/src/components/AvatarLoader.tsx +0 -104
  745. package/src/components/AvatarSelector.tsx +0 -223
  746. package/src/components/BscTradePanel.tsx +0 -549
  747. package/src/components/BugReportModal.tsx +0 -499
  748. package/src/components/CharacterRoster.tsx +0 -143
  749. package/src/components/CharacterView.tsx +0 -1575
  750. package/src/components/ChatAvatar.test.ts +0 -97
  751. package/src/components/ChatAvatar.tsx +0 -147
  752. package/src/components/ChatComposer.tsx +0 -330
  753. package/src/components/ChatMessage.tsx +0 -448
  754. package/src/components/ChatModalView.test.tsx +0 -118
  755. package/src/components/ChatModalView.tsx +0 -125
  756. package/src/components/ChatView.tsx +0 -992
  757. package/src/components/CloudOnboarding.tsx +0 -81
  758. package/src/components/CloudSourceControls.tsx +0 -85
  759. package/src/components/CodingAgentSettingsSection.tsx +0 -537
  760. package/src/components/CommandPalette.tsx +0 -284
  761. package/src/components/CompanionSceneHost.tsx +0 -517
  762. package/src/components/CompanionShell.tsx +0 -31
  763. package/src/components/CompanionView.tsx +0 -110
  764. package/src/components/ConfigPageView.tsx +0 -763
  765. package/src/components/ConfigSaveFooter.tsx +0 -41
  766. package/src/components/ConfirmModal.tsx +0 -379
  767. package/src/components/ConnectionFailedBanner.tsx +0 -91
  768. package/src/components/ConnectorsPageView.tsx +0 -13
  769. package/src/components/ConversationsSidebar.tsx +0 -279
  770. package/src/components/CustomActionEditor.tsx +0 -1127
  771. package/src/components/CustomActionsPanel.tsx +0 -288
  772. package/src/components/CustomActionsView.tsx +0 -325
  773. package/src/components/DatabasePageView.tsx +0 -55
  774. package/src/components/DatabaseView.tsx +0 -814
  775. package/src/components/ElizaCloudDashboard.tsx +0 -1696
  776. package/src/components/EmotePicker.tsx +0 -529
  777. package/src/components/ErrorBoundary.tsx +0 -76
  778. package/src/components/FineTuningView.tsx +0 -1080
  779. package/src/components/FlaminaGuide.test.tsx +0 -61
  780. package/src/components/FlaminaGuide.tsx +0 -212
  781. package/src/components/GameView.tsx +0 -551
  782. package/src/components/GameViewOverlay.tsx +0 -133
  783. package/src/components/GlobalEmoteOverlay.tsx +0 -152
  784. package/src/components/Header.test.tsx +0 -413
  785. package/src/components/Header.tsx +0 -400
  786. package/src/components/HeartbeatsView.tsx +0 -1003
  787. package/src/components/InventoryView.tsx +0 -393
  788. package/src/components/KnowledgeView.tsx +0 -1128
  789. package/src/components/LanguageDropdown.tsx +0 -192
  790. package/src/components/LifoMonitorPanel.tsx +0 -196
  791. package/src/components/LifoSandboxView.tsx +0 -499
  792. package/src/components/LoadingScreen.tsx +0 -112
  793. package/src/components/LogsPageView.tsx +0 -17
  794. package/src/components/LogsView.tsx +0 -239
  795. package/src/components/MediaGalleryView.tsx +0 -431
  796. package/src/components/MediaSettingsSection.tsx +0 -893
  797. package/src/components/MessageContent.tsx +0 -815
  798. package/src/components/MiladyBar.tsx +0 -103
  799. package/src/components/MiladyBarSettings.tsx +0 -872
  800. package/src/components/OnboardingWizard.test.tsx +0 -104
  801. package/src/components/OnboardingWizard.tsx +0 -249
  802. package/src/components/PairingView.tsx +0 -109
  803. package/src/components/PermissionsSection.tsx +0 -1184
  804. package/src/components/PluginsPageView.tsx +0 -9
  805. package/src/components/PluginsView.tsx +0 -3129
  806. package/src/components/ProviderSwitcher.tsx +0 -903
  807. package/src/components/RestartBanner.tsx +0 -76
  808. package/src/components/RuntimeView.tsx +0 -460
  809. package/src/components/SaveCommandModal.tsx +0 -211
  810. package/src/components/SecretsView.tsx +0 -569
  811. package/src/components/SecurityPageView.tsx +0 -242
  812. package/src/components/SettingsView.tsx +0 -825
  813. package/src/components/ShellOverlays.tsx +0 -41
  814. package/src/components/ShortcutsOverlay.tsx +0 -155
  815. package/src/components/SkillsView.tsx +0 -1435
  816. package/src/components/StartupFailureView.tsx +0 -63
  817. package/src/components/StreamView.tsx +0 -481
  818. package/src/components/StripeEmbeddedCheckout.tsx +0 -155
  819. package/src/components/SubscriptionStatus.tsx +0 -640
  820. package/src/components/SystemWarningBanner.tsx +0 -71
  821. package/src/components/ThemeToggle.tsx +0 -103
  822. package/src/components/TrajectoriesView.tsx +0 -526
  823. package/src/components/TrajectoryDetailView.tsx +0 -426
  824. package/src/components/VectorBrowserView.tsx +0 -1633
  825. package/src/components/VoiceConfigView.tsx +0 -674
  826. package/src/components/VrmStage.test.ts +0 -176
  827. package/src/components/VrmStage.tsx +0 -309
  828. package/src/components/WhatsAppQrOverlay.tsx +0 -230
  829. package/src/components/__tests__/chainConfig.test.ts +0 -220
  830. package/src/components/apps/AppDetailPane.tsx +0 -242
  831. package/src/components/apps/AppsCatalogGrid.tsx +0 -137
  832. package/src/components/apps/extensions/registry.ts +0 -13
  833. package/src/components/apps/extensions/types.ts +0 -9
  834. package/src/components/apps/helpers.ts +0 -43
  835. package/src/components/avatar/VrmAnimationLoader.test.ts +0 -164
  836. package/src/components/avatar/VrmAnimationLoader.ts +0 -151
  837. package/src/components/avatar/VrmBlinkController.ts +0 -118
  838. package/src/components/avatar/VrmCameraManager.ts +0 -407
  839. package/src/components/avatar/VrmEngine.ts +0 -2767
  840. package/src/components/avatar/VrmFootShadow.ts +0 -96
  841. package/src/components/avatar/VrmViewer.tsx +0 -421
  842. package/src/components/avatar/__tests__/VrmCameraManager.test.ts +0 -168
  843. package/src/components/avatar/__tests__/VrmEngine.test.ts +0 -1574
  844. package/src/components/avatar/mixamoVRMRigMap.ts +0 -62
  845. package/src/components/avatar/retargetMixamoFbxToVrm.ts +0 -144
  846. package/src/components/avatar/retargetMixamoGltfToVrm.ts +0 -119
  847. package/src/components/chainConfig.ts +0 -400
  848. package/src/components/companion/CompanionHeader.tsx +0 -50
  849. package/src/components/companion/CompanionSceneHost.tsx +0 -5
  850. package/src/components/companion/VrmStage.tsx +0 -2
  851. package/src/components/companion/__tests__/walletUtils.test.ts +0 -742
  852. package/src/components/companion/index.ts +0 -18
  853. package/src/components/companion/walletUtils.ts +0 -290
  854. package/src/components/companion-shell-styles.test.ts +0 -142
  855. package/src/components/companion-shell-styles.ts +0 -270
  856. package/src/components/confirm-delete-control.tsx +0 -69
  857. package/src/components/conversations/ConversationListItem.tsx +0 -185
  858. package/src/components/conversations/conversation-utils.ts +0 -151
  859. package/src/components/format.ts +0 -131
  860. package/src/components/index.ts +0 -96
  861. package/src/components/inventory/CopyableAddress.tsx +0 -41
  862. package/src/components/inventory/InventoryToolbar.tsx +0 -142
  863. package/src/components/inventory/NftGrid.tsx +0 -99
  864. package/src/components/inventory/TokenLogo.tsx +0 -71
  865. package/src/components/inventory/TokensTable.tsx +0 -216
  866. package/src/components/inventory/constants.ts +0 -170
  867. package/src/components/inventory/index.ts +0 -29
  868. package/src/components/inventory/media-url.test.ts +0 -38
  869. package/src/components/inventory/media-url.ts +0 -36
  870. package/src/components/inventory/useInventoryData.ts +0 -460
  871. package/src/components/knowledge-upload-image.ts +0 -215
  872. package/src/components/labels.ts +0 -46
  873. package/src/components/milady-bar/CloudCreditsChip.tsx +0 -61
  874. package/src/components/milady-bar/ProviderDropdown.tsx +0 -166
  875. package/src/components/milady-bar/WalletSummary.tsx +0 -61
  876. package/src/components/milady-bar/index.ts +0 -3
  877. package/src/components/onboarding/ActivateStep.tsx +0 -34
  878. package/src/components/onboarding/ConnectionStep.tsx +0 -1591
  879. package/src/components/onboarding/IdentityStep.tsx +0 -251
  880. package/src/components/onboarding/OnboardingPanel.tsx +0 -39
  881. package/src/components/onboarding/OnboardingStepNav.tsx +0 -41
  882. package/src/components/onboarding/PermissionsStep.tsx +0 -20
  883. package/src/components/onboarding/RpcStep.tsx +0 -402
  884. package/src/components/permissions/PermissionIcon.tsx +0 -25
  885. package/src/components/permissions/StreamingPermissions.tsx +0 -413
  886. package/src/components/plugins/showcase-data.ts +0 -481
  887. package/src/components/shared/ShellHeaderControls.tsx +0 -198
  888. package/src/components/shared-companion-scene-context.ts +0 -15
  889. package/src/components/skeletons.tsx +0 -88
  890. package/src/components/stream/ActivityFeed.tsx +0 -113
  891. package/src/components/stream/AvatarPip.tsx +0 -10
  892. package/src/components/stream/ChatContent.tsx +0 -126
  893. package/src/components/stream/ChatTicker.tsx +0 -55
  894. package/src/components/stream/IdleContent.tsx +0 -73
  895. package/src/components/stream/StatusBar.tsx +0 -463
  896. package/src/components/stream/StreamSettings.tsx +0 -506
  897. package/src/components/stream/StreamTerminal.tsx +0 -94
  898. package/src/components/stream/StreamVoiceConfig.tsx +0 -160
  899. package/src/components/stream/helpers.ts +0 -134
  900. package/src/components/stream/overlays/OverlayLayer.tsx +0 -75
  901. package/src/components/stream/overlays/built-in/ActionTickerWidget.tsx +0 -64
  902. package/src/components/stream/overlays/built-in/AlertPopupWidget.tsx +0 -87
  903. package/src/components/stream/overlays/built-in/BrandingWidget.tsx +0 -51
  904. package/src/components/stream/overlays/built-in/CustomHtmlWidget.tsx +0 -105
  905. package/src/components/stream/overlays/built-in/PeonGlassWidget.tsx +0 -265
  906. package/src/components/stream/overlays/built-in/PeonHudWidget.tsx +0 -247
  907. package/src/components/stream/overlays/built-in/PeonSakuraWidget.tsx +0 -278
  908. package/src/components/stream/overlays/built-in/ThoughtBubbleWidget.tsx +0 -77
  909. package/src/components/stream/overlays/built-in/ViewerCountWidget.tsx +0 -46
  910. package/src/components/stream/overlays/built-in/index.ts +0 -13
  911. package/src/components/stream/overlays/registry.ts +0 -22
  912. package/src/components/stream/overlays/types.ts +0 -90
  913. package/src/components/stream/overlays/useOverlayLayout.ts +0 -218
  914. package/src/components/trajectory-format.ts +0 -50
  915. package/src/components/ui-badges.tsx +0 -109
  916. package/src/components/ui-switch.tsx +0 -57
  917. package/src/components/vector-browser-three.ts +0 -29
  918. package/src/config/branding.ts +0 -67
  919. package/src/config/config-catalog.ts +0 -1092
  920. package/src/config/config-field.tsx +0 -1924
  921. package/src/config/config-renderer.tsx +0 -734
  922. package/src/config/index.ts +0 -12
  923. package/src/config/ui-renderer.tsx +0 -1751
  924. package/src/config/ui-spec.ts +0 -256
  925. package/src/events/index.ts +0 -96
  926. package/src/hooks/useBugReport.tsx +0 -43
  927. package/src/hooks/useCanvasWindow.ts +0 -372
  928. package/src/hooks/useChatAvatarVoice.ts +0 -111
  929. package/src/hooks/useClickOutside.ts +0 -31
  930. package/src/hooks/useContextMenu.ts +0 -127
  931. package/src/hooks/useKeyboardShortcuts.ts +0 -86
  932. package/src/hooks/useLifoSync.ts +0 -143
  933. package/src/hooks/useMemoryMonitor.ts +0 -334
  934. package/src/hooks/useMiladyBar.ts +0 -594
  935. package/src/hooks/useRenderGuard.ts +0 -43
  936. package/src/hooks/useRetakeCapture.ts +0 -68
  937. package/src/hooks/useStreamPopoutNavigation.ts +0 -27
  938. package/src/hooks/useTimeout.ts +0 -37
  939. package/src/hooks/useVoiceChat.ts +0 -1442
  940. package/src/hooks/useWhatsAppPairing.ts +0 -123
  941. package/src/i18n/index.ts +0 -76
  942. package/src/i18n/locales/en.json +0 -1195
  943. package/src/i18n/locales/es.json +0 -1195
  944. package/src/i18n/locales/ko.json +0 -1195
  945. package/src/i18n/locales/pt.json +0 -1195
  946. package/src/i18n/locales/zh-CN.json +0 -1195
  947. package/src/i18n/messages.ts +0 -21
  948. package/src/navigation/index.ts +0 -286
  949. package/src/navigation.test.ts +0 -189
  950. package/src/onboarding-config.test.ts +0 -104
  951. package/src/onboarding-config.ts +0 -122
  952. package/src/platform/browser-launch.test.ts +0 -94
  953. package/src/platform/browser-launch.ts +0 -149
  954. package/src/platform/index.ts +0 -58
  955. package/src/platform/init.ts +0 -238
  956. package/src/platform/lifo.ts +0 -225
  957. package/src/providers/index.ts +0 -108
  958. package/src/shell-params.test.ts +0 -48
  959. package/src/shell-params.ts +0 -36
  960. package/src/state/AppContext.tsx +0 -6415
  961. package/src/state/internal.ts +0 -91
  962. package/src/state/onboarding-resume.test.ts +0 -135
  963. package/src/state/onboarding-resume.ts +0 -263
  964. package/src/state/parsers.test.ts +0 -124
  965. package/src/state/parsers.ts +0 -309
  966. package/src/state/persistence.ts +0 -379
  967. package/src/state/shell-routing.ts +0 -39
  968. package/src/state/types.ts +0 -724
  969. package/src/state/ui-preferences.ts +0 -3
  970. package/src/state/useApp.ts +0 -23
  971. package/src/state/vrm.ts +0 -108
  972. package/src/styles/anime.css +0 -6324
  973. package/src/styles/onboarding-game.css +0 -976
  974. package/src/types/index.ts +0 -715
  975. package/src/types/react-test-renderer.d.ts +0 -45
  976. package/src/utils/asset-url.ts +0 -110
  977. package/src/utils/assistant-text.ts +0 -172
  978. package/src/utils/clipboard.ts +0 -41
  979. package/src/utils/desktop-dialogs.ts +0 -80
  980. package/src/utils/eliza-globals.ts +0 -44
  981. package/src/utils/number-parsing.ts +0 -125
  982. package/src/utils/openExternalUrl.ts +0 -20
  983. package/src/utils/spoken-text.ts +0 -65
  984. package/src/utils/streaming-text.ts +0 -120
  985. package/src/voice/types.ts +0 -197
  986. package/src/wallet-rpc.ts +0 -176
  987. package/test/app/AppContext.pty-sessions.test.tsx +0 -143
  988. package/test/app/MessageContent.test.tsx +0 -366
  989. package/test/app/PermissionsOnboarding.test.tsx +0 -358
  990. package/test/app/PermissionsSection.test.tsx +0 -575
  991. package/test/app/advanced-trajectory-fine-tuning.e2e.test.ts +0 -396
  992. package/test/app/agent-activity-box.test.tsx +0 -132
  993. package/test/app/agent-transfer-lock.test.ts +0 -279
  994. package/test/app/api-client-electrobun-fallback.test.ts +0 -139
  995. package/test/app/api-client-electron-fallback.test.ts +0 -139
  996. package/test/app/api-client-timeout.test.ts +0 -75
  997. package/test/app/api-client-ws.test.ts +0 -98
  998. package/test/app/api-client.ws-max-reconnect.test.ts +0 -139
  999. package/test/app/api-client.ws-reconnect.test.ts +0 -157
  1000. package/test/app/app-context-autonomy-events.test.ts +0 -559
  1001. package/test/app/apps-page-view.test.ts +0 -114
  1002. package/test/app/apps-view.test.ts +0 -768
  1003. package/test/app/autonomous-workflows.e2e.test.ts +0 -765
  1004. package/test/app/autonomy-events.test.ts +0 -150
  1005. package/test/app/avatar-selector.test.tsx +0 -52
  1006. package/test/app/bsc-trade-panel.test.tsx +0 -134
  1007. package/test/app/bug-report-modal.test.tsx +0 -353
  1008. package/test/app/character-action-bar-visibility.test.ts +0 -70
  1009. package/test/app/character-customization.e2e.test.ts +0 -1384
  1010. package/test/app/character-save-journey.test.ts +0 -1245
  1011. package/test/app/chat-advanced-features.e2e.test.ts +0 -706
  1012. package/test/app/chat-composer.test.tsx +0 -181
  1013. package/test/app/chat-journey.test.ts +0 -1075
  1014. package/test/app/chat-language-header.test.ts +0 -64
  1015. package/test/app/chat-message.test.tsx +0 -222
  1016. package/test/app/chat-modal-view.test.tsx +0 -191
  1017. package/test/app/chat-routine-filter.test.ts +0 -96
  1018. package/test/app/chat-send-lock.test.ts +0 -1465
  1019. package/test/app/chat-stream-api-client.test.tsx +0 -390
  1020. package/test/app/chat-view-game-modal.test.tsx +0 -661
  1021. package/test/app/chat-view.test.tsx +0 -877
  1022. package/test/app/cloud-api.e2e.test.ts +0 -258
  1023. package/test/app/cloud-login-flow.e2e.test.ts +0 -494
  1024. package/test/app/cloud-login-lock.test.ts +0 -416
  1025. package/test/app/command-palette.test.tsx +0 -184
  1026. package/test/app/command-registry.test.ts +0 -75
  1027. package/test/app/companion-greeting-wave.test.tsx +0 -431
  1028. package/test/app/companion-scene-host.test.tsx +0 -85
  1029. package/test/app/companion-stale-conversation.test.tsx +0 -447
  1030. package/test/app/companion-view.test.tsx +0 -690
  1031. package/test/app/confirm-delete-control.test.ts +0 -79
  1032. package/test/app/confirm-modal.test.tsx +0 -219
  1033. package/test/app/connection-mode-persistence.test.ts +0 -411
  1034. package/test/app/connectors-ui.e2e.test.ts +0 -508
  1035. package/test/app/conversations-sidebar-game-modal.test.tsx +0 -265
  1036. package/test/app/conversations-sidebar.test.tsx +0 -185
  1037. package/test/app/custom-actions-smoke.test.ts +0 -387
  1038. package/test/app/custom-avatar-api-client.test.ts +0 -207
  1039. package/test/app/desktop-utils.test.ts +0 -145
  1040. package/test/app/electrobun-rpc-bridge.test.ts +0 -83
  1041. package/test/app/events.test.ts +0 -88
  1042. package/test/app/export-import-flows.e2e.test.ts +0 -700
  1043. package/test/app/fine-tuning-view.test.ts +0 -471
  1044. package/test/app/game-view-auth-session.test.tsx +0 -187
  1045. package/test/app/game-view.test.ts +0 -444
  1046. package/test/app/global-emote-overlay.test.tsx +0 -106
  1047. package/test/app/header-status.test.tsx +0 -149
  1048. package/test/app/i18n.test.ts +0 -152
  1049. package/test/app/inventory-bsc-view.test.ts +0 -940
  1050. package/test/app/knowledge-ui.e2e.test.ts +0 -762
  1051. package/test/app/knowledge-upload-helpers.test.ts +0 -124
  1052. package/test/app/lifecycle-lock.test.ts +0 -267
  1053. package/test/app/lifo-popout-utils.test.ts +0 -208
  1054. package/test/app/lifo-safe-endpoint.test.ts +0 -34
  1055. package/test/app/loading-screen.test.tsx +0 -45
  1056. package/test/app/memory-monitor.test.ts +0 -331
  1057. package/test/app/milady-bar-regression.test.tsx +0 -519
  1058. package/test/app/milady-bar-settings.test.tsx +0 -1056
  1059. package/test/app/milady-bar.test.tsx +0 -583
  1060. package/test/app/navigation.test.tsx +0 -22
  1061. package/test/app/onboarding-e2e-journey.test.ts +0 -1409
  1062. package/test/app/onboarding-finish-lock.test.ts +0 -676
  1063. package/test/app/onboarding-language.test.tsx +0 -160
  1064. package/test/app/onboarding-steps.test.tsx +0 -375
  1065. package/test/app/open-external-url.test.ts +0 -65
  1066. package/test/app/pages-navigation-smoke.e2e.test.ts +0 -646
  1067. package/test/app/pairing-lock.test.ts +0 -260
  1068. package/test/app/pairing-view.test.tsx +0 -74
  1069. package/test/app/permissions-section.test.ts +0 -432
  1070. package/test/app/plugin-bridge.test.ts +0 -109
  1071. package/test/app/plugins-ui.e2e.test.ts +0 -605
  1072. package/test/app/plugins-view-game-modal.test.tsx +0 -686
  1073. package/test/app/plugins-view-toggle-restart.test.ts +0 -129
  1074. package/test/app/provider-dropdown-default.test.tsx +0 -300
  1075. package/test/app/restart-banner.test.tsx +0 -205
  1076. package/test/app/retake-capture.test.ts +0 -84
  1077. package/test/app/sandbox-api-client.test.ts +0 -108
  1078. package/test/app/save-command-modal.test.tsx +0 -109
  1079. package/test/app/secrets-view.test.tsx +0 -92
  1080. package/test/app/settings-control-styles.test.tsx +0 -142
  1081. package/test/app/settings-reset.e2e.test.ts +0 -726
  1082. package/test/app/settings-sections.e2e.test.ts +0 -614
  1083. package/test/app/shared-format.test.ts +0 -44
  1084. package/test/app/shared-switch.test.ts +0 -69
  1085. package/test/app/shell-mode-switching.e2e.test.ts +0 -841
  1086. package/test/app/shell-mode-tab-memory.test.tsx +0 -58
  1087. package/test/app/shell-overlays.test.tsx +0 -50
  1088. package/test/app/shortcuts-overlay.test.tsx +0 -111
  1089. package/test/app/sse-interruption.test.ts +0 -122
  1090. package/test/app/startup-asset-missing.e2e.test.ts +0 -126
  1091. package/test/app/startup-backend-missing.e2e.test.ts +0 -126
  1092. package/test/app/startup-chat.e2e.test.ts +0 -323
  1093. package/test/app/startup-conversation-restore.test.tsx +0 -381
  1094. package/test/app/startup-failure-view.test.tsx +0 -103
  1095. package/test/app/startup-onboarding.e2e.test.ts +0 -712
  1096. package/test/app/startup-timeout.test.tsx +0 -80
  1097. package/test/app/startup-token-401.e2e.test.ts +0 -103
  1098. package/test/app/stream-helpers.test.ts +0 -46
  1099. package/test/app/stream-popout-navigation.test.tsx +0 -41
  1100. package/test/app/stream-status-bar.test.tsx +0 -89
  1101. package/test/app/theme-toggle.test.tsx +0 -40
  1102. package/test/app/training-api-client.test.ts +0 -128
  1103. package/test/app/trajectories-view.test.tsx +0 -220
  1104. package/test/app/triggers-api-client.test.ts +0 -77
  1105. package/test/app/triggers-navigation.test.ts +0 -113
  1106. package/test/app/triggers-view.e2e.test.ts +0 -675
  1107. package/test/app/update-channel-lock.test.ts +0 -259
  1108. package/test/app/vector-browser.async-cleanup.test.tsx +0 -367
  1109. package/test/app/vector-browser.e2e.test.ts +0 -653
  1110. package/test/app/vrm-stage.test.tsx +0 -351
  1111. package/test/app/vrm-viewer.test.tsx +0 -298
  1112. package/test/app/wallet-api-save-lock.test.ts +0 -299
  1113. package/test/app/wallet-hooks.test.ts +0 -405
  1114. package/test/app/wallet-ui-flows.e2e.test.ts +0 -556
  1115. package/test/avatar/asset-url.test.ts +0 -90
  1116. package/test/avatar/avatar-selector.test.ts +0 -173
  1117. package/test/avatar/mixamo-vrm-rig-map.test.ts +0 -111
  1118. package/test/avatar/voice-chat-streaming-text.test.ts +0 -96
  1119. package/test/avatar/voice-chat.test.ts +0 -391
  1120. package/test/browser-extension/README.md +0 -138
  1121. package/test/browser-extension/test-harness.ts +0 -499
  1122. package/test/capacitor-plugins.e2e.test.ts +0 -168
  1123. package/test/test-types.ts +0 -5
  1124. package/test/ui/command-palette-commands.test.ts +0 -57
  1125. package/test/ui/ui-renderer.test.ts +0 -39
  1126. package/test/utils/assistant-text.test.ts +0 -68
  1127. package/test/utils/eliza-globals.test.ts +0 -59
  1128. package/test/utils/package-exports.test.ts +0 -70
  1129. package/test/utils/streaming-text.test.ts +0 -89
  1130. package/tsconfig.build.json +0 -19
  1131. package/tsconfig.json +0 -20
  1132. package/tsconfig.typecheck.json +0 -12
  1133. /package/{src/api/index.ts → api/index.js} +0 -0
  1134. /package/{src/bridge/index.ts → bridge/index.js} +0 -0
  1135. /package/{src/components/TriggersView.tsx → components/TriggersView.js} +0 -0
  1136. /package/{src/hooks/index.ts → hooks/index.js} +0 -0
  1137. /package/{src/index.ts → index.js} +0 -0
  1138. /package/{src/state/index.ts → state/index.js} +0 -0
  1139. /package/{src/styles → styles}/base.css +0 -0
  1140. /package/{src/styles → styles}/styles.css +0 -0
  1141. /package/{src/styles → styles}/xterm.css +0 -0
  1142. /package/{src/utils/index.ts → utils/index.js} +0 -0
  1143. /package/{src/voice/index.ts → voice/index.js} +0 -0
@@ -1,1751 +0,0 @@
1
- /**
2
- * ui-renderer.tsx — General-purpose json-render declarative UI renderer.
3
- *
4
- * Renders a UiSpec tree into React components. Supports:
5
- * - 35+ component types (layout, typography, form, data, feedback, nav, viz, interaction)
6
- * - State binding via statePath
7
- * - Dynamic values via $path references
8
- * - Conditional props via $cond expressions
9
- * - List rendering via repeat config
10
- * - Event bindings via on.press / on.change
11
- */
12
-
13
- import React, {
14
- createContext,
15
- useCallback,
16
- useContext,
17
- useMemo,
18
- useState,
19
- } from "react";
20
- import { useApp } from "../state";
21
- import { confirmDesktopAction, resolveAppAssetUrl } from "../utils";
22
- import { getByPath, setByPath } from "./config-catalog";
23
- import type {
24
- AuthState,
25
- CondExpr,
26
- UiAction,
27
- UiElement,
28
- UiRenderContext,
29
- UiSpec,
30
- ValidationCheck,
31
- VisibilityCondition,
32
- } from "./ui-spec";
33
-
34
- const UiContext = createContext<UiRenderContext | null>(null);
35
-
36
- const BLOCKED_LINK_PROTOCOLS = new Set([
37
- "javascript",
38
- "data",
39
- "vbscript",
40
- "file",
41
- ]);
42
-
43
- function useUiCtx(): UiRenderContext {
44
- const ctx = useContext(UiContext);
45
- if (!ctx) throw new Error("UiRenderer context missing");
46
- return ctx;
47
- }
48
-
49
- // ── Dynamic value resolution ────────────────────────────────────────
50
-
51
- function resolveProp(value: unknown, ctx: UiRenderContext): unknown {
52
- if (value == null) return value;
53
-
54
- // $data.path string prefix (simpler syntax for AI)
55
- if (typeof value === "string" && value.startsWith("$data.")) {
56
- const path = value.slice(6); // strip "$data."
57
- if (path.startsWith("$item/") && ctx.repeatItem) {
58
- return ctx.repeatItem[path.slice(6)];
59
- }
60
- return getByPath(ctx.state, path);
61
- }
62
-
63
- // $path reference
64
- if (
65
- typeof value === "object" &&
66
- "$path" in (value as Record<string, unknown>)
67
- ) {
68
- const path = (value as { $path: string }).$path;
69
- if (path.startsWith("$item/") && ctx.repeatItem) {
70
- return ctx.repeatItem[path.slice(6)];
71
- }
72
- return getByPath(ctx.state, path);
73
- }
74
-
75
- // $cond expression
76
- if (
77
- typeof value === "object" &&
78
- "$cond" in (value as Record<string, unknown>)
79
- ) {
80
- const expr = value as CondExpr;
81
- const cond = expr.$cond;
82
- let result = false;
83
-
84
- if (cond.eq) {
85
- const [a, b] = cond.eq.map((v) => resolveProp(v, ctx));
86
- result = a === b;
87
- } else if (cond.neq) {
88
- const [a, b] = cond.neq.map((v) => resolveProp(v, ctx));
89
- result = a !== b;
90
- } else if (cond.gt) {
91
- const [a, b] = cond.gt.map((v) => resolveProp(v, ctx));
92
- result = Number(a) > Number(b);
93
- } else if (cond.lt) {
94
- const [a, b] = cond.lt.map((v) => resolveProp(v, ctx));
95
- result = Number(a) < Number(b);
96
- } else if (cond.truthy) {
97
- result = !!resolveProp(cond.truthy, ctx);
98
- } else if (cond.falsy) {
99
- result = !resolveProp(cond.falsy, ctx);
100
- } else if (cond.path) {
101
- result = !!getByPath(ctx.state, cond.path);
102
- }
103
-
104
- return result ? resolveProp(expr.$then, ctx) : resolveProp(expr.$else, ctx);
105
- }
106
-
107
- // Object with path references
108
- if (
109
- typeof value === "object" &&
110
- value !== null &&
111
- "path" in (value as Record<string, unknown>)
112
- ) {
113
- const p = (value as { path: string }).path;
114
- if (p.startsWith("$item/") && ctx.repeatItem) {
115
- return ctx.repeatItem[p.slice(6)];
116
- }
117
- return getByPath(ctx.state, p);
118
- }
119
-
120
- return value;
121
- }
122
-
123
- function resolveProps(
124
- props: Record<string, unknown>,
125
- ctx: UiRenderContext,
126
- ): Record<string, unknown> {
127
- const resolved: Record<string, unknown> = {};
128
- for (const [k, v] of Object.entries(props)) {
129
- resolved[k] = resolveProp(v, ctx);
130
- }
131
- return resolved;
132
- }
133
-
134
- // ── Visibility evaluation ────────────────────────────────────────────
135
-
136
- export function evaluateUiVisibility(
137
- condition: VisibilityCondition | undefined,
138
- state: Record<string, unknown>,
139
- auth?: AuthState,
140
- ): boolean {
141
- if (!condition) return true;
142
-
143
- // Path-based
144
- if ("path" in condition && "operator" in condition) {
145
- const val = getByPath(state, condition.path);
146
- const target = condition.value;
147
- switch (condition.operator) {
148
- case "eq":
149
- return val === target;
150
- case "ne":
151
- return val !== target;
152
- case "gt":
153
- return Number(val) > Number(target);
154
- case "gte":
155
- return Number(val) >= Number(target);
156
- case "lt":
157
- return Number(val) < Number(target);
158
- case "lte":
159
- return Number(val) <= Number(target);
160
- default:
161
- return true;
162
- }
163
- }
164
-
165
- // Auth-based
166
- if ("auth" in condition) {
167
- if (!auth) return false;
168
- switch (condition.auth) {
169
- case "signedIn":
170
- return auth.isSignedIn;
171
- case "signedOut":
172
- return !auth.isSignedIn;
173
- case "admin":
174
- return auth.roles?.includes("admin") ?? false;
175
- default:
176
- return auth.roles?.includes(condition.auth) ?? false;
177
- }
178
- }
179
-
180
- // Logic combinators
181
- if ("and" in condition)
182
- return condition.and.every((c) => evaluateUiVisibility(c, state, auth));
183
- if ("or" in condition)
184
- return condition.or.some((c) => evaluateUiVisibility(c, state, auth));
185
- if ("not" in condition)
186
- return !evaluateUiVisibility(condition.not, state, auth);
187
-
188
- return true;
189
- }
190
-
191
- export function sanitizeLinkHref(href: unknown): string {
192
- // Strip ASCII control chars (tab, LF, CR) that browsers silently remove
193
- // during URL parsing, preventing bypass attacks like "java\nscript:alert(1)".
194
- const raw = String(href ?? "#")
195
- .trim()
196
- .replace(/[\t\n\r]/g, "");
197
- if (!raw) return "#";
198
-
199
- // Keep relative/hash links unchanged.
200
- if (
201
- raw.startsWith("#") ||
202
- raw.startsWith("/") ||
203
- raw.startsWith("./") ||
204
- raw.startsWith("../") ||
205
- raw.startsWith("?")
206
- ) {
207
- return raw;
208
- }
209
-
210
- const match = /^([a-zA-Z][a-zA-Z\d+.-]*):/.exec(raw);
211
- if (!match) return raw;
212
-
213
- const protocol = match[1].toLowerCase();
214
- if (BLOCKED_LINK_PROTOCOLS.has(protocol)) return "#";
215
-
216
- return raw;
217
- }
218
-
219
- // ── Built-in validators ─────────────────────────────────────────────
220
-
221
- const BUILTIN_VALIDATORS: Record<
222
- string,
223
- (value: unknown, args?: Record<string, unknown>) => boolean
224
- > = {
225
- required: (v) => v != null && v !== "",
226
- email: (v) => typeof v === "string" && /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(v),
227
- minLength: (v, args) =>
228
- typeof v === "string" && v.length >= Number(args?.length ?? 0),
229
- maxLength: (v, args) =>
230
- typeof v === "string" && v.length <= Number(args?.length ?? Infinity),
231
- pattern: (v, args) => {
232
- if (typeof v !== "string" || !args?.pattern) return true;
233
- try {
234
- return new RegExp(String(args.pattern)).test(v);
235
- } catch {
236
- return true;
237
- }
238
- },
239
- min: (v, args) => Number(v) >= Number(args?.value ?? -Infinity),
240
- max: (v, args) => Number(v) <= Number(args?.value ?? Infinity),
241
- };
242
-
243
- // ── Validation runner ───────────────────────────────────────────────
244
-
245
- export function runValidation(
246
- checks: ValidationCheck[],
247
- value: unknown,
248
- customValidators?: Record<
249
- string,
250
- (
251
- value: unknown,
252
- args?: Record<string, unknown>,
253
- ) => boolean | Promise<boolean>
254
- >,
255
- ): string[] {
256
- const errors: string[] = [];
257
- for (const check of checks) {
258
- const fn = BUILTIN_VALIDATORS[check.fn] ?? customValidators?.[check.fn];
259
- if (fn) {
260
- const result = fn(value, check.args);
261
- // Handle sync validators only (async handled separately)
262
- if (result === false) errors.push(check.message);
263
- }
264
- }
265
- return errors;
266
- }
267
-
268
- // ── State helpers ───────────────────────────────────────────────────
269
-
270
- function useStatePath(statePath: string | undefined, ctx: UiRenderContext) {
271
- const value = statePath ? getByPath(ctx.state, statePath) : undefined;
272
- const setValue = useCallback(
273
- (v: unknown) => {
274
- if (statePath) ctx.setState(statePath, v);
275
- },
276
- [statePath, ctx],
277
- );
278
- return [value, setValue] as const;
279
- }
280
-
281
- // ── Fire event action ───────────────────────────────────────────────
282
-
283
- function fireEvent(action: UiAction | undefined, ctx: UiRenderContext) {
284
- if (!action) return;
285
-
286
- const execute = () => {
287
- if (action.action === "setState" && action.params) {
288
- const p = action.params as { path: string; value: unknown };
289
- ctx.setState(p.path, p.value);
290
- if (action.onSuccess && ctx.onAction) {
291
- ctx.onAction(action.onSuccess.action, action.onSuccess.params);
292
- }
293
- } else if (ctx.onAction) {
294
- try {
295
- ctx.onAction(action.action, action.params);
296
- if (action.onSuccess)
297
- ctx.onAction(action.onSuccess.action, action.onSuccess.params);
298
- } catch {
299
- if (action.onError && ctx.onAction)
300
- ctx.onAction(action.onError.action, action.onError.params);
301
- }
302
- }
303
- };
304
-
305
- void (async () => {
306
- if (action.confirm) {
307
- const ok = await confirmDesktopAction({
308
- title: action.confirm.title,
309
- message: action.confirm.message ?? "",
310
- confirmLabel: "Confirm",
311
- cancelLabel: "Cancel",
312
- type: "question",
313
- });
314
- if (!ok) return;
315
- }
316
- execute();
317
- })();
318
- }
319
-
320
- // ── Gap / size maps ─────────────────────────────────────────────────
321
-
322
- const GAP: Record<string, string> = {
323
- none: "gap-0",
324
- xs: "gap-0.5",
325
- sm: "gap-1.5",
326
- md: "gap-3",
327
- lg: "gap-5",
328
- xl: "gap-8",
329
- };
330
-
331
- const ALIGN: Record<string, string> = {
332
- start: "items-start",
333
- center: "items-center",
334
- end: "items-end",
335
- stretch: "items-stretch",
336
- };
337
-
338
- const JUSTIFY: Record<string, string> = {
339
- start: "justify-start",
340
- center: "justify-center",
341
- end: "justify-end",
342
- between: "justify-between",
343
- around: "justify-around",
344
- };
345
-
346
- // ── Tailwind class constants ────────────────────────────────────────
347
-
348
- const INPUT_CLS =
349
- "w-full px-2 py-[5px] border border-[var(--border)] bg-[var(--card)] text-xs font-[var(--mono)] transition-colors focus:border-[var(--accent)] focus:outline-none box-border h-[30px]";
350
-
351
- // ══════════════════════════════════════════════════════════════════════
352
- // COMPONENT REGISTRY
353
- // ══════════════════════════════════════════════════════════════════════
354
-
355
- type ComponentFn = (
356
- props: Record<string, unknown>,
357
- children: React.ReactNode,
358
- ctx: UiRenderContext,
359
- el: UiElement,
360
- ) => React.ReactNode;
361
-
362
- // ── Layout ──────────────────────────────────────────────────────────
363
-
364
- const StackComponent: ComponentFn = (props, children) => {
365
- const dir = props.direction === "horizontal" ? "flex-row" : "flex-col";
366
- const gap = GAP[String(props.gap ?? "md")] ?? "gap-3";
367
- const align = ALIGN[String(props.align ?? "stretch")] ?? "";
368
- const justify = JUSTIFY[String(props.justify ?? "start")] ?? "";
369
- return (
370
- <div className={`flex ${dir} ${gap} ${align} ${justify}`}>{children}</div>
371
- );
372
- };
373
-
374
- const GridComponent: ComponentFn = (props, children) => {
375
- const cols = Number(props.columns ?? 2);
376
- const gap = GAP[String(props.gap ?? "md")] ?? "gap-3";
377
- return (
378
- <div
379
- className={`grid ${gap}`}
380
- style={{ gridTemplateColumns: `repeat(${cols}, 1fr)` }}
381
- >
382
- {children}
383
- </div>
384
- );
385
- };
386
-
387
- const CardComponent: ComponentFn = (props, children) => {
388
- const maxW = props.maxWidth === "full" ? "max-w-full" : "";
389
- return (
390
- <div
391
- className={`border border-[var(--border)] bg-[var(--card)] p-4 ${maxW}`}
392
- >
393
- {props.title ? (
394
- <div className="font-bold text-sm mb-0.5">{String(props.title)}</div>
395
- ) : null}
396
- {props.description ? (
397
- <div className="text-xs text-[var(--muted)] mb-3">
398
- {String(props.description)}
399
- </div>
400
- ) : null}
401
- {children}
402
- </div>
403
- );
404
- };
405
-
406
- const SeparatorComponent: ComponentFn = (props) => {
407
- const isVert = props.orientation === "vertical";
408
- return isVert ? (
409
- <div className="w-px bg-[var(--border)] self-stretch" />
410
- ) : (
411
- <hr className="border-t border-[var(--border)] my-2" />
412
- );
413
- };
414
-
415
- // ── Typography ──────────────────────────────────────────────────────
416
-
417
- const HeadingComponent: ComponentFn = (props) => {
418
- const text = String(props.text ?? "");
419
- const level = String(props.level ?? "h2");
420
- const cls =
421
- level === "h1"
422
- ? "text-xl font-bold"
423
- : level === "h3"
424
- ? "text-sm font-bold"
425
- : "text-base font-bold";
426
- return <div className={cls}>{text}</div>;
427
- };
428
-
429
- const TextComponent: ComponentFn = (props) => {
430
- const text = String(props.text ?? "");
431
- const variant = String(props.variant ?? "body");
432
- const cls: Record<string, string> = {
433
- body: "text-sm",
434
- caption: "text-xs text-[var(--muted)]",
435
- muted: "text-sm text-[var(--muted)]",
436
- lead: "text-sm font-medium",
437
- code: "text-xs font-mono bg-[var(--bg-hover)] px-1.5 py-0.5 border border-[var(--border)]",
438
- };
439
- return <div className={cls[variant] ?? "text-sm"}>{text}</div>;
440
- };
441
-
442
- // ── Form ────────────────────────────────────────────────────────────
443
-
444
- const InputComponent: ComponentFn = (props, _children, ctx, el) => {
445
- const [value, setValue] = useStatePath(
446
- props.statePath as string | undefined,
447
- ctx,
448
- );
449
- const sp = props.statePath as string | undefined;
450
- const errors = sp ? ctx.fieldErrors?.[sp] : undefined;
451
- const validateOn = el.validation?.validateOn ?? "blur";
452
-
453
- const handleChange = (v: string) => {
454
- setValue(v);
455
- if (validateOn === "change" && sp && ctx.validateField)
456
- ctx.validateField(sp);
457
- };
458
- const handleBlur = () => {
459
- if (validateOn === "blur" && sp && ctx.validateField) ctx.validateField(sp);
460
- };
461
-
462
- return (
463
- <div className="flex flex-col gap-1">
464
- {props.label ? (
465
- <span className="text-xs font-semibold">{String(props.label)}</span>
466
- ) : null}
467
- <input
468
- className={`${INPUT_CLS}${errors?.length ? " border-[var(--destructive)]" : ""}`}
469
- type={String(props.type ?? "text")}
470
- name={String(props.name ?? "")}
471
- placeholder={String(props.placeholder ?? "")}
472
- value={String(value ?? "")}
473
- onChange={(e) => handleChange(e.target.value)}
474
- onBlur={handleBlur}
475
- />
476
- {errors?.length ? (
477
- <div className="flex flex-col gap-0.5">
478
- {errors.map((err) => (
479
- <span key={err} className="text-[10px] text-[var(--destructive)]">
480
- {err}
481
- </span>
482
- ))}
483
- </div>
484
- ) : null}
485
- </div>
486
- );
487
- };
488
-
489
- const TextareaComponent: ComponentFn = (props, _children, ctx, el) => {
490
- const [value, setValue] = useStatePath(
491
- props.statePath as string | undefined,
492
- ctx,
493
- );
494
- const sp = props.statePath as string | undefined;
495
- const errors = sp ? ctx.fieldErrors?.[sp] : undefined;
496
- const validateOn = el.validation?.validateOn ?? "blur";
497
-
498
- const handleChange = (v: string) => {
499
- setValue(v);
500
- if (validateOn === "change" && sp && ctx.validateField)
501
- ctx.validateField(sp);
502
- };
503
- const handleBlur = () => {
504
- if (validateOn === "blur" && sp && ctx.validateField) ctx.validateField(sp);
505
- };
506
-
507
- return (
508
- <div className="flex flex-col gap-1">
509
- {props.label ? (
510
- <span className="text-xs font-semibold">{String(props.label)}</span>
511
- ) : null}
512
- <textarea
513
- className={`w-full px-2 py-[5px] border border-[var(--border)] bg-[var(--card)] text-xs font-[var(--mono)] transition-colors focus:border-[var(--accent)] focus:outline-none box-border min-h-[64px] resize-y${errors?.length ? " border-[var(--destructive)]" : ""}`}
514
- name={String(props.name ?? "")}
515
- placeholder={String(props.placeholder ?? "")}
516
- rows={Number(props.rows ?? 3)}
517
- value={String(value ?? "")}
518
- onChange={(e) => handleChange(e.target.value)}
519
- onBlur={handleBlur}
520
- />
521
- {errors?.length ? (
522
- <div className="flex flex-col gap-0.5">
523
- {errors.map((err) => (
524
- <span key={err} className="text-[10px] text-[var(--destructive)]">
525
- {err}
526
- </span>
527
- ))}
528
- </div>
529
- ) : null}
530
- </div>
531
- );
532
- };
533
-
534
- const SelectComponent: ComponentFn = (props, _children, ctx, el) => {
535
- const [value, setValue] = useStatePath(
536
- props.statePath as string | undefined,
537
- ctx,
538
- );
539
- const options =
540
- (props.options as Array<{ label: string; value: string }>) ?? [];
541
- const sp = props.statePath as string | undefined;
542
- const errors = sp ? ctx.fieldErrors?.[sp] : undefined;
543
- const validateOn = el.validation?.validateOn ?? "blur";
544
-
545
- const handleChange = (v: string) => {
546
- setValue(v);
547
- if (validateOn === "change" && sp && ctx.validateField)
548
- ctx.validateField(sp);
549
- };
550
- const handleBlur = () => {
551
- if (validateOn === "blur" && sp && ctx.validateField) ctx.validateField(sp);
552
- };
553
-
554
- return (
555
- <div className="flex flex-col gap-1">
556
- {props.label ? (
557
- <span className="text-xs font-semibold">{String(props.label)}</span>
558
- ) : null}
559
- <select
560
- className={`${INPUT_CLS} appearance-auto${errors?.length ? " border-[var(--destructive)]" : ""}`}
561
- value={String(value ?? "")}
562
- onChange={(e) => handleChange(e.target.value)}
563
- onBlur={handleBlur}
564
- >
565
- {props.placeholder ? (
566
- <option value="">{String(props.placeholder)}</option>
567
- ) : null}
568
- {options.map((o) => (
569
- <option key={o.value} value={o.value}>
570
- {o.label}
571
- </option>
572
- ))}
573
- </select>
574
- {errors?.length ? (
575
- <div className="flex flex-col gap-0.5">
576
- {errors.map((err) => (
577
- <span key={err} className="text-[10px] text-[var(--destructive)]">
578
- {err}
579
- </span>
580
- ))}
581
- </div>
582
- ) : null}
583
- </div>
584
- );
585
- };
586
-
587
- const CheckboxComponent: ComponentFn = (props, _children, ctx) => {
588
- const [value, setValue] = useStatePath(
589
- props.statePath as string | undefined,
590
- ctx,
591
- );
592
- return (
593
- <span className="flex items-center gap-2 text-xs cursor-pointer">
594
- <input
595
- type="checkbox"
596
- checked={!!value}
597
- onChange={(e) => setValue(e.target.checked)}
598
- />
599
- <span className="font-semibold">{String(props.label ?? "")}</span>
600
- </span>
601
- );
602
- };
603
-
604
- const RadioComponent: ComponentFn = (props, _children, ctx) => {
605
- const [value, setValue] = useStatePath(
606
- props.statePath as string | undefined,
607
- ctx,
608
- );
609
- const options =
610
- (props.options as Array<{ label: string; value: string }>) ?? [];
611
- return (
612
- <div className="flex flex-col gap-1">
613
- {props.label ? (
614
- <span className="text-xs font-semibold mb-0.5">
615
- {String(props.label)}
616
- </span>
617
- ) : null}
618
- {options.map((o) => (
619
- <span
620
- key={o.value}
621
- className="flex items-center gap-2 text-xs cursor-pointer"
622
- >
623
- <input
624
- type="radio"
625
- name={String(props.name ?? "")}
626
- value={o.value}
627
- checked={value === o.value}
628
- onChange={() => setValue(o.value)}
629
- />
630
- <span>{o.label}</span>
631
- </span>
632
- ))}
633
- </div>
634
- );
635
- };
636
-
637
- const SwitchComponent: ComponentFn = (props, _children, ctx) => {
638
- const [value, setValue] = useStatePath(
639
- props.statePath as string | undefined,
640
- ctx,
641
- );
642
- const checked = !!value;
643
- return (
644
- <span className="flex items-center gap-2 cursor-pointer">
645
- <button
646
- type="button"
647
- className={`relative w-9 h-[18px] transition-colors ${checked ? "bg-[var(--accent)]" : "bg-[var(--muted)]"}`}
648
- onClick={() => setValue(!checked)}
649
- >
650
- <div
651
- className={`absolute top-0.5 w-[14px] h-[14px] bg-white transition-all ${checked ? "left-5" : "left-0.5"}`}
652
- />
653
- </button>
654
- <span className="text-xs font-semibold">{String(props.label ?? "")}</span>
655
- </span>
656
- );
657
- };
658
-
659
- const SliderComponent: ComponentFn = (props, _children, ctx) => {
660
- const [value, setValue] = useStatePath(
661
- props.statePath as string | undefined,
662
- ctx,
663
- );
664
- return (
665
- <div className="flex flex-col gap-1">
666
- {props.label ? (
667
- <div className="flex justify-between text-xs">
668
- <span className="font-semibold">{String(props.label)}</span>
669
- <span className="text-[var(--muted)]">
670
- {String(value ?? props.min ?? 0)}
671
- </span>
672
- </div>
673
- ) : null}
674
- <input
675
- type="range"
676
- min={Number(props.min ?? 0)}
677
- max={Number(props.max ?? 100)}
678
- step={Number(props.step ?? 1)}
679
- value={Number(value ?? props.min ?? 0)}
680
- onChange={(e) => setValue(Number(e.target.value))}
681
- className="w-full"
682
- style={{ accentColor: "var(--accent)" }}
683
- />
684
- </div>
685
- );
686
- };
687
-
688
- const ToggleComponent: ComponentFn = (props, _children, ctx, el) => {
689
- const [value, setValue] = useStatePath(
690
- props.statePath as string | undefined,
691
- ctx,
692
- );
693
- const pressed = !!value;
694
- return (
695
- <button
696
- type="button"
697
- className={`px-3 py-1.5 text-xs border cursor-pointer transition-colors ${
698
- pressed
699
- ? "bg-[var(--accent)] text-[var(--accent-foreground,#1a1f26)] border-[var(--accent)]"
700
- : "bg-[var(--card)] text-[var(--text)] border-[var(--border)] hover:bg-[var(--bg-hover)]"
701
- }`}
702
- onClick={() => {
703
- setValue(!pressed);
704
- fireEvent(el.on?.press, ctx);
705
- }}
706
- >
707
- {String(props.label ?? "Toggle")}
708
- </button>
709
- );
710
- };
711
-
712
- const ToggleGroupComponent: ComponentFn = (props, _children, ctx) => {
713
- const [value, setValue] = useStatePath(
714
- props.statePath as string | undefined,
715
- ctx,
716
- );
717
- const items = (props.items as Array<{ label: string; value: string }>) ?? [];
718
- const isMultiple = props.type === "multiple";
719
- const selected = new Set(Array.isArray(value) ? (value as string[]) : []);
720
-
721
- const toggle = (v: string) => {
722
- if (isMultiple) {
723
- const next = new Set(selected);
724
- if (next.has(v)) next.delete(v);
725
- else next.add(v);
726
- setValue([...next]);
727
- } else {
728
- setValue(v);
729
- }
730
- };
731
-
732
- return (
733
- <div className="flex gap-1">
734
- {items.map((item) => {
735
- const active = isMultiple
736
- ? selected.has(item.value)
737
- : value === item.value;
738
- return (
739
- <button
740
- key={item.value}
741
- type="button"
742
- className={`px-2.5 py-1 text-xs border cursor-pointer transition-colors ${
743
- active
744
- ? "bg-[var(--accent)] text-[var(--accent-foreground,#1a1f26)] border-[var(--accent)]"
745
- : "bg-[var(--card)] text-[var(--text)] border-[var(--border)] hover:bg-[var(--bg-hover)]"
746
- }`}
747
- onClick={() => toggle(item.value)}
748
- >
749
- {item.label}
750
- </button>
751
- );
752
- })}
753
- </div>
754
- );
755
- };
756
-
757
- const ButtonGroupComponent: ComponentFn = (props, _children, ctx) => {
758
- const [value, setValue] = useStatePath(
759
- props.statePath as string | undefined,
760
- ctx,
761
- );
762
- const buttons =
763
- (props.buttons as Array<{ label: string; value: string }>) ?? [];
764
- return (
765
- <div className="flex gap-1">
766
- {buttons.map((btn) => {
767
- const active = value === btn.value;
768
- return (
769
- <button
770
- key={btn.value}
771
- type="button"
772
- className={`px-3 py-1.5 text-xs border cursor-pointer transition-colors ${
773
- active
774
- ? "bg-[var(--accent)] text-[var(--accent-foreground,#1a1f26)] border-[var(--accent)]"
775
- : "bg-[var(--card)] text-[var(--text)] border-[var(--border)] hover:bg-[var(--bg-hover)]"
776
- }`}
777
- onClick={() => setValue(btn.value)}
778
- >
779
- {btn.label}
780
- </button>
781
- );
782
- })}
783
- </div>
784
- );
785
- };
786
-
787
- // ── Data Display ────────────────────────────────────────────────────
788
-
789
- const TableComponent: ComponentFn = (props) => {
790
- const columns = (props.columns as string[]) ?? [];
791
- const rows = (props.rows as string[][]) ?? [];
792
- return (
793
- <div className="overflow-x-auto">
794
- {props.caption ? (
795
- <div className="text-xs font-semibold mb-1.5">
796
- {String(props.caption)}
797
- </div>
798
- ) : null}
799
- <table className="w-full text-xs border-collapse">
800
- <thead>
801
- <tr>
802
- {columns.map((col) => (
803
- <th
804
- key={col}
805
- className="text-left px-2.5 py-1.5 border-b border-[var(--border)] font-semibold text-[var(--muted)]"
806
- >
807
- {col}
808
- </th>
809
- ))}
810
- </tr>
811
- </thead>
812
- <tbody>
813
- {rows.map((row) => (
814
- <tr
815
- key={row.join("|")}
816
- className="border-b border-[var(--border)] last:border-b-0"
817
- >
818
- {row.map((cell) => (
819
- <td key={cell} className="px-2.5 py-1.5">
820
- {cell}
821
- </td>
822
- ))}
823
- </tr>
824
- ))}
825
- </tbody>
826
- </table>
827
- </div>
828
- );
829
- };
830
-
831
- const CarouselComponent: ComponentFn = (props) => {
832
- const { t } = useApp();
833
- const items =
834
- (props.items as Array<{ title: string; description: string }>) ?? [];
835
- const [current, setCurrent] = useState(0);
836
- return (
837
- <div className="relative">
838
- <div className="border border-[var(--border)] bg-[var(--bg-hover)] p-4 min-h-[60px]">
839
- {items[current] && (
840
- <div>
841
- <div className="text-xs font-bold">{items[current].title}</div>
842
- <div className="text-xs text-[var(--muted)] mt-0.5">
843
- {items[current].description}
844
- </div>
845
- </div>
846
- )}
847
- </div>
848
- <div className="flex justify-center gap-2 mt-2">
849
- <button
850
- type="button"
851
- className="text-xs px-2 py-0.5 border border-[var(--border)] bg-[var(--card)] cursor-pointer hover:bg-[var(--bg-hover)]"
852
- onClick={() => setCurrent((p) => Math.max(0, p - 1))}
853
- disabled={current === 0}
854
- >
855
- {t("ui-renderer.Larr")}
856
- </button>
857
- <span className="text-[10px] text-[var(--muted)] self-center">
858
- {current + 1} / {items.length}
859
- </span>
860
- <button
861
- type="button"
862
- className="text-xs px-2 py-0.5 border border-[var(--border)] bg-[var(--card)] cursor-pointer hover:bg-[var(--bg-hover)]"
863
- onClick={() => setCurrent((p) => Math.min(items.length - 1, p + 1))}
864
- disabled={current === items.length - 1}
865
- >
866
- {t("ui-renderer.Rarr")}
867
- </button>
868
- </div>
869
- </div>
870
- );
871
- };
872
-
873
- const BadgeComponent: ComponentFn = (props) => {
874
- const variant = String(props.variant ?? "default");
875
- const cls: Record<string, string> = {
876
- default: "bg-[var(--surface)] text-[var(--text)] border-[var(--border)]",
877
- success: "bg-[rgba(22,163,106,0.1)] text-[var(--ok)] border-[var(--ok)]",
878
- warning:
879
- "bg-[rgba(243,156,18,0.1)] text-[var(--warn,#f39c12)] border-[var(--warn,#f39c12)]",
880
- error:
881
- "bg-[rgba(231,76,60,0.1)] text-[var(--destructive)] border-[var(--destructive)]",
882
- info: "bg-[rgba(52,152,219,0.1)] text-[var(--accent)] border-[var(--accent)]",
883
- };
884
- return (
885
- <span
886
- className={`inline-block text-[10px] font-medium px-2 py-0.5 border ${cls[variant] ?? cls.default}`}
887
- >
888
- {String(props.text ?? "")}
889
- </span>
890
- );
891
- };
892
-
893
- const AvatarComponent: ComponentFn = (props) => {
894
- const name = String(props.name ?? "?");
895
- const size =
896
- props.size === "lg"
897
- ? "w-10 h-10 text-sm"
898
- : props.size === "sm"
899
- ? "w-6 h-6 text-[10px]"
900
- : "w-8 h-8 text-xs";
901
- const initials = name
902
- .split(" ")
903
- .map((w) => w[0])
904
- .join("")
905
- .slice(0, 2)
906
- .toUpperCase();
907
- return (
908
- <div
909
- className={`${size} rounded-full bg-[var(--accent)] text-[var(--accent-foreground,#1a1f26)] flex items-center justify-center font-bold shrink-0`}
910
- >
911
- {initials}
912
- </div>
913
- );
914
- };
915
-
916
- const ImageComponent: ComponentFn = (props) => {
917
- const src = props.src as string | undefined;
918
- const resolvedSrc = src ? resolveAppAssetUrl(src) : undefined;
919
- const alt = String(props.alt ?? "");
920
- const w = props.width ? `${props.width}px` : "auto";
921
- const h = props.height ? `${props.height}px` : "auto";
922
- return resolvedSrc ? (
923
- <img
924
- src={resolvedSrc}
925
- alt={alt}
926
- style={{ width: w, height: h }}
927
- className="object-cover border border-[var(--border)]"
928
- />
929
- ) : (
930
- <div
931
- className="bg-[var(--bg-hover)] border border-[var(--border)] flex items-center justify-center text-xs text-[var(--muted)]"
932
- style={{ width: w, height: h }}
933
- >
934
- {alt || "Image"}
935
- </div>
936
- );
937
- };
938
-
939
- // ── Feedback ────────────────────────────────────────────────────────
940
-
941
- const AlertComponent: ComponentFn = (props) => {
942
- const type = String(props.type ?? "info");
943
- const borderCls: Record<string, string> = {
944
- info: "border-[var(--accent)]",
945
- success: "border-[var(--ok)]",
946
- warning: "border-[var(--warn,#f39c12)]",
947
- error: "border-[var(--destructive)]",
948
- };
949
- const textCls: Record<string, string> = {
950
- info: "text-[var(--accent)]",
951
- success: "text-[var(--ok)]",
952
- warning: "text-[var(--warn,#f39c12)]",
953
- error: "text-[var(--destructive)]",
954
- };
955
- return (
956
- <div
957
- className={`border-l-[3px] ${borderCls[type] ?? ""} bg-[var(--bg-hover)] px-3 py-2`}
958
- >
959
- {props.title ? (
960
- <div className={`text-xs font-bold ${textCls[type] ?? ""}`}>
961
- {String(props.title)}
962
- </div>
963
- ) : null}
964
- {props.message ? (
965
- <div className="text-xs text-[var(--text)] mt-0.5">
966
- {String(props.message)}
967
- </div>
968
- ) : null}
969
- </div>
970
- );
971
- };
972
-
973
- const ProgressComponent: ComponentFn = (props) => {
974
- const value = Number(props.value ?? 0);
975
- const max = Number(props.max ?? 100);
976
- const pct = Math.min(100, Math.max(0, (value / max) * 100));
977
- return (
978
- <div className="flex flex-col gap-1">
979
- {props.label ? (
980
- <div className="flex justify-between text-xs">
981
- <span className="font-semibold">{String(props.label)}</span>
982
- <span className="text-[var(--muted)]">{Math.round(pct)}%</span>
983
- </div>
984
- ) : null}
985
- <div className="w-full h-2 bg-[var(--bg-hover)] border border-[var(--border)] overflow-hidden">
986
- <div
987
- className="h-full bg-[var(--accent)] transition-[width] duration-300"
988
- style={{ width: `${pct}%` }}
989
- />
990
- </div>
991
- </div>
992
- );
993
- };
994
-
995
- const RatingComponent: ComponentFn = (props) => {
996
- const value = Number(props.value ?? 0);
997
- const max = Number(props.max ?? 5);
998
- return (
999
- <div className="flex flex-col gap-1">
1000
- {props.label ? (
1001
- <div className="text-xs font-semibold">{String(props.label)}</div>
1002
- ) : null}
1003
- <div className="flex gap-0.5">
1004
- {Array.from({ length: max }, (_, i) => i + 1).map((starValue) => (
1005
- <span
1006
- key={starValue}
1007
- className={`text-sm ${starValue <= value ? "text-[var(--warn,#f39c12)]" : "text-[var(--muted)] opacity-30"}`}
1008
- >
1009
-
1010
- </span>
1011
- ))}
1012
- </div>
1013
- </div>
1014
- );
1015
- };
1016
-
1017
- const SkeletonComponent: ComponentFn = (props) => {
1018
- const w = props.width ? String(props.width) : "100%";
1019
- const h = props.height ? String(props.height) : "20px";
1020
- const rounded = props.rounded ? "rounded" : "";
1021
- return (
1022
- <div
1023
- className={`bg-[var(--bg-hover)] animate-pulse ${rounded}`}
1024
- style={{ width: w, height: h }}
1025
- />
1026
- );
1027
- };
1028
-
1029
- const SpinnerComponent: ComponentFn = (props) => {
1030
- const size =
1031
- props.size === "lg"
1032
- ? "w-8 h-8"
1033
- : props.size === "sm"
1034
- ? "w-4 h-4"
1035
- : "w-6 h-6";
1036
- return (
1037
- <div className="flex items-center gap-2">
1038
- <div
1039
- className={`${size} border-2 border-[var(--border)] border-t-[var(--accent)] rounded-full animate-spin`}
1040
- />
1041
- {props.label ? (
1042
- <span className="text-xs text-[var(--muted)]">
1043
- {String(props.label)}
1044
- </span>
1045
- ) : null}
1046
- </div>
1047
- );
1048
- };
1049
-
1050
- // ── Navigation ──────────────────────────────────────────────────────
1051
-
1052
- const ButtonComponent: ComponentFn = (props, _children, ctx, el) => {
1053
- const variant = String(props.variant ?? "primary");
1054
- const cls: Record<string, string> = {
1055
- primary:
1056
- "bg-[var(--accent)] text-[var(--accent-foreground,#1a1f26)] border-[var(--accent)] hover:opacity-90",
1057
- secondary:
1058
- "bg-[var(--card)] text-[var(--text)] border-[var(--border)] hover:bg-[var(--bg-hover)]",
1059
- danger:
1060
- "bg-[var(--destructive)] text-white border-[var(--destructive)] hover:opacity-90",
1061
- ghost:
1062
- "bg-transparent text-[var(--text)] border-transparent hover:bg-[var(--bg-hover)]",
1063
- };
1064
- return (
1065
- <button
1066
- type="button"
1067
- className={`px-3 py-1.5 text-xs font-medium border cursor-pointer transition-colors ${cls[variant] ?? cls.primary}`}
1068
- disabled={!!props.disabled}
1069
- onClick={() => fireEvent(el.on?.press, ctx)}
1070
- >
1071
- {String(props.label ?? "Button")}
1072
- </button>
1073
- );
1074
- };
1075
-
1076
- const LinkComponent: ComponentFn = (props, _children, ctx, el) => {
1077
- const safeHref = sanitizeLinkHref(props.href);
1078
-
1079
- return (
1080
- <a
1081
- href={safeHref}
1082
- className="text-xs text-[var(--accent)] underline hover:opacity-80"
1083
- target={props.external ? "_blank" : undefined}
1084
- rel={props.external ? "noopener noreferrer" : undefined}
1085
- onClick={(e) => {
1086
- if (el.on?.press) {
1087
- e.preventDefault();
1088
- fireEvent(el.on.press, ctx);
1089
- }
1090
- }}
1091
- >
1092
- {String(props.label ?? props.href ?? "Link")}
1093
- </a>
1094
- );
1095
- };
1096
-
1097
- const DropdownMenuComponent: ComponentFn = (props, _children, ctx) => {
1098
- const [open, setOpen] = useState(false);
1099
- const items = (props.items as Array<{ label: string; value: string }>) ?? [];
1100
- return (
1101
- <div className="relative inline-block">
1102
- <button
1103
- type="button"
1104
- className="px-3 py-1.5 text-xs border border-[var(--border)] bg-[var(--card)] cursor-pointer hover:bg-[var(--bg-hover)]"
1105
- onClick={() => setOpen(!open)}
1106
- >
1107
- {String(props.label ?? "Menu")} ▾
1108
- </button>
1109
- {open && (
1110
- <div className="absolute top-full left-0 mt-1 min-w-[120px] border border-[var(--border)] bg-[var(--card)] shadow-md z-10">
1111
- {items.map((item) => (
1112
- <button
1113
- key={item.value}
1114
- type="button"
1115
- className="block w-full text-left px-3 py-1.5 text-xs hover:bg-[var(--bg-hover)] cursor-pointer"
1116
- onClick={() => {
1117
- setOpen(false);
1118
- if (ctx.onAction)
1119
- ctx.onAction("menuSelect", {
1120
- value: item.value,
1121
- label: item.label,
1122
- });
1123
- }}
1124
- >
1125
- {item.label}
1126
- </button>
1127
- ))}
1128
- </div>
1129
- )}
1130
- </div>
1131
- );
1132
- };
1133
-
1134
- const TabsComponent: ComponentFn = (props, _children, ctx) => {
1135
- const tabs =
1136
- (props.tabs as Array<{ label: string; value: string; content: string }>) ??
1137
- [];
1138
- const [value, setValue] = useStatePath(
1139
- props.statePath as string | undefined,
1140
- ctx,
1141
- );
1142
- const active = String(value ?? props.defaultValue ?? tabs[0]?.value ?? "");
1143
- const activeTab = tabs.find((t) => t.value === active);
1144
- return (
1145
- <div>
1146
- <div className="flex border-b border-[var(--border)]">
1147
- {tabs.map((tab) => (
1148
- <button
1149
- key={tab.value}
1150
- type="button"
1151
- className={`px-3 py-1.5 text-xs cursor-pointer transition-colors ${
1152
- tab.value === active
1153
- ? "border-b-2 border-[var(--accent)] text-[var(--accent)] font-semibold"
1154
- : "text-[var(--muted)] hover:text-[var(--text)]"
1155
- }`}
1156
- onClick={() => setValue(tab.value)}
1157
- >
1158
- {tab.label}
1159
- </button>
1160
- ))}
1161
- </div>
1162
- {activeTab && <div className="py-3 text-xs">{activeTab.content}</div>}
1163
- </div>
1164
- );
1165
- };
1166
-
1167
- const PaginationComponent: ComponentFn = (props, _children, ctx) => {
1168
- const total = Number(props.totalPages ?? 1);
1169
- const [value, setValue] = useStatePath(
1170
- props.statePath as string | undefined,
1171
- ctx,
1172
- );
1173
- const current = Number(value ?? 1);
1174
- return (
1175
- <div className="flex items-center gap-1">
1176
- <button
1177
- type="button"
1178
- className="px-2 py-1 text-xs border border-[var(--border)] bg-[var(--card)] cursor-pointer hover:bg-[var(--bg-hover)] disabled:opacity-40"
1179
- disabled={current <= 1}
1180
- onClick={() => setValue(current - 1)}
1181
- >
1182
-
1183
- </button>
1184
- {Array.from({ length: total }, (_, i) => i + 1).map((page) => (
1185
- <button
1186
- key={page}
1187
- type="button"
1188
- className={`px-2 py-1 text-xs border cursor-pointer ${
1189
- page === current
1190
- ? "bg-[var(--accent)] text-[var(--accent-foreground,#1a1f26)] border-[var(--accent)]"
1191
- : "border-[var(--border)] bg-[var(--card)] hover:bg-[var(--bg-hover)]"
1192
- }`}
1193
- onClick={() => setValue(page)}
1194
- >
1195
- {page}
1196
- </button>
1197
- ))}
1198
- <button
1199
- type="button"
1200
- className="px-2 py-1 text-xs border border-[var(--border)] bg-[var(--card)] cursor-pointer hover:bg-[var(--bg-hover)] disabled:opacity-40"
1201
- disabled={current >= total}
1202
- onClick={() => setValue(current + 1)}
1203
- >
1204
-
1205
- </button>
1206
- </div>
1207
- );
1208
- };
1209
-
1210
- // ── Metric / KPI ────────────────────────────────────────────────────
1211
-
1212
- const MetricComponent: ComponentFn = (props) => {
1213
- const trend = props.trend as string | undefined;
1214
- const trendColor =
1215
- trend === "up"
1216
- ? "text-green-400"
1217
- : trend === "down"
1218
- ? "text-red-400"
1219
- : "text-[var(--muted)]";
1220
- return (
1221
- <div className="flex flex-col gap-0.5 p-3 rounded-lg border border-[var(--border)] bg-[var(--card)]">
1222
- <div className="text-[10px] text-[var(--muted)] uppercase tracking-wider font-medium">
1223
- {String(props.label ?? "")}
1224
- </div>
1225
- <div className="flex items-baseline gap-1.5">
1226
- <span className="text-xl font-semibold text-[var(--txt)]">
1227
- {props.value != null ? String(props.value) : "—"}
1228
- </span>
1229
- {props.unit != null && (
1230
- <span className="text-xs text-[var(--muted)]">
1231
- {String(props.unit)}
1232
- </span>
1233
- )}
1234
- </div>
1235
- {props.change != null && (
1236
- <div className={`text-[11px] font-medium ${trendColor}`}>
1237
- {String(props.change)}
1238
- </div>
1239
- )}
1240
- </div>
1241
- );
1242
- };
1243
-
1244
- // ── Visualization ───────────────────────────────────────────────────
1245
-
1246
- const BarGraphComponent: ComponentFn = (props) => {
1247
- const data = (props.data as Array<{ label: string; value: number }>) ?? [];
1248
- const maxVal = Math.max(...data.map((d) => d.value), 1);
1249
- return (
1250
- <div>
1251
- {props.title ? (
1252
- <div className="text-xs font-bold mb-2">{String(props.title)}</div>
1253
- ) : null}
1254
- <div className="flex items-end gap-2 h-[100px]">
1255
- {data.map((d) => (
1256
- <div
1257
- key={d.label}
1258
- className="flex-1 flex flex-col items-center gap-0.5"
1259
- >
1260
- <div className="text-[9px] text-[var(--muted)]">{d.value}</div>
1261
- <div
1262
- className="w-full bg-[var(--accent)] transition-all duration-300 min-h-[2px]"
1263
- style={{ height: `${(d.value / maxVal) * 80}px` }}
1264
- />
1265
- <div className="text-[9px] text-[var(--muted)] truncate max-w-full">
1266
- {d.label}
1267
- </div>
1268
- </div>
1269
- ))}
1270
- </div>
1271
- </div>
1272
- );
1273
- };
1274
-
1275
- const LineGraphComponent: ComponentFn = (props) => {
1276
- const data = (props.data as Array<{ label: string; value: number }>) ?? [];
1277
- const maxVal = Math.max(...data.map((d) => d.value), 1);
1278
- const h = 80;
1279
- const w = 100;
1280
- const points = data.map((d, i) => ({
1281
- x: (i / Math.max(data.length - 1, 1)) * w,
1282
- y: h - (d.value / maxVal) * h,
1283
- }));
1284
- const pathD = points
1285
- .map((p, i) => `${i === 0 ? "M" : "L"} ${p.x} ${p.y}`)
1286
- .join(" ");
1287
- return (
1288
- <div>
1289
- {props.title ? (
1290
- <div className="text-xs font-bold mb-2">{String(props.title)}</div>
1291
- ) : null}
1292
- <svg
1293
- viewBox={`0 0 ${w} ${h + 20}`}
1294
- className="w-full h-[100px]"
1295
- preserveAspectRatio="none"
1296
- >
1297
- <title>{String(props.title ?? "Line graph")}</title>
1298
- <path
1299
- d={pathD}
1300
- fill="none"
1301
- stroke="var(--accent)"
1302
- strokeWidth="2"
1303
- vectorEffect="non-scaling-stroke"
1304
- />
1305
- {points.map((p) => (
1306
- <circle
1307
- key={`${p.x}:${p.y}`}
1308
- cx={p.x}
1309
- cy={p.y}
1310
- r="3"
1311
- fill="var(--accent)"
1312
- vectorEffect="non-scaling-stroke"
1313
- />
1314
- ))}
1315
- {data.map((d, i) => (
1316
- <text
1317
- key={`${d.label}:${d.value}`}
1318
- x={points[i].x}
1319
- y={h + 14}
1320
- textAnchor="middle"
1321
- fontSize="8"
1322
- fill="var(--muted)"
1323
- >
1324
- {d.label}
1325
- </text>
1326
- ))}
1327
- </svg>
1328
- </div>
1329
- );
1330
- };
1331
-
1332
- // ── Interaction ─────────────────────────────────────────────────────
1333
-
1334
- const TooltipComponent: ComponentFn = (props) => {
1335
- const [show, setShow] = useState(false);
1336
- return (
1337
- <button
1338
- type="button"
1339
- className="relative inline-block"
1340
- onMouseEnter={() => setShow(true)}
1341
- onMouseLeave={() => setShow(false)}
1342
- onFocus={() => setShow(true)}
1343
- onBlur={() => setShow(false)}
1344
- onClick={() => setShow((prev) => !prev)}
1345
- >
1346
- <span className="text-xs text-[var(--accent)] underline cursor-help">
1347
- {String(props.text ?? "Hover")}
1348
- </span>
1349
- {show && (
1350
- <div className="absolute bottom-full left-1/2 -translate-x-1/2 mb-1 px-2 py-1 text-[10px] bg-[var(--text)] text-[var(--card)] whitespace-nowrap z-10">
1351
- {String(props.content ?? "")}
1352
- </div>
1353
- )}
1354
- </button>
1355
- );
1356
- };
1357
-
1358
- const PopoverComponent: ComponentFn = (props) => {
1359
- const [open, setOpen] = useState(false);
1360
- return (
1361
- <div className="relative inline-block">
1362
- <button
1363
- type="button"
1364
- className="text-xs text-[var(--accent)] underline cursor-pointer"
1365
- onClick={() => setOpen(!open)}
1366
- >
1367
- {String(props.trigger ?? "Click")}
1368
- </button>
1369
- {open && (
1370
- <div className="absolute top-full left-0 mt-1 p-3 border border-[var(--border)] bg-[var(--card)] shadow-md z-10 min-w-[150px]">
1371
- <div className="text-xs">{String(props.content ?? "")}</div>
1372
- <button
1373
- type="button"
1374
- className="text-[10px] text-[var(--muted)] mt-1 cursor-pointer hover:text-[var(--text)]"
1375
- onClick={() => setOpen(false)}
1376
- >
1377
- Close
1378
- </button>
1379
- </div>
1380
- )}
1381
- </div>
1382
- );
1383
- };
1384
-
1385
- const CollapsibleComponent: ComponentFn = (props, children) => {
1386
- const [open, setOpen] = useState(!!props.defaultOpen);
1387
- return (
1388
- <div className="border border-[var(--border)]">
1389
- <button
1390
- type="button"
1391
- className="w-full flex items-center gap-2 px-3 py-2 text-xs font-semibold cursor-pointer hover:bg-[var(--bg-hover)] transition-colors"
1392
- onClick={() => setOpen(!open)}
1393
- >
1394
- <span
1395
- className="text-[10px] transition-transform"
1396
- style={{ transform: open ? "rotate(90deg)" : "none" }}
1397
- >
1398
- &#9654;
1399
- </span>
1400
- {String(props.title ?? "Collapsible")}
1401
- </button>
1402
- {open && <div className="px-3 pb-3">{children}</div>}
1403
- </div>
1404
- );
1405
- };
1406
-
1407
- const AccordionComponent: ComponentFn = (props) => {
1408
- const items =
1409
- (props.items as Array<{ title: string; content: string }>) ?? [];
1410
- const isSingle = props.type === "single";
1411
- const [openSet, setOpenSet] = useState<Set<number>>(new Set());
1412
-
1413
- const toggle = (idx: number) => {
1414
- setOpenSet((prev) => {
1415
- const next = isSingle ? new Set<number>() : new Set(prev);
1416
- if (prev.has(idx)) next.delete(idx);
1417
- else next.add(idx);
1418
- return next;
1419
- });
1420
- };
1421
-
1422
- return (
1423
- <div className="border border-[var(--border)] divide-y divide-[var(--border)]">
1424
- {items.map((item, i) => (
1425
- <div key={`${item.title}:${item.content}`}>
1426
- <button
1427
- type="button"
1428
- className="w-full flex items-center gap-2 px-3 py-2 text-xs font-semibold cursor-pointer hover:bg-[var(--bg-hover)]"
1429
- onClick={() => toggle(i)}
1430
- >
1431
- <span
1432
- className="text-[10px] transition-transform"
1433
- style={{ transform: openSet.has(i) ? "rotate(90deg)" : "none" }}
1434
- >
1435
- &#9654;
1436
- </span>
1437
- {item.title}
1438
- </button>
1439
- {openSet.has(i) && (
1440
- <div className="px-3 pb-3 text-xs">{item.content}</div>
1441
- )}
1442
- </div>
1443
- ))}
1444
- </div>
1445
- );
1446
- };
1447
-
1448
- const DialogComponent: ComponentFn = (props, children, ctx) => {
1449
- const openPath = props.openPath as string | undefined;
1450
- const isOpen = openPath ? !!getByPath(ctx.state, openPath) : false;
1451
- if (!isOpen) return null;
1452
- const close = () => {
1453
- if (openPath) ctx.setState(openPath, false);
1454
- };
1455
- return (
1456
- <div
1457
- className="fixed inset-0 z-50 flex items-center justify-center bg-black/50"
1458
- onClick={(e) => {
1459
- if (e.target === e.currentTarget) close();
1460
- }}
1461
- onKeyDown={(e) => {
1462
- if (e.key === "Escape" || e.key === "Enter" || e.key === " ") {
1463
- e.preventDefault();
1464
- close();
1465
- }
1466
- }}
1467
- role="dialog"
1468
- aria-modal="true"
1469
- >
1470
- <div className="w-full max-w-md border border-[var(--border)] bg-[var(--card)] p-5 shadow-lg">
1471
- <div className="flex items-center justify-between mb-3">
1472
- <div>
1473
- {props.title ? (
1474
- <div className="font-bold text-sm">{String(props.title)}</div>
1475
- ) : null}
1476
- {props.description ? (
1477
- <div className="text-xs text-[var(--muted)] mt-0.5">
1478
- {String(props.description)}
1479
- </div>
1480
- ) : null}
1481
- </div>
1482
- <button
1483
- type="button"
1484
- className="text-[var(--muted)] hover:text-[var(--text)] text-lg leading-none px-1 cursor-pointer"
1485
- onClick={close}
1486
- >
1487
- ×
1488
- </button>
1489
- </div>
1490
- {children}
1491
- </div>
1492
- </div>
1493
- );
1494
- };
1495
-
1496
- const DrawerComponent: ComponentFn = (props, children, ctx) => {
1497
- const openPath = props.openPath as string | undefined;
1498
- const isOpen = openPath ? !!getByPath(ctx.state, openPath) : false;
1499
- if (!isOpen) return null;
1500
- const close = () => {
1501
- if (openPath) ctx.setState(openPath, false);
1502
- };
1503
- return (
1504
- <div
1505
- className="fixed inset-0 z-50 flex items-end bg-black/50"
1506
- onClick={(e) => {
1507
- if (e.target === e.currentTarget) close();
1508
- }}
1509
- onKeyDown={(e) => {
1510
- if (e.key === "Escape" || e.key === "Enter" || e.key === " ") {
1511
- e.preventDefault();
1512
- close();
1513
- }
1514
- }}
1515
- role="dialog"
1516
- aria-modal="true"
1517
- >
1518
- <div className="w-full max-h-[80vh] border-t border-[var(--border)] bg-[var(--card)] p-5 shadow-lg overflow-y-auto animate-[slide-up_200ms_ease]">
1519
- <div className="w-10 h-1 bg-[var(--border)] mx-auto mb-3 rounded-full" />
1520
- {props.title ? (
1521
- <div className="font-bold text-sm">{String(props.title)}</div>
1522
- ) : null}
1523
- {props.description ? (
1524
- <div className="text-xs text-[var(--muted)] mt-0.5 mb-3">
1525
- {String(props.description)}
1526
- </div>
1527
- ) : null}
1528
- {children}
1529
- </div>
1530
- </div>
1531
- );
1532
- };
1533
-
1534
- // ── Component map ───────────────────────────────────────────────────
1535
-
1536
- const COMPONENTS: Record<string, ComponentFn> = {
1537
- // Layout
1538
- Stack: StackComponent,
1539
- Grid: GridComponent,
1540
- Card: CardComponent,
1541
- Separator: SeparatorComponent,
1542
- // Typography
1543
- Heading: HeadingComponent,
1544
- Text: TextComponent,
1545
- // Form
1546
- Input: InputComponent,
1547
- Textarea: TextareaComponent,
1548
- Select: SelectComponent,
1549
- Checkbox: CheckboxComponent,
1550
- Radio: RadioComponent,
1551
- Switch: SwitchComponent,
1552
- Slider: SliderComponent,
1553
- Toggle: ToggleComponent,
1554
- ToggleGroup: ToggleGroupComponent,
1555
- ButtonGroup: ButtonGroupComponent,
1556
- // Data
1557
- Table: TableComponent,
1558
- Carousel: CarouselComponent,
1559
- Badge: BadgeComponent,
1560
- Avatar: AvatarComponent,
1561
- Image: ImageComponent,
1562
- // Feedback
1563
- Alert: AlertComponent,
1564
- Progress: ProgressComponent,
1565
- Rating: RatingComponent,
1566
- Skeleton: SkeletonComponent,
1567
- Spinner: SpinnerComponent,
1568
- // Navigation
1569
- Button: ButtonComponent,
1570
- Link: LinkComponent,
1571
- DropdownMenu: DropdownMenuComponent,
1572
- Tabs: TabsComponent,
1573
- Pagination: PaginationComponent,
1574
- // Metric
1575
- Metric: MetricComponent,
1576
- // Visualization
1577
- BarGraph: BarGraphComponent,
1578
- LineGraph: LineGraphComponent,
1579
- // Interaction
1580
- Tooltip: TooltipComponent,
1581
- Popover: PopoverComponent,
1582
- Collapsible: CollapsibleComponent,
1583
- Accordion: AccordionComponent,
1584
- Dialog: DialogComponent,
1585
- Drawer: DrawerComponent,
1586
- };
1587
-
1588
- // ══════════════════════════════════════════════════════════════════════
1589
- // ELEMENT RENDERER
1590
- // ══════════════════════════════════════════════════════════════════════
1591
-
1592
- function ElementRenderer({ elementId }: { elementId: string }) {
1593
- const { t } = useApp();
1594
- const ctx = useUiCtx();
1595
- const el = ctx.spec.elements[elementId];
1596
- if (!el) return null;
1597
-
1598
- // Visibility check
1599
- if (el.visible && !evaluateUiVisibility(el.visible, ctx.state, ctx.auth)) {
1600
- return null;
1601
- }
1602
-
1603
- const component = COMPONENTS[el.type];
1604
- if (!component) {
1605
- return (
1606
- <div className="text-[10px] text-[var(--destructive)] border border-dashed border-[var(--destructive)] p-2">
1607
- {t("ui-renderer.UnknownComponent")} {el.type}
1608
- </div>
1609
- );
1610
- }
1611
-
1612
- const resolvedProps = resolveProps(el.props, ctx);
1613
-
1614
- // Handle repeat / list rendering
1615
- if (el.repeat) {
1616
- const listData = getByPath(ctx.state, el.repeat.path) as
1617
- | Array<Record<string, unknown>>
1618
- | undefined;
1619
- if (!Array.isArray(listData)) return null;
1620
-
1621
- return (
1622
- <>
1623
- {listData.map((item) => {
1624
- const itemCtx: UiRenderContext = { ...ctx, repeatItem: item };
1625
- const childNodes = el.children.map((childId) => (
1626
- <UiContext.Provider key={childId} value={itemCtx}>
1627
- <ElementRenderer elementId={childId} />
1628
- </UiContext.Provider>
1629
- ));
1630
- const repeatKey = el.repeat?.key;
1631
- const itemKey = String(
1632
- repeatKey != null ? item[repeatKey] : Math.random(),
1633
- );
1634
- return (
1635
- <React.Fragment key={itemKey}>
1636
- {component(resolvedProps, childNodes, itemCtx, el)}
1637
- </React.Fragment>
1638
- );
1639
- })}
1640
- </>
1641
- );
1642
- }
1643
-
1644
- // Normal rendering: resolve children
1645
- const childNodes = el.children.map((childId) => (
1646
- <ElementRenderer key={childId} elementId={childId} />
1647
- ));
1648
-
1649
- return <>{component(resolvedProps, childNodes, ctx, el)}</>;
1650
- }
1651
-
1652
- // ══════════════════════════════════════════════════════════════════════
1653
- // ROOT RENDERER
1654
- // ══════════════════════════════════════════════════════════════════════
1655
-
1656
- export interface UiRendererProps {
1657
- spec: UiSpec;
1658
- onAction?: (action: string, params?: Record<string, unknown>) => void;
1659
- loading?: boolean;
1660
- auth?: AuthState;
1661
- validators?: Record<
1662
- string,
1663
- (
1664
- value: unknown,
1665
- args?: Record<string, unknown>,
1666
- ) => boolean | Promise<boolean>
1667
- >;
1668
- }
1669
-
1670
- export function UiRenderer({
1671
- spec,
1672
- onAction,
1673
- loading,
1674
- auth,
1675
- validators,
1676
- }: UiRendererProps) {
1677
- const [state, setStateRaw] = useState<Record<string, unknown>>(() => ({
1678
- ...spec.state,
1679
- }));
1680
- const [fieldErrors, setFieldErrors] = useState<Record<string, string[]>>({});
1681
-
1682
- const setState = useCallback((path: string, value: unknown) => {
1683
- setStateRaw((prev) => {
1684
- const next = { ...prev };
1685
- setByPath(next, path, value);
1686
- return next;
1687
- });
1688
- }, []);
1689
-
1690
- const validateField = useCallback(
1691
- (statePath: string) => {
1692
- // Find the element that has this statePath
1693
- for (const el of Object.values(spec.elements)) {
1694
- if (el.props.statePath === statePath && el.validation) {
1695
- const value = getByPath(state, statePath);
1696
- const errors = runValidation(el.validation.checks, value, validators);
1697
- setFieldErrors((prev) => ({ ...prev, [statePath]: errors }));
1698
- return;
1699
- }
1700
- }
1701
- },
1702
- [spec.elements, state, validators],
1703
- );
1704
-
1705
- const ctx = useMemo<UiRenderContext>(
1706
- () => ({
1707
- spec,
1708
- state,
1709
- setState,
1710
- onAction,
1711
- auth,
1712
- loading,
1713
- validators,
1714
- fieldErrors,
1715
- validateField,
1716
- }),
1717
- [
1718
- spec,
1719
- state,
1720
- setState,
1721
- onAction,
1722
- auth,
1723
- loading,
1724
- validators,
1725
- fieldErrors,
1726
- validateField,
1727
- ],
1728
- );
1729
-
1730
- // Loading skeleton when no elements
1731
- if (loading && Object.keys(spec.elements).length === 0) {
1732
- return (
1733
- <div className="flex flex-col gap-3 animate-pulse">
1734
- <div className="h-4 bg-[var(--bg-hover)] w-3/4" />
1735
- <div className="h-3 bg-[var(--bg-hover)] w-1/2" />
1736
- <div className="h-3 bg-[var(--bg-hover)] w-5/6" />
1737
- </div>
1738
- );
1739
- }
1740
-
1741
- return (
1742
- <UiContext.Provider value={ctx}>
1743
- <ElementRenderer elementId={spec.root} />
1744
- </UiContext.Provider>
1745
- );
1746
- }
1747
-
1748
- /** Get the full list of supported component types. */
1749
- export function getSupportedComponents(): string[] {
1750
- return Object.keys(COMPONENTS);
1751
- }