@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
@@ -24,11 +24,25 @@
24
24
  */
25
25
 
26
26
  import type { AuthoringAdapter, EditorNode, PropertyDescriptor, Transform } from '@engine/adapter';
27
+ import { faXmark } from '@fortawesome/free-solid-svg-icons';
27
28
  import { useSyncExternalStore } from 'react';
28
29
  import * as THREE from 'three';
30
+ import { assetSelectionVersion, subscribeAssetSelection } from '../asset-selection';
29
31
  import { getActiveAuthoring } from '../authoring/active-adapter';
30
32
  import { CompositeAuthoringAdapter } from '../authoring/composite-authoring-adapter';
31
33
  import { ReactWorldAuthoringAdapter } from '../authoring/react-world-authoring-adapter';
34
+ import {
35
+ Button,
36
+ Checkbox,
37
+ ColorSwatchInput,
38
+ EditorIcon,
39
+ FieldRow,
40
+ IconButton,
41
+ Panel,
42
+ Select,
43
+ TextInput,
44
+ themeVars,
45
+ } from '../design-system';
32
46
  import { useEditorStore } from '../EditorContext';
33
47
  import { setActiveScope } from '../hotkeys';
34
48
  import { isIngestActiveReact } from '../ingest-mode';
@@ -38,8 +52,13 @@ import {
38
52
  matchedInspectorSections,
39
53
  subscribeInspectorSectionRegistry,
40
54
  } from '../inspector-section-registry';
55
+ import {
56
+ subscribeWorkspaceDocuments,
57
+ workspaceDocumentRegistryVersion,
58
+ } from '../workspace-document-registry';
59
+ import { openEntityAssetDocument } from './asset-documents';
41
60
  import { groupProperties } from './inspector-property-grouping';
42
- import { Panel } from './primitives/Panel';
61
+ import { groupLabelStyle, LABEL_COL_WIDTH } from './inspector-widgets/shared';
43
62
 
44
63
  /**
45
64
  * D4 (B2) — the CHILD adapter owning `nodeId`'s synthetic world-group row
@@ -113,14 +132,17 @@ function toggleCatalogIsolation(
113
132
  adapter.stories?.isolate?.(nodeId, storyId);
114
133
  }
115
134
 
116
- const NUM_STYLE: React.CSSProperties = {
117
- width: 64,
118
- background: '#1e1e1e',
119
- color: '#c5c8ce',
120
- border: '1px solid #333',
121
- borderRadius: 2,
122
- padding: '3px 5px',
123
- fontSize: 12,
135
+ /** Layout-only remnant of the old hand-rolled field style — chrome now comes
136
+ * from the shared `.vgai-input`/`.vgai-select` classes (theme-css.ts), so
137
+ * every field here shares one height/padding/radius/focus treatment. */
138
+ const NUM_STYLE: React.CSSProperties = { width: 64 };
139
+
140
+ /** Row label (label-left/field-right grammar) — one width via
141
+ * `LABEL_COL_WIDTH` (I-13). */
142
+ const ROW_LABEL_STYLE: React.CSSProperties = {
143
+ width: LABEL_COL_WIDTH,
144
+ fontSize: 'var(--vgai-font-md)',
145
+ color: themeVars.content.muted,
124
146
  };
125
147
 
126
148
  function AxisRow({
@@ -140,19 +162,20 @@ function AxisRow({
140
162
  { a: 2, n: 'z' },
141
163
  ];
142
164
  return (
143
- <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '4px 8px' }}>
144
- <span style={{ width: 56, fontSize: 12, color: '#9aa0a6' }}>{label}</span>
165
+ <FieldRow label={label} htmlFor={`${testidPrefix}-x`} style={{ padding: '4px 8px' }}>
145
166
  {axes.map(({ a, n }) => (
146
- <input
167
+ <TextInput
168
+ id={`${testidPrefix}-${n}`}
147
169
  key={n}
148
170
  type="number"
171
+ aria-label={`${label} ${n.toUpperCase()}`}
149
172
  data-testid={`${testidPrefix}-${n}`}
150
173
  value={Number.isFinite(values[a]) ? Math.round(values[a] * 1000) / 1000 : 0}
151
174
  onChange={(e) => onCommit(a, Number.parseFloat(e.target.value))}
152
175
  style={NUM_STYLE}
153
176
  />
154
177
  ))}
155
- </div>
178
+ </FieldRow>
156
179
  );
157
180
  }
