@vgai/editor 0.2.0 → 0.4.0-canary.20260715.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (430) hide show
  1. package/README.md +24 -0
  2. package/dist/assets/axe-C7YBtOuM.js +30 -0
  3. package/dist/assets/browserAll-DDtGGE48.js +1 -0
  4. package/dist/assets/create-runtime-DbTlBlKG.js +1 -0
  5. package/dist/assets/{game-BI111o5f.js → game-BE0r7DMI.js} +3 -3
  6. package/dist/assets/game-BdTHR2_X.js +1 -0
  7. package/dist/assets/{game-pt_1lQLv.js → game-C3iQGSqo.js} +1 -1
  8. package/dist/assets/game-CcHfYxjP.js +1 -0
  9. package/dist/assets/game-Cqzj_lpD.js +1 -0
  10. package/dist/assets/game-DSZdeCHu.js +1 -0
  11. package/dist/assets/game-Dch9sAPc.js +1 -0
  12. package/dist/assets/{game-xsOho_wg.js → game-SAFn90pA.js} +3 -3
  13. package/dist/assets/game-loop-DMIgSMV-.js +1 -0
  14. package/dist/assets/{game-source-CvidN7AB.js → game-source-Dk83w26t.js} +1 -1
  15. package/dist/assets/{index-Bp5cecD6.js → index-4idIsHHJ.js} +2 -2
  16. package/dist/assets/{index-DL7RcQ0n.js → index-C-LhOTBN.js} +1 -1
  17. package/dist/assets/{index-Cs8xwv3e.js → index-CDkxceqE.js} +1 -1
  18. package/dist/assets/index-CQEfi217.js +15412 -0
  19. package/dist/assets/index-Dvi-V0NE.css +1 -0
  20. package/dist/assets/ingest-siblings-s0P5I1Ub.js +1 -0
  21. package/dist/assets/mount-manifest-DXMOlF79.js +1 -0
  22. package/dist/assets/react-18-C9eHn8x1.js +1 -0
  23. package/dist/assets/webworkerAll-Fn0e-ouF.js +1 -0
  24. package/dist/assets/world-documents-GM0a9Kv7.js +1 -0
  25. package/dist/index.html +15 -13
  26. package/dist/ingest/racing-game/vgai.game.json +5 -4
  27. package/dist/ingest/simcity/vgai.game.json +5 -4
  28. package/dist/ingest/tanks/vgai.game.json +5 -4
  29. package/dist/project-scripts.bundle.js +3917 -0
  30. package/dist/scenes/untitled.vscn.json +2 -0
  31. package/dist-server/packaged.mjs +7697 -3435
  32. package/package.json +31 -4
  33. package/scripts/probe-reporter.ts +349 -0
  34. package/scripts/run-probe.ts +2260 -0
  35. package/server/asset-catalog-audit.ts +268 -0
  36. package/server/asset-catalog-v2.ts +146 -0
  37. package/server/asset-library-routes.ts +276 -58
  38. package/server/canonical-path.ts +1 -1
  39. package/server/dev.ts +148 -44
  40. package/server/editor-server.ts +888 -61
  41. package/server/editor-sse.ts +115 -4
  42. package/server/harness-chat-service.ts +796 -0
  43. package/server/local-asset-catalog.ts +157 -22
  44. package/server/packaged.ts +51 -21
  45. package/server/process-shutdown.ts +136 -0
  46. package/server/prod.ts +9 -6
  47. package/server/project-hmr-files.ts +41 -0
  48. package/server/project-operations.ts +343 -0
  49. package/server/project-optimize-deps-entries.ts +4 -4
  50. package/server/project-output-writer.ts +156 -0
  51. package/server/project-validation.ts +140 -0
  52. package/server/project-view.ts +8 -50
  53. package/server/server-utils.ts +75 -10
  54. package/server/session-registry.ts +12 -0
  55. package/src/EditorContext.tsx +107 -3
  56. package/src/action-registry.ts +115 -17
  57. package/src/adapter-resolver.ts +213 -478
  58. package/src/asset-events.ts +64 -1
  59. package/src/asset-preview.ts +906 -0
  60. package/src/asset-selection.ts +121 -0
  61. package/src/asset-workflow/asset-capabilities.ts +259 -0
  62. package/src/asset-workflow/asset-editor-errors.ts +46 -0
  63. package/src/asset-workflow/asset-import-pipeline.ts +176 -0
  64. package/src/asset-workflow/asset-library-query.ts +107 -0
  65. package/src/asset-workflow/asset-types.ts +192 -0
  66. package/src/asset-workflow/asset-workflow-quality.ts +65 -0
  67. package/src/asset-workflow/import-contract.ts +113 -0
  68. package/src/asset-workflow/model-conversion.ts +126 -0
  69. package/src/asset-workflow/model-inspection.ts +185 -0
  70. package/src/asset-workflow/project-asset-commands.ts +23 -0
  71. package/src/asset-workflow/project-asset-health.ts +153 -0
  72. package/src/asset-workflow/project-asset-operations.ts +119 -0
  73. package/src/asset-workflow/thumbnail-system.ts +172 -0
  74. package/src/authoring/active-systems.ts +15 -0
  75. package/src/authoring/boundary-authoring-adapter.ts +16 -5
  76. package/src/authoring/composite-authoring-adapter.ts +305 -124
  77. package/src/authoring/design-time-layers.ts +300 -117
  78. package/src/authoring/edit-mode-authoring.ts +278 -293
  79. package/src/authoring/embed-only-adapter.ts +4 -2
  80. package/src/authoring/first-party-hierarchy-menu.ts +7 -2
  81. package/src/authoring/first-party-inspector/AddSectionMenu.tsx +5 -12
  82. package/src/authoring/first-party-inspector/EnvironmentSection.tsx +53 -126
  83. package/src/authoring/first-party-inspector/HeaderSection.tsx +54 -65
  84. package/src/authoring/first-party-inspector/is-first-party-selection.ts +30 -11
  85. package/src/authoring/first-party-inspector/register.tsx +13 -2
  86. package/src/authoring/ingest-authoring-adapter.ts +142 -45
  87. package/src/authoring/mount-failure-report.ts +5 -5
  88. package/src/authoring/provenance.ts +41 -0
  89. package/src/authoring/react-dom-authoring-adapter.ts +92 -92
  90. package/src/authoring/react-inspector-section.tsx +489 -51
  91. package/src/authoring/react-world-authoring-adapter.ts +541 -306
  92. package/src/authoring/story-overlay.ts +1 -1
  93. package/src/authoring/story-types.ts +11 -0
  94. package/src/authoring/vgai-scene-authoring-adapter.ts +54 -25
  95. package/src/authoring/viewport-tool-context.ts +78 -0
  96. package/src/authoring/world-canvas-viewport-state.ts +35 -0
  97. package/src/authoring/world-hidden-viewport.ts +186 -0
  98. package/src/authoring/world-pan-state.ts +33 -17
  99. package/src/authoring/world-session-state.ts +1 -1
  100. package/src/authoring/world2d-authoring-adapter.ts +109 -52
  101. package/src/availability-tick.ts +56 -0
  102. package/src/browser-play-entry.ts +5 -5
  103. package/src/browser-project-scripts.ts +1 -0
  104. package/src/build-identity.ts +15 -0
  105. package/src/command-listener.ts +893 -19
  106. package/src/components/AlignToolbar.tsx +74 -63
  107. package/src/components/AppRoot.tsx +193 -26
  108. package/src/components/ApplicationMenus.tsx +272 -0
  109. package/src/components/AssetBrowser.tsx +1450 -293
  110. package/src/components/AssetEditorShell.tsx +141 -0
  111. package/src/components/AssetImportDetails.tsx +218 -0
  112. package/src/components/AssetLibraryPanel.tsx +14 -0
  113. package/src/components/CameraInfo.tsx +11 -20
  114. package/src/components/CenterDocuments.tsx +585 -0
  115. package/src/components/CommandPalette.tsx +75 -30
  116. package/src/components/ConsolePanel.css +55 -0
  117. package/src/components/ConsolePanel.tsx +57 -112
  118. package/src/components/DebugConsolePanel.tsx +461 -0
  119. package/src/components/DebuggerPanel.tsx +165 -0
  120. package/src/components/DefaultEditorLayout.tsx +167 -231
  121. package/src/components/GameHierarchy.tsx +873 -290
  122. package/src/components/GamePerformanceOverlay.tsx +46 -0
  123. package/src/components/HarnessChatPanel.tsx +2352 -0
  124. package/src/components/HistoryPanel.tsx +226 -0
  125. package/src/components/Inspector.tsx +153 -99
  126. package/src/components/InspectorToolSection.tsx +6 -4
  127. package/src/components/MountFailureBanner.tsx +31 -48
  128. package/src/components/NetworkSection.tsx +25 -14
  129. package/src/components/OnlineAssetBrowser.tsx +794 -343
  130. package/src/components/OverlayReportBanner.tsx +38 -64
  131. package/src/components/PerformancePanel.tsx +206 -0
  132. package/src/components/PlayBar.tsx +93 -263
  133. package/src/components/PrefabSaveDialog.tsx +55 -127
  134. package/src/components/ProjectHeader.css +60 -0
  135. package/src/components/ProjectHeader.tsx +170 -105
  136. package/src/components/ProjectScreen.tsx +246 -184
  137. package/src/components/ReactCanvasControls.tsx +185 -0
  138. package/src/components/ResolutionPicker.tsx +85 -0
  139. package/src/components/RootActivateDialog.tsx +39 -68
  140. package/src/components/SaveDialog.tsx +55 -127
  141. package/src/components/SaveStatus.tsx +11 -29
  142. package/src/components/StartupLoadingScreen.tsx +96 -0
  143. package/src/components/StateWatchPanel.tsx +302 -0
  144. package/src/components/StatsOverlay.tsx +12 -5
  145. package/src/components/StatusBar.tsx +64 -0
  146. package/src/components/ThemeManagerDialog.css +89 -0
  147. package/src/components/ThemeManagerDialog.tsx +371 -0
  148. package/src/components/ToolHost.tsx +26 -15
  149. package/src/components/Toolbar.tsx +117 -214
  150. package/src/components/VgaiVoxelLogo.tsx +89 -0
  151. package/src/components/ViewportOverlay.tsx +97 -172
  152. package/src/components/ViewportPanel.tsx +130 -31
  153. package/src/components/WorkspaceDock.tsx +891 -0
  154. package/src/components/WorldSelectionOverlay.tsx +51 -63
  155. package/src/components/WorldTextEditor.tsx +9 -5
  156. package/src/components/asset-documents.tsx +390 -0
  157. package/src/components/asset-editor-persistence.ts +44 -0
  158. package/src/components/asset-selection-section.tsx +338 -0
  159. package/src/components/asset-viewers/AudioViewer.tsx +73 -21
  160. package/src/components/asset-viewers/GenericJsonViewer.tsx +26 -11
  161. package/src/components/asset-viewers/ImageViewer.tsx +43 -11
  162. package/src/components/asset-viewers/InputMapViewer.tsx +512 -134
  163. package/src/components/asset-viewers/MaterialAssetEditor.tsx +540 -0
  164. package/src/components/asset-viewers/ModelViewer.tsx +805 -121
  165. package/src/components/asset-viewers/OnlineAssetDetail.tsx +177 -60
  166. package/src/components/asset-viewers/SourceAssetViewer.tsx +121 -0
  167. package/src/components/asset-workflow.css +506 -0
  168. package/src/components/build-documents.tsx +696 -0
  169. package/src/components/core-utilities.tsx +75 -0
  170. package/src/components/data-documents.tsx +364 -0
  171. package/src/components/{DataPanel.tsx → data-editor.tsx} +138 -288
  172. package/src/components/debugger-panel-state.ts +57 -0
  173. package/src/components/inspector-widgets/AlignmentGrid.tsx +8 -14
  174. package/src/components/inspector-widgets/BorderEditor.tsx +41 -33
  175. package/src/components/inspector-widgets/ColorPicker.tsx +39 -39
  176. package/src/components/inspector-widgets/FontPicker.tsx +13 -21
  177. package/src/components/inspector-widgets/GradientEditor.tsx +11 -19
  178. package/src/components/inspector-widgets/ScrubbableInput.tsx +6 -3
  179. package/src/components/inspector-widgets/ShadowEditor.tsx +20 -33
  180. package/src/components/inspector-widgets/shared.tsx +90 -49
  181. package/src/components/inspectors/AnimationSection.tsx +39 -40
  182. package/src/components/inspectors/AudioSection.tsx +28 -39
  183. package/src/components/inspectors/BoneAttachmentSection.tsx +19 -24
  184. package/src/components/inspectors/CameraSection.tsx +14 -23
  185. package/src/components/inspectors/ComponentsSection.tsx +39 -43
  186. package/src/components/inspectors/JointsSection.tsx +34 -43
  187. package/src/components/inspectors/LightSection.tsx +90 -35
  188. package/src/components/inspectors/MaterialSection.tsx +137 -174
  189. package/src/components/inspectors/MeshSection.tsx +9 -17
  190. package/src/components/inspectors/NavigationSection.tsx +8 -15
  191. package/src/components/inspectors/ParticleSection.tsx +91 -76
  192. package/src/components/inspectors/PhysicsSection.tsx +42 -46
  193. package/src/components/inspectors/PostProcessingSection.tsx +28 -36
  194. package/src/components/inspectors/RenderingSection.tsx +12 -20
  195. package/src/components/inspectors/ShadowSection.tsx +7 -8
  196. package/src/components/inspectors/SplineSection.tsx +31 -42
  197. package/src/components/inspectors/TransformSection.tsx +14 -22
  198. package/src/components/patterns/Dialog.tsx +95 -0
  199. package/src/components/patterns/Fields.tsx +44 -0
  200. package/src/components/patterns/List.tsx +25 -0
  201. package/src/components/patterns/StateSurface.tsx +40 -0
  202. package/src/components/patterns/Surfaces.tsx +115 -0
  203. package/src/components/patterns/Tabs.tsx +80 -0
  204. package/src/components/patterns/Toolbar.tsx +51 -0
  205. package/src/components/patterns/Tree.tsx +72 -0
  206. package/src/components/primitives/Button.tsx +46 -0
  207. package/src/components/primitives/ColorInput.tsx +11 -47
  208. package/src/components/primitives/EditorIcon.tsx +99 -0
  209. package/src/components/primitives/FormControls.tsx +71 -0
  210. package/src/components/primitives/JsonInput.tsx +15 -2
  211. package/src/components/primitives/Layout.tsx +100 -0
  212. package/src/components/primitives/Menu.tsx +105 -0
  213. package/src/components/primitives/NumberInput.tsx +8 -35
  214. package/src/components/primitives/Panel.tsx +49 -44
  215. package/src/components/primitives/SectionHeader.tsx +10 -28
  216. package/src/components/primitives/Text.tsx +46 -0
  217. package/src/components/primitives/Tooltip.tsx +20 -12
  218. package/src/components/primitives/Vec3Input.tsx +3 -0
  219. package/src/components/primitives/banner-tones.ts +33 -0
  220. package/src/components/primitives/editor-icons.ts +102 -0
  221. package/src/components/primitives/panel-header-styles.ts +30 -0
  222. package/src/components/project-operation-documents.tsx +226 -0
  223. package/src/components/status-contributions.tsx +175 -0
  224. package/src/components/story-documents-register.ts +15 -0
  225. package/src/components/story-documents.tsx +1185 -0
  226. package/src/components/tool-documents.tsx +110 -0
  227. package/src/components/workspace-dock.css +293 -0
  228. package/src/components/workspace-history.ts +33 -0
  229. package/src/components/world-documents.tsx +145 -0
  230. package/src/components/xstate-documents.tsx +209 -0
  231. package/src/composite-screenshot.ts +248 -0
  232. package/src/design-system/index.ts +70 -0
  233. package/src/design-system-stories/Foundation.stories.tsx +183 -0
  234. package/src/design-system-stories/Patterns.stories.tsx +251 -0
  235. package/src/design-system-stories/Workspace.stories.tsx +538 -0
  236. package/src/doctor/report.ts +57 -13
  237. package/src/editor-api.ts +295 -31
  238. package/src/editor-compatibility.ts +200 -0
  239. package/src/editor-console.ts +35 -17
  240. package/src/editor-hotkeys.ts +85 -33
  241. package/src/editor-store.ts +538 -233
  242. package/src/editor-viewport.ts +160 -34
  243. package/src/entity-factory.ts +14 -3
  244. package/src/gizmo-registry.ts +21 -5
  245. package/src/harness-chat-editor-context.ts +37 -0
  246. package/src/harness-chat-indicator.ts +68 -0
  247. package/src/harness-chat-layout.ts +53 -0
  248. package/src/harness-chat-lifecycle.ts +170 -0
  249. package/src/harness-chat-reconnect.ts +85 -0
  250. package/src/harness-chat-types.ts +409 -0
  251. package/src/hierarchy-drop.ts +50 -0
  252. package/src/hierarchy-expansion-state.ts +100 -0
  253. package/src/hierarchy-menu-registry.ts +1 -1
  254. package/src/hierarchy-projection.ts +76 -0
  255. package/src/history/editor-session.ts +21 -0
  256. package/src/history/history-commands.ts +147 -0
  257. package/src/history/history-service.ts +904 -0
  258. package/src/history/json-history-resource.ts +165 -0
  259. package/src/history/persistence-coordinator.ts +35 -0
  260. package/src/history/project-file-history.ts +266 -0
  261. package/src/history/project-root-history-backends.ts +53 -0
  262. package/src/history/resource-registry.ts +209 -0
  263. package/src/history/snapshot-store.ts +108 -0
  264. package/src/history/source-history-backend.ts +374 -0
  265. package/src/history/types.ts +100 -0
  266. package/src/hmr-registration-group.ts +67 -0
  267. package/src/hmr-stable-react-context.ts +23 -0
  268. package/src/hosted-example.ts +12 -2
  269. package/src/hotkeys.ts +89 -18
  270. package/src/ingest/discovery-react.ts +9 -10
  271. package/src/ingest/discovery.ts +4 -4
  272. package/src/ingest/discovery2d.ts +5 -5
  273. package/src/ingest/games/bloom-composer/vgai.game.json +3 -3
  274. package/src/ingest/games/embed-bundle/vgai.game.json +3 -3
  275. package/src/ingest/games/games-fps/vgai.game.json +3 -3
  276. package/src/ingest/games/iframe-reachable/vgai.game.json +3 -3
  277. package/src/ingest/games/interactive-cubes/vgai.game.json +3 -3
  278. package/src/ingest/games/mismatched-three/vgai.game.json +3 -3
  279. package/src/ingest/games/own-three-bundled/vgai.game.json +3 -3
  280. package/src/ingest/games/pointerlock-maze/vgai.game.json +7 -4
  281. package/src/ingest/games-2d/bubbo-bubbo/vgai.game.json +3 -3
  282. package/src/ingest/games-2d/bunnymark/vgai.game.json +3 -3
  283. package/src/ingest/games-2d/flappy/vgai.game.json +3 -3
  284. package/src/ingest/games-2d/flappy-pixi/vgai.game.json +3 -3
  285. package/src/ingest/games-2d/puzzling-potions/vgai.game.json +3 -3
  286. package/src/ingest/games-2d/tilemap-camera/vgai.game.json +3 -3
  287. package/src/ingest/games-react/react-rpg/vgai.game.json +3 -3
  288. package/src/ingest/types.ts +1 -1
  289. package/src/ingest-mode.ts +47 -52
  290. package/src/ingest-siblings.ts +23 -33
  291. package/src/initial-scene.ts +1 -2
  292. package/src/main.tsx +16 -8
  293. package/src/manifest-project.ts +10 -12
  294. package/src/model-thumbnail.ts +261 -26
  295. package/src/module-mode.ts +44 -50
  296. package/src/play-log-events.ts +26 -0
  297. package/src/play-mode.ts +495 -401
  298. package/src/play-scene-adoption.ts +23 -0
  299. package/src/playground/main.ts +68 -24
  300. package/src/playwright-shim.ts +473 -0
  301. package/src/project-manager.ts +90 -10
  302. package/src/project-operations.ts +112 -0
  303. package/src/project-story-discovery.ts +25 -0
  304. package/src/project-tool-discovery.ts +43 -0
  305. package/src/scene-serializer.ts +0 -6
  306. package/src/scene-sync.ts +7 -2
  307. package/src/script-loader.ts +3 -3
  308. package/src/skeleton-helper.ts +57 -0
  309. package/src/storage/seed.ts +68 -8
  310. package/src/stories/StoryPreviewMount.tsx +265 -0
  311. package/src/stories/action-stories.fixture.tsx +44 -0
  312. package/src/stories/button-stories.fixture.tsx +50 -0
  313. package/src/stories/compose-project-stories.ts +182 -0
  314. package/src/stories/loader-stories.fixture.tsx +53 -0
  315. package/src/stories/story-discovery.ts +130 -0
  316. package/src/stories/story-registry.ts +146 -0
  317. package/src/theme-css.ts +1049 -0
  318. package/src/theme-library.ts +238 -0
  319. package/src/theme-preference.ts +130 -0
  320. package/src/theme.ts +527 -0
  321. package/src/tool-loader.ts +80 -24
  322. package/src/ui-source/inspect.ts +27 -4
  323. package/src/ui-source/source-write-backend.ts +83 -22
  324. package/src/widgets/index.ts +9 -18
  325. package/src/workspace-aux-commands.ts +11 -0
  326. package/src/workspace-dock-controller.ts +64 -0
  327. package/src/workspace-document-ids.ts +5 -0
  328. package/src/workspace-document-registry.ts +367 -0
  329. package/src/workspace-state-persistence.ts +455 -0
  330. package/src/workspace-status-registry.ts +110 -0
  331. package/src/workspace-utility-commands.ts +49 -0
  332. package/src/workspace-utility-registry.ts +161 -0
  333. package/src/world-document-routing.ts +16 -0
  334. package/src/xstate-inspect/XStateMachineInspector.tsx +544 -0
  335. package/src/xstate-inspect/character-animation-machine.fixture.ts +74 -0
  336. package/src/xstate-inspect/use-live-actor-state.ts +39 -0
  337. package/src/xstate-inspect/xstate-graph.ts +265 -0
  338. package/src/xstate-inspect/xstate-layout.ts +76 -0
  339. package/src/z-index.ts +26 -0
  340. package/template/.claude/skills/editor/SKILL.md +129 -90
  341. package/template/AGENTS.md +1110 -0
  342. package/template/CLAUDE.md +1 -512
  343. package/template/IDIOMS.md +50 -0
  344. package/template/check-idioms.ts +706 -0
  345. package/template/manifest-entry-modules-plugin.ts +53 -0
  346. package/template/package.json +13 -4
  347. package/template/public/scenes/default.scn2d.json +6 -0
  348. package/template/public/scenes/default.vscn.json +7 -1
  349. package/template/public/scenes/untitled.vscn.json +10 -0
  350. package/template/scripts/playtest.ts +40 -0
  351. package/template/server/loopback.ts +75 -0
  352. package/template/server/rooms/arena-room.ts +69 -1
  353. package/template/server/rooms/game-room.ts +68 -1
  354. package/template/src/data/README.md +9 -4
  355. package/template/src/data/data-ref.ts +35 -0
  356. package/template/src/data/tuning.schema.ts +1 -1
  357. package/template/src/main.ts +41 -62
  358. package/template/src/manifest-entry-modules.d.ts +3 -0
  359. package/template/src/operations/README.md +88 -0
  360. package/template/src/runtime/pixi-adapter.ts +24 -0
  361. package/template/src/scripts/components/data-spinner.ts +43 -2
  362. package/template/src/scripts/components/spin-lap-math.ts +27 -0
  363. package/template/src/tools/README.md +5 -3
  364. package/template/src/tools/example.tool.tsx +13 -7
  365. package/template/src/ui/Button.stories.tsx +66 -0
  366. package/template/src/ui/RebindPanel.tsx +2 -6
  367. package/template/src/ui/game.tsx +17 -0
  368. package/template/tests/acceptance/example.spec.ts +64 -0
  369. package/template/tests/logic/example.test.ts +31 -0
  370. package/template/tests/logic/room.test.ts +100 -0
  371. package/template/tests/tsconfig.json +30 -0
  372. package/template/validate-manifest.ts +5 -5
  373. package/template/validate-scenes.ts +50 -18
  374. package/template/vgai.game.json +20 -13
  375. package/template/vite.config.ts +77 -16
  376. package/vite-plugin-ui-oid.ts +261 -17
  377. package/dist/assets/CCDIKSolver-Dz-ysxZF.js +0 -1
  378. package/dist/assets/SelectionBox-BXsv_6aH.js +0 -1
  379. package/dist/assets/browser-project-scripts-DOru4L1x.js +0 -2
  380. package/dist/assets/browserAll-CEkWYlFk.js +0 -1
  381. package/dist/assets/create-runtime-DYIWr3va.js +0 -1
  382. package/dist/assets/data-asset-Bb9sIM7i.js +0 -5
  383. package/dist/assets/game-8SDZPPgH.js +0 -1
  384. package/dist/assets/game-CevorxyV.js +0 -1
  385. package/dist/assets/game-Di7XlywD.js +0 -1
  386. package/dist/assets/game-DjnCaw8R.js +0 -1
  387. package/dist/assets/game-Q9A0aXSV.js +0 -1
  388. package/dist/assets/index-CPVV6pjw.js +0 -1
  389. package/dist/assets/index-CpOnYyeD.js +0 -213
  390. package/dist/assets/index-Dr8H_6Rl.js +0 -1
  391. package/dist/assets/index-_bCaipUk.js +0 -13650
  392. package/dist/assets/ingest-siblings-Dz8eEqrV.js +0 -1
  393. package/dist/assets/mount-manifest-Bhk0ohsl.js +0 -1
  394. package/dist/assets/scene-query-BivAHhJu.js +0 -1
  395. package/dist/assets/webworkerAll-BLrH0F6F.js +0 -1
  396. package/dist/assets/xstate-animation-binding-1NGLmw6y.js +0 -1
  397. package/dist/assets/xstate.esm-BgUD33nl.js +0 -3
  398. package/src/authoring/scene-ui-layer.ts +0 -485
  399. package/src/authoring/ui-authoring-adapter.ts +0 -325
  400. package/src/authoring/ui-hierarchy-menu.ts +0 -40
  401. package/src/authoring/ui-inspector-sections.tsx +0 -156
  402. package/src/authoring/undo-timeline.ts +0 -145
  403. package/src/components/BottomPanel.tsx +0 -326
  404. package/src/components/BuildPanel.tsx +0 -455
  405. package/src/components/FolderTree.tsx +0 -179
  406. package/src/components/RightPanel.tsx +0 -166
  407. package/src/components/WorldContextMenu.tsx +0 -257
  408. package/src/components/asset-viewers/AssetViewer.tsx +0 -38
  409. package/src/ingest/games-react/react-rpg/src/ui/game-state.tsx +0 -129
  410. package/src/scene-ui-mode/active-scene-ui.ts +0 -58
  411. package/src/scene-ui-mode/scene-ui-palette-panel.tsx +0 -152
  412. package/src/scene-ui-mode/scene-ui-timeline-tab.tsx +0 -29
  413. package/src/scene-ui-mode/ui-prefab-dialog-host.tsx +0 -74
  414. package/src/scene-ui-mode/ui-prefab-hierarchy-menu.ts +0 -49
  415. package/src/scene-ui-mode/ui-prefab-io.ts +0 -76
  416. package/src/ui-editor/inspector.tsx +0 -563
  417. package/src/ui-editor/node-ops.ts +0 -266
  418. package/src/ui-editor/overlay.tsx +0 -380
  419. package/src/ui-editor/palette.tsx +0 -114
  420. package/src/ui-editor/react-store.ts +0 -78
  421. package/src/ui-editor/timeline-panel.tsx +0 -443
  422. package/src/ui-editor/ui-edit-store.ts +0 -552
  423. package/src/ui-editor/ui-prefab.ts +0 -95
  424. package/template/project.json +0 -9
  425. package/template/src/scripts/main.ts +0 -94
  426. package/template/src/ui/DefaultHud.tsx +0 -40
  427. package/template/src/ui/game-state.tsx +0 -37
  428. package/template/src/ui/mount-default-hud.tsx +0 -19
  429. package/template/src/ui/mount-ui.ts +0 -15
  430. package/vite-plugin-react-world-provider.ts +0 -81
@@ -1,16 +1,21 @@
1
1
  import { faCheck, faDownload, faSpinner } from '@fortawesome/free-solid-svg-icons';
2
- import { FontAwesomeIcon } from '@fortawesome/react-fontawesome';
3
2
  import { useCallback, useEffect, useState } from 'react';
4
- import { useEditorStore } from '../../EditorContext';
5
- import { type AssetFileOption, downloadOnlineAsset, getOnlineAssetFiles } from '../../editor-api';
3
+ import { Button, EditorIcon, SectionHeader, Select, themeVars } from '../../design-system';
4
+ import {
5
+ type AssetFileOption,
6
+ downloadOnlineAsset,
7
+ getOnlineAssetFiles,
8
+ getOnlineAssetPreview,
9
+ type OnlineAssetPreview,
10
+ } from '../../editor-api';
6
11
  import type { OnlineAssetInfo } from '../../editor-store';
7
- import { SectionHeader } from '../primitives/SectionHeader';
12
+ import { ModelViewer } from './ModelViewer';
8
13
 
9
14
  const selectStyle: React.CSSProperties = {
10
- background: '#1e1e1e',
11
- border: '1px solid #333',
12
- borderRadius: 3,
13
- color: '#c5c8ce',
15
+ background: themeVars.surface.inset,
16
+ border: `1px solid ${themeVars.boundary.default}`,
17
+ borderRadius: themeVars.shape.small,
18
+ color: themeVars.content.primary,
14
19
  fontSize: 11,
15
20
  padding: '3px 6px',
16
21
  outline: 'none',
@@ -25,15 +30,23 @@ function formatBytes(bytes: number): string {
25
30
  }
26
31
 
27
32
  interface Props {
28
- tabKey: string;
29
33
  online: OnlineAssetInfo;
34
+ /** W2: called with the local serving path once the download lands — the
35
+ * owning asset DOCUMENT (`asset-documents.tsx`) swaps to the local viewer
36
+ * in place (was `store.resolveOnlineAssetTab` in the right-rail era). */
37
+ onResolved: (localPath: string) => void;
30
38
  }
31
39
 
32
- export function OnlineAssetDetail({ tabKey, online }: Props) {
33
- const store = useEditorStore();
40
+ // biome-ignore lint/complexity/noExcessiveCognitiveComplexity: one catalog document coordinates preview resolution, metadata, format selection, and explicit project import.
41
+ export function OnlineAssetDetail({ online, onResolved }: Props) {
34
42
  const [fileOptions, setFileOptions] = useState<AssetFileOption[]>([]);
35
43
  const [selectedFile, setSelectedFile] = useState<AssetFileOption | null>(null);
36
44
  const [loadingFiles, setLoadingFiles] = useState(true);
45
+ const [filesError, setFilesError] = useState<string | null>(null);
46
+ const [preview, setPreview] = useState<OnlineAssetPreview | null>(null);
47
+ const [loadingPreview, setLoadingPreview] = useState(false);
48
+ const [previewUnavailable, setPreviewUnavailable] = useState(false);
49
+ const [thumbnailUnavailable, setThumbnailUnavailable] = useState(false);
37
50
  const [downloadStatus, setDownloadStatus] = useState<'idle' | 'downloading' | 'done' | 'error'>(
38
51
  'idle',
39
52
  );
@@ -41,14 +54,22 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
41
54
  useEffect(() => {
42
55
  let cancelled = false;
43
56
  setLoadingFiles(true);
57
+ setFilesError(null);
44
58
  getOnlineAssetFiles(online.source, online.id)
45
59
  .then((files) => {
46
60
  if (cancelled) return;
47
61
  setFileOptions(files);
48
62
  if (files.length > 0) setSelectedFile(files[0]!);
49
63
  })
50
- .catch(() => {
51
- if (!cancelled) setFileOptions([]);
64
+ .catch((error: unknown) => {
65
+ if (!cancelled) {
66
+ setFileOptions([]);
67
+ setFilesError(
68
+ error instanceof Error
69
+ ? error.message
70
+ : 'Asset delivery metadata is unavailable while offline.',
71
+ );
72
+ }
52
73
  })
53
74
  .finally(() => {
54
75
  if (!cancelled) setLoadingFiles(false);
@@ -58,6 +79,37 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
58
79
  };
59
80
  }, [online.source, online.id]);
60
81
 
82
+ const supportsAssetLabPreview =
83
+ online.source === 'local' &&
84
+ (online.type === 'model' || online.type === 'animation' || online.type === 'source');
85
+
86
+ useEffect(() => {
87
+ let cancelled = false;
88
+ setPreview(null);
89
+ setPreviewUnavailable(false);
90
+ setThumbnailUnavailable(false);
91
+ if (!supportsAssetLabPreview) {
92
+ setLoadingPreview(false);
93
+ return;
94
+ }
95
+ setLoadingPreview(true);
96
+ getOnlineAssetPreview(online.source, online.id)
97
+ .then((resolved) => {
98
+ if (cancelled) return;
99
+ setPreview(resolved);
100
+ setPreviewUnavailable(!resolved);
101
+ })
102
+ .catch(() => {
103
+ if (!cancelled) setPreviewUnavailable(true);
104
+ })
105
+ .finally(() => {
106
+ if (!cancelled) setLoadingPreview(false);
107
+ });
108
+ return () => {
109
+ cancelled = true;
110
+ };
111
+ }, [online.id, online.source, supportsAssetLabPreview]);
112
+
61
113
  const onDownload = useCallback(async () => {
62
114
  if (!selectedFile) return;
63
115
  setDownloadStatus('downloading');
@@ -73,22 +125,27 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
73
125
  const result = await downloadOnlineAsset(params);
74
126
  if (result.ok && result.path) {
75
127
  setDownloadStatus('done');
76
- // Switch this tab to the local asset viewer
77
- store.resolveOnlineAssetTab(tabKey, `/${result.path}`);
128
+ // Switch this document to the local asset viewer
129
+ onResolved(`/${result.path}`);
78
130
  } else {
79
131
  setDownloadStatus('error');
80
132
  }
81
133
  } catch {
82
134
  setDownloadStatus('error');
83
135
  }
84
- }, [online, selectedFile, store, tabKey]);
85
-
86
- const isIdle = downloadStatus === 'idle' || downloadStatus === 'error';
136
+ }, [online, selectedFile, onResolved]);
87
137
 
88
138
  return (
89
139
  <div style={{ padding: 8, display: 'flex', flexDirection: 'column', gap: 8 }}>
90
140
  {/* Name */}
91
- <div style={{ fontWeight: 600, fontSize: 12, color: '#c5c8ce', wordBreak: 'break-all' }}>
141
+ <div
142
+ style={{
143
+ fontWeight: 600,
144
+ fontSize: 12,
145
+ color: themeVars.content.primary,
146
+ wordBreak: 'break-all',
147
+ }}
148
+ >
92
149
  {online.name}
93
150
  </div>
94
151
 
@@ -97,27 +154,65 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
97
154
  style={{
98
155
  width: '100%',
99
156
  aspectRatio: '1',
100
- background: '#1a1a1a',
101
- borderRadius: 4,
157
+ background: themeVars.surface.shell,
158
+ borderRadius: themeVars.shape.small,
102
159
  overflow: 'hidden',
103
160
  display: 'flex',
104
161
  alignItems: 'center',
105
162
  justifyContent: 'center',
106
163
  }}
107
164
  >
108
- <img
109
- src={online.thumbnailUrl}
110
- alt={online.name}
111
- style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }}
112
- />
165
+ {loadingPreview ? (
166
+ <div style={{ color: themeVars.content.muted, fontSize: 11 }}>
167
+ <EditorIcon icon={faSpinner} spin style={{ marginRight: 5 }} />
168
+ Loading Asset Editor preview…
169
+ </div>
170
+ ) : preview ? (
171
+ <ModelViewer
172
+ assetPath={preview.path}
173
+ entityId={undefined}
174
+ materialPath={preview.materialPath}
175
+ displayName={online.name}
176
+ embedded
177
+ />
178
+ ) : (
179
+ <img
180
+ src={
181
+ thumbnailUnavailable
182
+ ? '/__editor/asset-library/local-placeholder.svg'
183
+ : online.thumbnailUrl
184
+ }
185
+ alt={thumbnailUnavailable ? `${online.name} preview unavailable` : online.name}
186
+ onError={() => setThumbnailUnavailable(true)}
187
+ style={{ maxWidth: '100%', maxHeight: '100%', objectFit: 'contain' }}
188
+ />
189
+ )}
113
190
  </div>
191
+ {thumbnailUnavailable && (
192
+ <div role="status" style={{ color: themeVars.content.dim, fontSize: 10 }}>
193
+ The catalog preview could not be loaded; showing the typed fallback.
194
+ </div>
195
+ )}
196
+ {previewUnavailable && (
197
+ <div style={{ color: themeVars.content.dim, fontSize: 10 }}>
198
+ Interactive preview is unavailable for this variant; showing its catalog thumbnail.
199
+ </div>
200
+ )}
114
201
 
115
202
  {/* Info section */}
116
203
  <SectionHeader label="Info">
117
204
  <div style={{ display: 'flex', flexDirection: 'column', gap: 4 }}>
118
205
  <div>
119
- <div style={{ fontSize: 11, color: '#8c8c8c', marginBottom: 2 }}>Source</div>
120
- <div style={{ fontSize: 11, color: '#c5c8ce' }}>
206
+ <div
207
+ style={{
208
+ fontSize: 11,
209
+ color: themeVars.content.dim,
210
+ marginBottom: 2,
211
+ }}
212
+ >
213
+ Source
214
+ </div>
215
+ <div style={{ fontSize: 11, color: themeVars.content.primary }}>
121
216
  {online.source === 'polyhaven'
122
217
  ? 'Poly Haven'
123
218
  : online.source === 'ambientcg'
@@ -126,12 +221,28 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
126
221
  </div>
127
222
  </div>
128
223
  <div>
129
- <div style={{ fontSize: 11, color: '#8c8c8c', marginBottom: 2 }}>Type</div>
130
- <div style={{ fontSize: 11, color: '#c5c8ce' }}>{online.type}</div>
224
+ <div
225
+ style={{
226
+ fontSize: 11,
227
+ color: themeVars.content.dim,
228
+ marginBottom: 2,
229
+ }}
230
+ >
231
+ Type
232
+ </div>
233
+ <div style={{ fontSize: 11, color: themeVars.content.primary }}>{online.type}</div>
131
234
  </div>
132
235
  {online.tags.length > 0 && (
133
236
  <div>
134
- <div style={{ fontSize: 11, color: '#8c8c8c', marginBottom: 2 }}>Tags</div>
237
+ <div
238
+ style={{
239
+ fontSize: 11,
240
+ color: themeVars.content.dim,
241
+ marginBottom: 2,
242
+ }}
243
+ >
244
+ Tags
245
+ </div>
135
246
  <div style={{ display: 'flex', flexWrap: 'wrap', gap: 3 }}>
136
247
  {online.tags.slice(0, 12).map((tag) => (
137
248
  <span
@@ -139,9 +250,9 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
139
250
  style={{
140
251
  fontSize: 10,
141
252
  padding: '1px 5px',
142
- background: '#2a2a2a',
143
- borderRadius: 3,
144
- color: '#999',
253
+ background: themeVars.surface.raised,
254
+ borderRadius: themeVars.shape.small,
255
+ color: themeVars.content.muted,
145
256
  }}
146
257
  >
147
258
  {tag}
@@ -152,24 +263,36 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
152
263
  )}
153
264
  {online.author && (
154
265
  <div>
155
- <div style={{ fontSize: 11, color: '#8c8c8c', marginBottom: 2 }}>Author</div>
156
- <div style={{ fontSize: 11, color: '#c5c8ce' }}>{online.author}</div>
266
+ <div
267
+ style={{
268
+ fontSize: 11,
269
+ color: themeVars.content.dim,
270
+ marginBottom: 2,
271
+ }}
272
+ >
273
+ Author
274
+ </div>
275
+ <div style={{ fontSize: 11, color: themeVars.content.primary }}>{online.author}</div>
157
276
  </div>
158
277
  )}
159
278
  </div>
160
279
  </SectionHeader>
161
280
 
162
- {/* Download section */}
163
- <SectionHeader label="Download">
281
+ {/* Explicit project acquisition section */}
282
+ <SectionHeader label="Add to Project">
164
283
  <div style={{ display: 'flex', flexDirection: 'column', gap: 6 }}>
165
284
  {loadingFiles ? (
166
- <div style={{ fontSize: 11, color: '#666' }}>
167
- <FontAwesomeIcon icon={faSpinner} spin style={{ marginRight: 4 }} />
285
+ <div style={{ fontSize: 11, color: themeVars.content.dim }}>
286
+ <EditorIcon icon={faSpinner} spin style={{ marginRight: 4 }} />
168
287
  Loading options...
169
288
  </div>
289
+ ) : filesError ? (
290
+ <div role="alert" style={{ fontSize: 11, color: themeVars.content.muted }}>
291
+ Delivery unavailable: {filesError}
292
+ </div>
170
293
  ) : fileOptions.length > 0 ? (
171
294
  <>
172
- <select
295
+ <Select
173
296
  value={selectedFile ? fileOptions.indexOf(selectedFile) : 0}
174
297
  onChange={(e) => setSelectedFile(fileOptions[Number(e.target.value)] ?? null)}
175
298
  style={selectStyle}
@@ -180,29 +303,19 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
180
303
  {f.sizeBytes ? ` (${formatBytes(f.sizeBytes)})` : ''}
181
304
  </option>
182
305
  ))}
183
- </select>
306
+ </Select>
184
307
 
185
- <button
308
+ <Button
186
309
  type="button"
310
+ variant={downloadStatus === 'done' ? 'success' : 'primary'}
311
+ size="comfortable"
187
312
  onClick={onDownload}
188
313
  disabled={downloadStatus === 'downloading'}
189
314
  style={{
190
- background: downloadStatus === 'done' ? '#22c55e' : '#579EFF',
191
- border: 'none',
192
- borderRadius: 4,
193
- color: '#fff',
194
- fontSize: 11,
195
- padding: '6px 12px',
196
- cursor: isIdle ? 'pointer' : 'default',
197
- opacity: downloadStatus === 'downloading' ? 0.7 : 1,
198
- display: 'flex',
199
- alignItems: 'center',
200
- justifyContent: 'center',
201
- gap: 5,
202
315
  width: '100%',
203
316
  }}
204
317
  >
205
- <FontAwesomeIcon
318
+ <EditorIcon
206
319
  icon={
207
320
  downloadStatus === 'done'
208
321
  ? faCheck
@@ -219,16 +332,20 @@ export function OnlineAssetDetail({ tabKey, online }: Props) {
219
332
  ? 'Downloading...'
220
333
  : downloadStatus === 'error'
221
334
  ? 'Retry'
222
- : 'Download to Project'}
223
- </button>
335
+ : 'Add to Project'}
336
+ </Button>
224
337
  </>
225
338
  ) : (
226
- <div style={{ fontSize: 11, color: '#666' }}>No download options available.</div>
339
+ <div role="status" style={{ fontSize: 11, color: themeVars.content.dim }}>
340
+ {online.source === 'local'
341
+ ? 'No healthy SSD or cloud delivery is available for this asset.'
342
+ : 'This provider has no compatible remote delivery for the selected asset.'}
343
+ </div>
227
344
  )}
228
345
  </div>
229
346
  </SectionHeader>
230
347
 
231
- <div style={{ fontSize: 10, color: '#555', padding: '4px 0' }}>
348
+ <div style={{ fontSize: 10, color: themeVars.content.dim, padding: '4px 0' }}>
232
349
  License: {online.license ?? 'CC0 (Public Domain)'}
233
350
  </div>
234
351
  </div>
@@ -0,0 +1,121 @@
1
+ import { resolveUrl } from '@engine/loader';
2
+ import { useEffect, useState } from 'react';
3
+ import { themeVars } from '../../design-system';
4
+ import { AudioViewer } from './AudioViewer';
5
+ import { GenericJsonViewer } from './GenericJsonViewer';
6
+ import { ImageViewer } from './ImageViewer';
7
+ import { ModelViewer } from './ModelViewer';
8
+
9
+ const IMAGE_EXTENSIONS = new Set(['png', 'jpg', 'jpeg', 'webp', 'svg', 'gif']);
10
+ const AUDIO_EXTENSIONS = new Set(['mp3', 'ogg', 'wav', 'flac']);
11
+ const MODEL_EXTENSIONS = new Set(['glb', 'gltf', 'fbx', 'obj', 'dae', 'stl', 'ply', 'bvh', '3ds']);
12
+ const TEXT_EXTENSIONS = new Set([
13
+ 'txt',
14
+ 'md',
15
+ 'ts',
16
+ 'tsx',
17
+ 'js',
18
+ 'jsx',
19
+ 'css',
20
+ 'html',
21
+ 'mtl',
22
+ 'csv',
23
+ 'xml',
24
+ 'yaml',
25
+ 'yml',
26
+ ]);
27
+
28
+ export type SourceAssetRoute = 'model' | 'image' | 'audio' | 'json' | 'text' | 'binary';
29
+
30
+ export function sourceAssetRoute(assetPath: string): SourceAssetRoute {
31
+ const file = assetPath.split(/[?#]/, 1)[0]!.toLowerCase();
32
+ const extension = file.slice(file.lastIndexOf('.') + 1);
33
+ if (MODEL_EXTENSIONS.has(extension)) return 'model';
34
+ if (IMAGE_EXTENSIONS.has(extension)) return 'image';
35
+ if (AUDIO_EXTENSIONS.has(extension)) return 'audio';
36
+ if (extension === 'json') return 'json';
37
+ if (TEXT_EXTENSIONS.has(extension)) return 'text';
38
+ return 'binary';
39
+ }
40
+
41
+ function TextSourcePreview({ assetPath }: { assetPath: string }) {
42
+ const [content, setContent] = useState<string | null>(null);
43
+ const [error, setError] = useState<string | null>(null);
44
+ useEffect(() => {
45
+ let cancelled = false;
46
+ setContent(null);
47
+ setError(null);
48
+ fetch(resolveUrl(assetPath), { cache: 'no-store' })
49
+ .then((response) => {
50
+ if (!response.ok) throw new Error(`HTTP ${response.status}`);
51
+ return response.text();
52
+ })
53
+ .then((value) => {
54
+ if (!cancelled) setContent(value);
55
+ })
56
+ .catch((reason) => {
57
+ if (!cancelled) setError(reason instanceof Error ? reason.message : String(reason));
58
+ });
59
+ return () => {
60
+ cancelled = true;
61
+ };
62
+ }, [assetPath]);
63
+ return (
64
+ <div style={{ padding: 12, minHeight: 0, display: 'flex', flexDirection: 'column', gap: 8 }}>
65
+ <div style={{ color: themeVars.content.primary, fontSize: 12, fontWeight: 600 }}>
66
+ {assetPath.split('/').pop()}
67
+ </div>
68
+ <pre
69
+ style={{
70
+ margin: 0,
71
+ padding: 12,
72
+ maxHeight: 560,
73
+ overflow: 'auto',
74
+ whiteSpace: 'pre-wrap',
75
+ wordBreak: 'break-word',
76
+ fontFamily: themeVars.typography.mono,
77
+ fontSize: 11,
78
+ lineHeight: 1.5,
79
+ color: error ? themeVars.semantic.danger : themeVars.content.primary,
80
+ background: themeVars.surface.inset,
81
+ border: `1px solid ${themeVars.boundary.default}`,
82
+ borderRadius: themeVars.shape.small,
83
+ }}
84
+ >
85
+ {error ?? content ?? 'Loading…'}
86
+ </pre>
87
+ </div>
88
+ );
89
+ }
90
+
91
+ /** Viewer for downloaded catalog source/animation files without a magic fallback. */
92
+ export function SourceAssetViewer({
93
+ assetPath,
94
+ active = true,
95
+ }: {
96
+ assetPath: string;
97
+ active?: boolean;
98
+ }) {
99
+ switch (sourceAssetRoute(assetPath)) {
100
+ case 'model':
101
+ return <ModelViewer assetPath={assetPath} entityId={undefined} active={active} />;
102
+ case 'image':
103
+ return <ImageViewer assetPath={assetPath} />;
104
+ case 'audio':
105
+ return <AudioViewer assetPath={assetPath} />;
106
+ case 'json':
107
+ return <GenericJsonViewer assetPath={assetPath} />;
108
+ case 'text':
109
+ return <TextSourcePreview assetPath={assetPath} />;
110
+ case 'binary':
111
+ return (
112
+ <div style={{ padding: 16, color: themeVars.content.muted, fontSize: 12 }}>
113
+ <div style={{ color: themeVars.content.primary, fontWeight: 600, marginBottom: 6 }}>
114
+ {assetPath.split('/').pop()}
115
+ </div>
116
+ This binary source is available in the project, but it has no safe in-editor renderer. Its
117
+ file remains selectable and referenceable without being misidentified as another format.
118
+ </div>
119
+ );
120
+ }
121
+ }