158
181
 
@@ -164,6 +187,12 @@ export function Inspector() {
164
187
  // possibly while a matching selection is already showing. First-party
165
188
  // registrations are import-time side effects, so this never fired for them.
166
189
  useSyncExternalStore(subscribeInspectorSectionRegistry, inspectorSectionRegistryVersion);
190
+ // W2 — two more contexts registered sections may key on: the §5.1 asset
191
+ // selection (`asset-selection-section.tsx`) and the active workspace
192
+ // document (`story-documents.tsx`'s Story Args). Their registrations'
193
+ // `match` reads those stores, so the shell must re-render when they change.
194
+ useSyncExternalStore(subscribeAssetSelection, assetSelectionVersion);
195
+ useSyncExternalStore(subscribeWorkspaceDocuments, workspaceDocumentRegistryVersion);
167
196
  const adapter = getActiveAuthoring(store);
168
197
  const id = [...store.selectedEntityIds][0] ?? null;
169
198
 
@@ -174,12 +203,18 @@ export function Inspector() {
174
203
  return (
175
204
  <Panel
176
205
  name="Inspector (embed-only)"
206
+ hideHeader
177
207
  data-testid="inspector-panel"
178
208
  onPointerDown={() => setActiveScope('inspector')}
179
209
  >
180
210
  <div
181
211
  data-testid="ingest-embed-note"
182
- style={{ padding: 12, color: '#c9a227', fontSize: 12, lineHeight: 1.5 }}
212
+ style={{
213
+ padding: 12,
214
+ color: themeVars.semantic.warning,
215
+ fontSize: 'var(--vgai-font-md)',
216
+ lineHeight: 1.5,
217
+ }}
183
218
  >
184
219
  {isIngestActiveReact() ? (
185
220
  <>
@@ -226,9 +261,10 @@ export function Inspector() {
226
261
  return (
227
262
  <Panel
228
263
  name={panelNameOverride ?? 'Environment (ingested game)'}
264
+ hideHeader
229
265
  data-testid="inspector-panel"
230
266
  onPointerDown={() => setActiveScope('inspector')}
231
- style={{ overflowY: 'auto', scrollbarWidth: 'none' }}
267
+ style={{ overflowY: 'auto' }}
232
268
  >
233
269
  {matched.map(({ Section }, i) => (
234
270
  <Section key={i} adapter={adapter} nodeId={null} />
@@ -243,17 +279,19 @@ export function Inspector() {
243
279
  return (
244
280
  <Panel
245
281
  name="Environment (ingested game)"
282
+ hideHeader
246
283
  data-testid="inspector-panel"
247
284
  onPointerDown={() => setActiveScope('inspector')}
248
285
  >
249
286
  <div style={{ pointerEvents: 'auto', padding: 4 }}>
250
- <div style={{ padding: 8, color: '#777', fontSize: 12 }}>
287
+ <div
288
+ style={{ padding: 8, color: themeVars.content.dim, fontSize: 'var(--vgai-font-md)' }}
289
+ >
251
290
  Scene settings — nothing selected.
252
291
  </div>
253
292
  <div style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '6px 8px' }}>
254
- <span style={{ width: 80, fontSize: 12, color: '#9aa0a6' }}>Background</span>
255
- <input
256
- type="color"
293
+ <span style={ROW_LABEL_STYLE}>Background</span>
294
+ <ColorSwatchInput
257
295
  data-testid="ingest-env-background"
258
296
  value={bg}
259
297
  onChange={(e) => {
@@ -270,11 +308,10 @@ export function Inspector() {
270
308
  gap: 6,
271
309
  alignItems: 'center',
272
310
  padding: '6px 8px',
273
- fontSize: 12,
311
+ fontSize: 'var(--vgai-font-md)',
274
312
  }}
275
313
  >
276
- <input
277
- type="checkbox"
314
+ <Checkbox
278
315
  data-testid="ingest-env-fog"
279
316
  checked={hasFog}
280
317
  onChange={(e) => {
@@ -369,11 +406,10 @@ export function Inspector() {
369
406
  gap: 6,
370
407
  alignItems: 'center',
371
408
  padding: '6px 8px',
372
- fontSize: 12,
409
+ fontSize: 'var(--vgai-font-md)',
373
410
  }}
374
411
  >
375
- <input
376
- type="checkbox"
412
+ <Checkbox
377
413
  data-testid={testidFor(p.path)}
378
414
  checked={v !== false}
379
415
  onChange={(e) => setProp(p.path, e.target.checked)}
@@ -387,16 +423,15 @@ export function Inspector() {
387
423
  key={p.path}
388
424
  style={{ display: 'flex', alignItems: 'center', gap: 6, padding: '6px 8px' }}
389
425
  >
390
- <span style={{ width: 64, fontSize: 12, color: '#9aa0a6' }}>{p.label}</span>
426
+ <span style={ROW_LABEL_STYLE}>{p.label}</span>
391
427
  {p.type === 'color' ? (
392
- <input
393
- type="color"
428
+ <ColorSwatchInput
394
429
  data-testid={p.path === 'material.color' ? 'ingest-color' : testidFor(p.path)}
395
430
  value={(v as string) ?? '#ffffff'}
396
431
  onChange={(e) => setProp(p.path, e.target.value)}
397
432
  />
398
433
  ) : p.type === 'number' ? (
399
- <input
434
+ <TextInput
400
435
  type="number"
401
436
  data-testid={testidFor(p.path)}
402
437
  disabled={p.readonly}
@@ -405,13 +440,13 @@ export function Inspector() {
405
440
  style={NUM_STYLE}
406
441
  />
407
442
  ) : (
408
- <input
443
+ <TextInput
409
444
  type="text"
410
445
  data-testid={testidFor(p.path)}
411
446
  readOnly={p.readonly}
412
447
  value={String(v ?? '')}
413
448
  onChange={(e) => setProp(p.path, e.target.value)}
414
- style={{ ...NUM_STYLE, width: 120 }}
449
+ style={{ width: 120 }}
415
450
  />
416
451
  )}
417
452
  </div>
@@ -430,19 +465,27 @@ export function Inspector() {
430
465
  return (
431
466
  <Panel
432
467
  name={panelNameOverride ?? 'Inspector (ingested game)'}
468
+ hideHeader
433
469
  data-testid="inspector-panel"
434
470
  onPointerDown={() => setActiveScope('inspector')}
435
471
  >
436
472
  <div style={{ pointerEvents: 'auto' }}>
437
473
  {!suppressed.has('header') && (
438
- <div style={{ padding: 8, borderBottom: '1px solid #333' }}>
439
- <input
474
+ <div style={{ padding: 8, borderBottom: `1px solid ${themeVars.boundary.default}` }}>
475
+ <TextInput
476
+ className="vgai-input"
440
477
  data-testid="ingest-name"
441
478
  value={node?.label ?? ''}
442
479
  onChange={(e) => setProp('name', e.target.value)}
443
- style={{ ...NUM_STYLE, width: '100%', fontWeight: 600 }}
480
+ style={{ width: '100%', fontWeight: 600, fontSize: 'var(--vgai-font-md)' }}
444
481
  />
445
- <div style={{ marginTop: 6, fontSize: 11, color: '#777' }}>
482
+ <div
483
+ style={{
484
+ marginTop: 6,
485
+ fontSize: 'var(--vgai-font-base)',
486
+ color: themeVars.content.dim,
487
+ }}
488
+ >
446
489
  {node?.kind} · runtime-only (ingested)
447
490
  </div>
448
491
  </div>
@@ -476,20 +519,9 @@ export function Inspector() {
476
519
  <div
477
520
  key={group.name}
478
521
  data-testid={`ingest-group-${group.groupId}`}
479
- style={{ borderTop: '1px solid #333', marginTop: 4 }}
522
+ style={{ borderTop: `1px solid ${themeVars.boundary.default}`, marginTop: 4 }}
480
523
  >
481
- <div
482
- style={{
483
- fontSize: 11,
484
- fontWeight: 600,
485
- color: '#9aa0a6',
486
- padding: '6px 8px 2px',
487
- textTransform: 'uppercase',
488
- letterSpacing: 0.4,
489
- }}
490
- >
491
- {group.name}
492
- </div>
524
+ <div style={{ ...groupLabelStyle, padding: '6px 8px 2px' }}>{group.name}</div>
493
525
  {group.properties.map(renderProperty)}
494
526
  </div>
495
527
  ))}
@@ -514,12 +546,20 @@ export function Inspector() {
514
546
  return (
515
547
  <div
516
548
  data-testid="ingest-components-na"
517
- style={{ padding: '8px', borderTop: '1px solid #333', marginTop: 4 }}
549
+ style={{
550
+ padding: '8px',
551
+ borderTop: `1px solid ${themeVars.boundary.default}`,
552
+ marginTop: 4,
553
+ }}
518
554
  >
519
- <div style={{ fontSize: 11, fontWeight: 600, color: '#9aa0a6', marginBottom: 4 }}>
520
- Components
521
- </div>
522
- <div style={{ fontSize: 11, color: '#777', fontStyle: 'italic' }}>
555
+ <div style={{ ...groupLabelStyle, marginBottom: 4 }}>Components</div>
556
+ <div
557
+ style={{
558
+ fontSize: 'var(--vgai-font-base)',
559
+ color: themeVars.content.dim,
560
+ fontStyle: 'italic',
561
+ }}
562
+ >
523
563
  No components — this object is owned by the unmodified game (no engine
524
564
  GameComponents).
525
565
  </div>
@@ -528,10 +568,14 @@ export function Inspector() {
528
568
  }
529
569
  const componentsProvider = adapter.components;
530
570
  return (
531
- <div style={{ padding: '8px', borderTop: '1px solid #333', marginTop: 4 }}>
532
- <div style={{ fontSize: 11, fontWeight: 600, color: '#9aa0a6', marginBottom: 4 }}>
533
- Components
534
- </div>
571
+ <div
572
+ style={{
573
+ padding: '8px',
574
+ borderTop: `1px solid ${themeVars.boundary.default}`,
575
+ marginTop: 4,
576
+ }}
577
+ >
578
+ <div style={{ ...groupLabelStyle, marginBottom: 4 }}>Components</div>
535
579
  {compList.map((c) => (
536
580
  <div
537
581
  key={c.type}
@@ -543,31 +587,31 @@ export function Inspector() {
543
587
  padding: '2px 0',
544
588
  }}
545
589
  >
546
- <span style={{ fontSize: 11, color: '#c5c8ce' }}>{c.type}</span>
547
- <button
548
- type="button"
590
+ <span
591
+ style={{
592
+ fontSize: 'var(--vgai-font-base)',
593
+ color: themeVars.content.primary,
594
+ }}
595
+ >
596
+ {c.type}
597
+ </span>
598
+ <IconButton
549
599
  data-testid="ingest-component-remove"
550
600
  title="Remove component"
601
+ aria-label={`Remove ${c.type}`}
602
+ variant="ghost"
603
+ size="compact"
551
604
  onClick={() => {
552
605
  componentsProvider.remove(id, c.type);
553
606
  store.notifyIngestEdit();
554
607
  }}
555
- style={{
556
- background: 'transparent',
557
- border: 'none',
558
- color: '#777',
559
- cursor: 'pointer',
560
- fontSize: 12,
561
- lineHeight: 1,
562
- padding: 0,
563
- }}
564
608
  >
565
- ×
566
- </button>
609
+ <EditorIcon icon={faXmark} />
610
+ </IconButton>
567
611
  </div>
568
612
  ))}
569
613
  {compAvailable.length > 0 && (
570
- <select
614
+ <Select
571
615
  data-testid="ingest-component-add"
572
616
  value=""
573
617
  onChange={(e) => {
@@ -576,7 +620,7 @@ export function Inspector() {
576
620
  store.notifyIngestEdit();
577
621
  }
578
622
  }}
579
- style={{ ...NUM_STYLE, width: '100%', marginTop: 4, cursor: 'pointer' }}
623
+ style={{ width: '100%', marginTop: 4 }}
580
624
  >
581
625
  <option value="">+ Add component…</option>
582
626
  {compAvailable.map((name) => (
@@ -584,7 +628,7 @@ export function Inspector() {
584
628
  {name}
585
629
  </option>
586
630
  ))}
587
- </select>
631
+ </Select>
588
632
  )}
589
633
  </div>
590
634
  );
@@ -597,19 +641,23 @@ export function Inspector() {
597
641
  other selection (an ordinary entity, or a world kind that never
598
642
  sets `stories`) omits this section entirely. */}
599
643
  {!suppressed.has('stories') && showStoriesSection && (
600
- <div style={{ padding: '8px', borderTop: '1px solid #333', marginTop: 4 }}>
601
- <div style={{ fontSize: 11, fontWeight: 600, color: '#9aa0a6', marginBottom: 4 }}>
602
- Stories
603
- </div>
644
+ <div
645
+ style={{
646
+ padding: '8px',
647
+ borderTop: `1px solid ${themeVars.boundary.default}`,
648
+ marginTop: 4,
649
+ }}
650
+ >
651
+ <div style={{ ...groupLabelStyle, marginBottom: 4 }}>Stories</div>
604
652
  {storyRefs.length > 0 ? (
605
- <select
653
+ <Select
606
654
  data-testid="ingest-stories-select"
607
655
  value={adapter.stories?.active(id) ?? ''}
608
656
  onChange={(e) => {
609
657
  const v = e.target.value;
610
658
  adapter.stories?.apply(id, v === '' ? null : v);
611
659
  }}
612
- style={{ ...NUM_STYLE, width: '100%' }}
660
+ style={{ width: '100%' }}
613
661
  >
614
662
  <option value="">(none)</option>
615
663
  {storyRefs.map((s) => (
@@ -617,42 +665,37 @@ export function Inspector() {
617
665
  {s.label}
618
666
  </option>
619
667
  ))}
620
- </select>
668
+ </Select>
621
669
  ) : (
622
670
  <div
623
671
  data-testid="ingest-stories-none"
624
- style={{ fontSize: 11, color: '#777', fontStyle: 'italic' }}
672
+ style={{
673
+ fontSize: 'var(--vgai-font-base)',
674
+ color: themeVars.content.dim,
675
+ fontStyle: 'italic',
676
+ }}
625
677
  >
626
- No stories — this world defines no `src/ui/registry.ts` states/stories.
678
+ No stories — this root has no associated portable CSF previews.
627
679
  </div>
628
680
  )}
629
681
  {/* B3 — Isolate toggle: render ONLY this catalog component (alone,
630
682
  against whichever story is currently selected in the dropdown
631
683
  above) on the world's design-time layer; exiting restores the
632
- entry (live preview). Session-only — mirrors the story-overlay
633
- writes below, never persisted to the registry. */}
684
+ Live Preview. Session-only — mirrors the story overlay writes
685
+ below, never persisted to source. */}
634
686
  {isCatalogNode && (
635
- <button
636
- type="button"
687
+ <Button
637
688
  data-testid="catalog-isolate"
638
689
  onClick={() => {
639
690
  toggleCatalogIsolation(adapter, id, isIsolated);
640
691
  store.notifyIngestEdit();
641
692
  }}
642
- style={{
643
- marginTop: 6,
644
- width: '100%',
645
- padding: '6px 8px',
646
- fontSize: 12,
647
- background: isIsolated ? '#3a5' : '#2a2a2a',
648
- color: '#e6e6e6',
649
- border: '1px solid #444',
650
- borderRadius: 3,
651
- cursor: 'pointer',
652
- }}
693
+ variant={isIsolated ? 'primary' : 'secondary'}
694
+ aria-pressed={isIsolated}
695
+ style={{ marginTop: 6, width: '100%' }}
653
696
  >
654
697
  {isIsolated ? 'Exit isolation' : 'Isolate'}
655
- </button>
698
+ </Button>
656
699
  )}
657
700
  </div>
658
701
  )}
@@ -662,6 +705,17 @@ export function Inspector() {
662
705
  Layout/Style/Props/Events, or any future spec-27 contribution) —
663
706
  rendered AFTER the generic grid above, as siblings, in
664
707
  registration order. */}
708
+ {store.objectMap.has(id) && (
709
+ <div style={{ padding: 8, borderTop: `1px solid ${themeVars.boundary.default}` }}>
710
+ <Button
711
+ data-testid="open-asset-lab"
712
+ onClick={() => openEntityAssetDocument(store, id)}
713
+ style={{ width: '100%' }}
714
+ >
715
+ Open in Asset Editor
716
+ </Button>
717
+ </div>
718
+ )}
665
719
  {matched.map(({ Section }, i) => (
666
720
  <Section key={i} adapter={adapter} nodeId={id} />
667
721
  ))}
@@ -1,3 +1,4 @@
1
+ import { themeVars } from '../design-system';
1
2
  /**
2
3
  * Inspector-tool section host (W3, docs/DATA-TOOLS-DESIGN.md §3.2/§3.4) —
3
4
  * renders one project tool (`placement: 'inspector'`) as a section in the
@@ -18,8 +19,8 @@
18
19
  * W3.1 (§3.3): the tool render is wrapped in `EditorSelectionProvider`, INSIDE
19
20
  * the error boundary, so `useSelection()` works for any inspector tool
20
21
  * without adding to `InspectorToolProps` — richer data arrives through hooks,
21
- * not more props. Dock tools get no such provider (`ToolHost`/`BottomPanel`
22
- * have no adapter/selection in scope) — `useSelection` there throws a
22
+ * not more props. Utility tools get no such provider (`ToolHost` inside a
23
+ * Dockview utility has no adapter/selection in scope) — `useSelection` throws a
23
24
  * teaching error, contained the same way a render crash is.
24
25
  */
25
26
 
@@ -27,6 +28,7 @@ import type { AuthoringAdapter } from '@engine/adapter';
27
28
  import { EditorSelectionProvider } from '@engine/react/use-selection';
28
29
  import type { InspectorToolProps } from '@engine/tools/define-tool';
29
30
  import type { ComponentType } from 'react';
31
+ import { groupLabelStyle } from './inspector-widgets/shared';
30
32
  import { ToolErrorBoundary } from './ToolHost';
31
33
 
32
34
  export interface InspectorToolSectionProps {
@@ -56,9 +58,9 @@ export function InspectorToolSection({
56
58
  return (
57
59
  <div
58
60
  data-testid={`inspector-tool-${id}`}
59
- style={{ padding: '8px', borderTop: '1px solid #333', marginTop: 4 }}
61
+ style={{ padding: '8px', borderTop: `1px solid ${themeVars.boundary.default}`, marginTop: 4 }}
60
62
  >
61
- <div style={{ fontSize: 11, fontWeight: 600, color: '#9aa0a6', marginBottom: 4 }}>
63
+ <div style={{ ...groupLabelStyle, marginBottom: 4 }}>
62
64
  <span aria-hidden="true" style={{ marginRight: 4 }}>
63
65
  ⚙
64
66
  </span>
@@ -17,7 +17,7 @@
17
17
  * D-V5 (docs/WAVE5-MULTIWORLD-INGEST-DESIGN.md, F24 composite): the slot
18
18
  * behind this banner is now an ORDERED LIST
19
19
  * (`getMountFailureReports`) — a composite manifest's sibling-mount loop can
20
- * fail several worlds independently in one attempt, and silently showing
20
+ * fail several roots independently in one attempt, and silently showing
21
21
  * only the latest would be the exact F9 anti-pattern this banner exists to
22
22
  * close. This renders EVERY entry, each its own worldId-labelled
23
23
  * summary/message pair, inside the SAME single banner (one `data-testid`,
@@ -28,6 +28,7 @@
28
28
 
29
29
  import { useReducer, useSyncExternalStore } from 'react';
30
30
  import { getMountFailureReports, setMountFailureReport } from '../authoring/mount-failure-report';
31
+ import { EditorBanner, EditorIcon, editorIcons, IconButton } from '../design-system';
31
32
  import { useEditorStore } from '../EditorContext';
32
33
 
33
34
  export function MountFailureBanner() {
@@ -52,59 +53,41 @@ export function MountFailureBanner() {
52
53
  if (reports.length === 0) return null;
53
54
 
54
55
  return (
55
- <div
56
+ <EditorBanner
56
57
  data-testid="mount-failure-banner"
57
- style={{
58
- background: '#4a1f1f',
59
- border: '1px solid #8a2f2f',
60
- color: '#f0a0a0',
61
- borderRadius: 3,
62
- margin: '4px 8px',
63
- padding: '6px 8px',
64
- fontSize: 11,
65
- pointerEvents: 'auto',
66
- }}
67
- >
68
- <div style={{ display: 'flex', alignItems: 'flex-start', gap: 6 }}>
69
- <span style={{ flex: 1 }}>
70
- {reports.map((report) => (
71
- <div key={report.worldId} style={{ marginBottom: 4 }}>
72
- <div data-testid="mount-failure-summary">
73
- <strong>
74
- "{report.worldId}" ({report.kind} / {report.identity}) failed to mount.
75
- </strong>
76
- </div>
77
- <div
78
- data-testid="mount-failure-message"
79
- style={{ marginTop: 2, wordBreak: 'break-word' }}
80
- >
81
- {report.message}
82
- </div>
83
- </div>
84
- ))}
85
- <div style={{ marginTop: 2, opacity: 0.8 }}>See the Console tab for the full trace.</div>
86
- </span>
87
- <button
88
- type="button"
58
+ tone="error"
59
+ icon={<EditorIcon icon={editorIcons.status.error} />}
60
+ style={{ margin: '4px 8px', pointerEvents: 'auto' }}
61
+ actions={
62
+ <IconButton
63
+ aria-label="Dismiss mount failure"
89
64
  data-testid="mount-failure-dismiss"
90
65
  onClick={() => {
91
66
  setMountFailureReport(null);
92
67
  forceRerender();
93
68
  }}
94
- style={{
95
- background: 'none',
96
- border: 'none',
97
- color: '#f0a0a0',
98
- cursor: 'pointer',
99
- fontSize: 13,
100
- lineHeight: 1,
101
- padding: 0,
102
- }}
103
- aria-label="Dismiss"
69
+ size="compact"
104
70
  >
105
- ×
106
- </button>
107
- </div>
108
- </div>
71
+ <EditorIcon icon={editorIcons.action.close} />
72
+ </IconButton>
73
+ }
74
+ >
75
+ {reports.map((report) => (
76
+ <div key={report.worldId} style={{ marginBottom: 4 }}>
77
+ <div data-testid="mount-failure-summary">
78
+ <strong>
79
+ "{report.worldId}" ({report.kind} / {report.identity}) failed to mount.
80
+ </strong>
81
+ </div>
82
+ <div
83
+ data-testid="mount-failure-message"
84
+ style={{ marginTop: 2, wordBreak: 'break-word' }}
85
+ >
86
+ {report.message}
87
+ </div>
88
+ </div>
89
+ ))}
90
+ <div style={{ marginTop: 2, opacity: 0.8 }}>See the Console tab for the full trace.</div>
91
+ </EditorBanner>
109
92
  );
110
93
  }