@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
@@ -0,0 +1,461 @@
1
+ import { Checkbox, Select, TextInput, themeVars } from '../design-system';
2
+ /**
3
+ * Debug Console — the human door onto the game's registered debug COMMANDS
4
+ * (`ctx.debug.registerCommand`, docs/SYNTHETIC-PLAYER-SPEC.md §3.6): lists
5
+ * every command with its locus badge, renders a schema-driven invoke form
6
+ * from the command's `argsJsonSchema` (the JSON-Schema projection of its Zod
7
+ * args tuple), and keeps an invocation history.
8
+ *
9
+ * Reads the live adapter through `getActiveDebug()` (the authoring seam —
10
+ * play-mode installs the whole `SystemAdapters` bag on enter, clears on
11
+ * exit) and renders NOTHING when no debug adapter is active — same
12
+ * degrade-to-absent discipline as `NetworkSection`. The 250ms poll covers
13
+ * the adapter's IDENTITY changing (play started/stopped) and new
14
+ * registrations appearing (hot reload re-seeds).
15
+ *
16
+ * Widget reuse: the args form funnels through the SAME
17
+ * `jsonSchemaToFieldDescriptors` module the Data panel renders from
18
+ * (`inspectors/json-schema-fields.ts`) — a command's Zod tuple is adapted to
19
+ * a pseudo-object (`arg0`/`arg1`/… from `prefixItems`, or the older
20
+ * array-form `items`) so tuple args get the same typed widgets for free.
21
+ *
22
+ * Layout: one bordered row per command — header line (monospace name, locus
23
+ * chip, ellipsized description, right-aligned Invoke) with the args form
24
+ * indented on its own line below — and a `ConsolePanel`-style history region
25
+ * pinned under the command list (timestamped, ✓/✗ per entry, newest first).
26
+ */
27
+
28
+ import type { DebugCommandInfo } from '@engine/adapter/system-adapter';
29
+ import { useEffect, useState } from 'react';
30
+ import { getActiveDebug } from '../authoring/active-systems';
31
+ import { Button } from '../design-system';
32
+ import {
33
+ type DataFieldDescriptor,
34
+ defaultValueForDescriptor,
35
+ jsonSchemaToFieldDescriptors,
36
+ } from './inspectors/json-schema-fields';
37
+
38
+ /**
39
+ * Adapt a command's args JSON Schema (a TUPLE: JSON Schema 2020-12
40
+ * `prefixItems`, or the older array-form `items`) into the pseudo-object
41
+ * field descriptors (`arg0`, `arg1`, …) the shared widget converter
42
+ * understands. Pure — unit-tested headlessly.
43
+ */
44
+ export function tupleSchemaToFields(argsJsonSchema: unknown): DataFieldDescriptor[] {
45
+ const node = argsJsonSchema as { prefixItems?: unknown[]; items?: unknown } | null | undefined;
46
+ const items = Array.isArray(node?.prefixItems)
47
+ ? node.prefixItems
48
+ : Array.isArray(node?.items)
49
+ ? node.items
50
+ : [];
51
+ const properties = Object.fromEntries(items.map((item, i) => [`arg${i}`, item]));
52
+ return jsonSchemaToFieldDescriptors({ type: 'object', properties });
53
+ }
54
+
55
+ /** Ordered positional args out of the form's `arg<i>`-keyed values. */
56
+ export function fieldValuesToArgs(
57
+ fields: DataFieldDescriptor[],
58
+ values: Record<string, unknown>,
59
+ ): unknown[] {
60
+ return fields.map((f) => values[f.name]);
61
+ }
62
+
63
+ interface HistoryEntry {
64
+ name: string;
65
+ args: unknown[];
66
+ ok: boolean;
67
+ /** Rendered result/error text (already stringified for display). */
68
+ detail: string;
69
+ at: number;
70
+ }
71
+
72
+ const LOCUS_COLORS: Record<'client' | 'server', string> = {
73
+ client: themeVars.accent.default,
74
+ server: themeVars.semantic.warning,
75
+ };
76
+
77
+ const LOCUS_HINTS: Record<'client' | 'server', string> = {
78
+ client: 'Runs in this client',
79
+ server: 'Runs on the authoritative server — needs an attached Colyseus room',
80
+ };
81
+
82
+ function LocusBadge({ locus, name }: { locus: 'client' | 'server'; name: string }) {
83
+ const color = LOCUS_COLORS[locus];
84
+ return (
85
+ <span
86
+ data-testid={`debug-command-locus-${name}`}
87
+ title={LOCUS_HINTS[locus]}
88
+ style={{
89
+ border: `1px solid ${color}55`,
90
+ background: `${color}14`,
91
+ color,
92
+ borderRadius: themeVars.shape.small,
93
+ padding: '0 4px',
94
+ fontSize: 9,
95
+ fontWeight: 700,
96
+ lineHeight: '14px',
97
+ textTransform: 'uppercase',
98
+ letterSpacing: 0.4,
99
+ flexShrink: 0,
100
+ }}
101
+ >
102
+ {locus}
103
+ </span>
104
+ );
105
+ }
106
+
107
+ function FieldInput({
108
+ field,
109
+ value,
110
+ onChange,
111
+ }: {
112
+ field: DataFieldDescriptor;
113
+ value: unknown;
114
+ onChange: (v: unknown) => void;
115
+ }) {
116
+ switch (field.kind) {
117
+ case 'number':
118
+ return (
119
+ <TextInput
120
+ data-testid={`debug-arg-${field.name}`}
121
+ type="number"
122
+ className="vgai-input"
123
+ style={{ width: 72 }}
124
+ value={typeof value === 'number' ? value : ''}
125
+ {...(field.min !== undefined ? { min: field.min } : {})}
126
+ {...(field.max !== undefined ? { max: field.max } : {})}
127
+ onChange={(e) => onChange(e.target.value === '' ? 0 : Number(e.target.value))}
128
+ />
129
+ );
130
+ case 'boolean':
131
+ return (
132
+ <Checkbox
133
+ data-testid={`debug-arg-${field.name}`}
134
+ className="vgai-checkbox"
135
+ style={{ margin: 0 }}
136
+ checked={value === true}
137
+ onChange={(e) => onChange(e.target.checked)}
138
+ />
139
+ );
140
+ case 'enum':
141
+ return (
142
+ <Select
143
+ data-testid={`debug-arg-${field.name}`}
144
+ className="vgai-select"
145
+ value={typeof value === 'string' ? value : ''}
146
+ onChange={(e) => onChange(e.target.value)}
147
+ >
148
+ {(field.options ?? []).map((opt) => (
149
+ <option key={opt} value={opt}>
150
+ {opt}
151
+ </option>
152
+ ))}
153
+ </Select>
154
+ );
155
+ case 'string':
156
+ case 'color':
157
+ case 'ref':
158
+ return (
159
+ <TextInput
160
+ data-testid={`debug-arg-${field.name}`}
161
+ type="text"
162
+ className="vgai-input"
163
+ style={{ width: 140 }}
164
+ value={typeof value === 'string' ? value : ''}
165
+ onChange={(e) => onChange(e.target.value)}
166
+ />
167
+ );
168
+ default: {
169
+ // 'json' / 'group' — raw JSON, parsed on commit; an unparsable edit
170
+ // keeps the previous value (same refuse-don't-widen rule as DataPanel's
171
+ // JsonCell).
172
+ return (
173
+ <TextInput
174
+ data-testid={`debug-arg-${field.name}`}
175
+ type="text"
176
+ className="vgai-input"
177
+ style={{ width: 160, fontFamily: themeVars.typography.mono }}
178
+ defaultValue={JSON.stringify(value ?? null)}
179
+ onBlur={(e) => {
180
+ try {
181
+ onChange(JSON.parse(e.target.value));
182
+ } catch {
183
+ /* refuse invalid JSON */
184
+ }
185
+ }}
186
+ />
187
+ );
188
+ }
189
+ }
190
+ }
191
+
192
+ /** Args-form label: the schema's own `.describe()` text when it's short
193
+ * enough to sit inline (the tuple projection's `arg0`/`arg1` names carry no
194
+ * meaning), else the positional name with the description as a tooltip. */
195
+ function fieldLabel(f: DataFieldDescriptor): string {
196
+ return f.description && f.description.length <= 24 ? f.description : f.name;
197
+ }
198
+
199
+ function CommandRow({
200
+ command,
201
+ onInvoked,
202
+ }: {
203
+ command: DebugCommandInfo;
204
+ onInvoked: (entry: HistoryEntry) => void;
205
+ }) {
206
+ const fields = tupleSchemaToFields(command.argsJsonSchema);
207
+ const [values, setValues] = useState<Record<string, unknown>>(() =>
208
+ Object.fromEntries(fields.map((f) => [f.name, defaultValueForDescriptor(f)])),
209
+ );
210
+ const [busy, setBusy] = useState(false);
211
+
212
+ const invoke = async () => {
213
+ const debug = getActiveDebug();
214
+ if (!debug) return;
215
+ const args = fieldValuesToArgs(fields, values);
216
+ setBusy(true);
217
+ try {
218
+ const result = await debug.invoke(command.name, args);
219
+ onInvoked({
220
+ name: command.name,
221
+ args,
222
+ ok: true,
223
+ detail: result === undefined ? 'ok' : JSON.stringify(result),
224
+ at: Date.now(),
225
+ });
226
+ } catch (err) {
227
+ onInvoked({
228
+ name: command.name,
229
+ args,
230
+ ok: false,
231
+ detail: err instanceof Error ? err.message : String(err),
232
+ at: Date.now(),
233
+ });
234
+ } finally {
235
+ setBusy(false);
236
+ }
237
+ };
238
+
239
+ return (
240
+ <div
241
+ data-testid={`debug-command-${command.name}`}
242
+ style={{
243
+ display: 'flex',
244
+ flexDirection: 'column',
245
+ gap: 4,
246
+ padding: '5px 8px 6px',
247
+ borderBottom: `1px solid ${themeVars.boundary.default}`,
248
+ }}
249
+ >
250
+ {/* Header line: name · locus · description ······ Invoke */}
251
+ <div style={{ display: 'flex', alignItems: 'center', gap: 8, minWidth: 0 }}>
252
+ <span
253
+ style={{
254
+ fontFamily: themeVars.typography.mono,
255
+ color: themeVars.content.primary,
256
+ flexShrink: 0,
257
+ }}
258
+ >
259
+ {command.name}
260
+ </span>
261
+ <LocusBadge locus={command.locus} name={command.name} />
262
+ <span
263
+ style={{
264
+ color: themeVars.content.dim,
265
+ fontSize: 10,
266
+ flex: 1,
267
+ minWidth: 0,
268
+ overflow: 'hidden',
269
+ textOverflow: 'ellipsis',
270
+ whiteSpace: 'nowrap',
271
+ }}
272
+ {...(command.description ? { title: command.description } : {})}
273
+ >
274
+ {command.description ?? ''}
275
+ </span>
276
+ <Button
277
+ variant="primary"
278
+ size="compact"
279
+ data-testid={`debug-invoke-${command.name}`}
280
+ disabled={busy}
281
+ onClick={() => void invoke()}
282
+ style={{ flexShrink: 0 }}
283
+ >
284
+ Invoke
285
+ </Button>
286
+ </div>
287
+ {/* Args form (only when the command takes args), indented under the name */}
288
+ {fields.length > 0 && (
289
+ <div
290
+ style={{
291
+ display: 'flex',
292
+ alignItems: 'center',
293
+ gap: 10,
294
+ flexWrap: 'wrap',
295
+ paddingLeft: 12,
296
+ }}
297
+ >
298
+ {fields.map((f) => (
299
+ <label
300
+ key={f.name}
301
+ style={{ display: 'flex', alignItems: 'center', gap: 4 }}
302
+ {...(f.description ? { title: f.description } : {})}
303
+ >
304
+ <span style={{ color: themeVars.content.muted, fontSize: 10 }}>{fieldLabel(f)}</span>
305
+ <FieldInput
306
+ field={f}
307
+ value={values[f.name]}
308
+ onChange={(v) => setValues((prev) => ({ ...prev, [f.name]: v }))}
309
+ />
310
+ </label>
311
+ ))}
312
+ </div>
313
+ )}
314
+ </div>
315
+ );
316
+ }
317
+
318
+ function formatTime(ts: number): string {
319
+ const d = new Date(ts);
320
+ const pad = (n: number) => n.toString().padStart(2, '0');
321
+ return `${pad(d.getHours())}:${pad(d.getMinutes())}:${pad(d.getSeconds())}`;
322
+ }
323
+
324
+ /** Keep huge stringified results from flooding a history line — the full
325
+ * text stays reachable via the row's title tooltip. */
326
+ function truncateDetail(detail: string): string {
327
+ return detail.length > 160 ? `${detail.slice(0, 160)}…` : detail;
328
+ }
329
+
330
+ function HistoryRow({ entry }: { entry: HistoryEntry }) {
331
+ return (
332
+ <div
333
+ title={entry.detail}
334
+ style={{
335
+ display: 'flex',
336
+ alignItems: 'flex-start',
337
+ gap: 6,
338
+ padding: '1px 8px',
339
+ // themeVars.semantic.dangerFaint: deliberate low-emphasis RESTING row tint (see theme.ts).
340
+ background: entry.ok ? 'transparent' : themeVars.semantic.dangerFaint,
341
+ }}
342
+ >
343
+ <span style={{ color: themeVars.content.dim, flexShrink: 0 }}>{formatTime(entry.at)}</span>
344
+ <span
345
+ style={{
346
+ color: entry.ok ? themeVars.semantic.success : themeVars.semantic.danger,
347
+ flexShrink: 0,
348
+ }}
349
+ >
350
+ {entry.ok ? '✓' : '✗'}
351
+ </span>
352
+ <span
353
+ style={{ flex: 1, minWidth: 0, wordBreak: 'break-word', color: themeVars.content.primary }}
354
+ >
355
+ {entry.name}({entry.args.map((a) => JSON.stringify(a)).join(', ')})
356
+ <span style={{ color: themeVars.content.muted }}> → </span>
357
+ <span style={{ color: entry.ok ? themeVars.content.muted : themeVars.semantic.danger }}>
358
+ {truncateDetail(entry.detail)}
359
+ </span>
360
+ </span>
361
+ </div>
362
+ );
363
+ }
364
+
365
+ export function DebugConsolePanel() {
366
+ const [commands, setCommands] = useState<DebugCommandInfo[] | null>(() => {
367
+ const debug = getActiveDebug();
368
+ return debug ? debug.commands() : null;
369
+ });
370
+ const [history, setHistory] = useState<HistoryEntry[]>([]);
371
+
372
+ useEffect(() => {
373
+ const tick = () => {
374
+ const debug = getActiveDebug();
375
+ setCommands(debug ? debug.commands() : null);
376
+ };
377
+ tick();
378
+ const intervalId = setInterval(tick, 250);
379
+ return () => clearInterval(intervalId);
380
+ }, []);
381
+
382
+ if (!commands) return null;
383
+
384
+ return (
385
+ <div
386
+ data-testid="debug-console-panel"
387
+ style={{
388
+ flex: 1,
389
+ minHeight: 0,
390
+ display: 'flex',
391
+ flexDirection: 'column',
392
+ fontSize: 11,
393
+ color: themeVars.content.primary,
394
+ background: themeVars.surface.inset,
395
+ }}
396
+ >
397
+ <div style={{ flex: 1, minHeight: 0, overflowY: 'auto' }}>
398
+ {commands.length === 0 ? (
399
+ <div style={{ padding: 12, fontSize: 12, color: themeVars.content.muted, maxWidth: 480 }}>
400
+ <p style={{ margin: '0 0 6px' }}>No debug commands registered.</p>
401
+ <p style={{ margin: 0 }}>
402
+ Register one from a GameComponent with{' '}
403
+ <code>ctx.debug.registerCommand(name, spec, fn)</code> — it shows up here live.
404
+ </p>
405
+ </div>
406
+ ) : (
407
+ commands.map((c) => (
408
+ <CommandRow
409
+ key={c.name}
410
+ command={c}
411
+ onInvoked={(entry) => setHistory((prev) => [entry, ...prev].slice(0, 50))}
412
+ />
413
+ ))
414
+ )}
415
+ </div>
416
+ {history.length > 0 && (
417
+ <div
418
+ data-testid="debug-history"
419
+ style={{
420
+ flexShrink: 0,
421
+ maxHeight: '45%',
422
+ display: 'flex',
423
+ flexDirection: 'column',
424
+ borderTop: `1px solid ${themeVars.boundary.default}`,
425
+ }}
426
+ >
427
+ <div style={{ display: 'flex', alignItems: 'center', padding: '3px 8px', flexShrink: 0 }}>
428
+ <span
429
+ style={{
430
+ fontSize: 10,
431
+ fontWeight: 600,
432
+ color: themeVars.content.muted,
433
+ textTransform: 'uppercase',
434
+ letterSpacing: 0.5,
435
+ }}
436
+ >
437
+ History
438
+ </span>
439
+ <Button
440
+ type="button"
441
+ variant="ghost"
442
+ size="compact"
443
+ onClick={() => setHistory([])}
444
+ title="Clear history"
445
+ style={{ marginLeft: 'auto' }}
446
+ >
447
+ Clear
448
+ </Button>
449
+ </div>
450
+ <div
451
+ style={{ overflowY: 'auto', fontFamily: themeVars.typography.mono, lineHeight: '17px' }}
452
+ >
453
+ {history.map((h) => (
454
+ <HistoryRow key={`${h.at}-${h.name}`} entry={h} />
455
+ ))}
456
+ </div>
457
+ </div>
458
+ )}
459
+ </div>
460
+ );
461
+ }
@@ -0,0 +1,165 @@
1
+ import {
2
+ getXStateAnimationBindingsVersion,
3
+ subscribeXStateAnimationBindings,
4
+ } from '@engine/animation/xstate-animation-binding';
5
+ import { clipNamesOf, collectMachineAnimationMeta } from '@engine/animation/xstate-animation-meta';
6
+ import { useEffect, useSyncExternalStore } from 'react';
7
+ import type { AnyStateMachine } from 'xstate';
8
+ import { getActiveDebug, getActiveNetworking } from '../authoring/active-systems';
9
+ import { useAvailabilityTick } from '../availability-tick';
10
+ import { Button, EditorTab, EditorTabList, themeVars } from '../design-system';
11
+ import { XStateMachineInspector } from '../xstate-inspect/XStateMachineInspector';
12
+ import { DebugConsolePanel } from './DebugConsolePanel';
13
+ import {
14
+ activeDebuggerTab,
15
+ type DebuggerTabId,
16
+ debuggerMachineNodeId,
17
+ debuggerPanelVersion,
18
+ selectDebuggerMachine,
19
+ setDebuggerTab,
20
+ subscribeDebuggerPanel,
21
+ } from './debugger-panel-state';
22
+ import { NetworkSection } from './NetworkSection';
23
+ import { PerformancePanel } from './PerformancePanel';
24
+ import { StateWatchPanel } from './StateWatchPanel';
25
+ import { listLiveMachines, liveBindingFor } from './xstate-documents';
26
+
27
+ interface TabSpec {
28
+ id: DebuggerTabId;
29
+ label: string;
30
+ }
31
+
32
+ function EmptyDebugState({ children }: { children: React.ReactNode }) {
33
+ return (
34
+ <div style={{ padding: 12, color: themeVars.content.muted, fontSize: 12 }}>{children}</div>
35
+ );
36
+ }
37
+
38
+ function MachinesPanel() {
39
+ useSyncExternalStore(
40
+ subscribeXStateAnimationBindings,
41
+ getXStateAnimationBindingsVersion,
42
+ getXStateAnimationBindingsVersion,
43
+ );
44
+ const machines = listLiveMachines();
45
+ const requested = debuggerMachineNodeId();
46
+ const selected = machines.find((machine) => machine.nodeId === requested) ?? machines[0];
47
+ const binding = selected ? liveBindingFor(selected.nodeId) : undefined;
48
+
49
+ useEffect(() => {
50
+ if (selected && requested !== selected.nodeId) selectDebuggerMachine(selected.nodeId);
51
+ }, [requested, selected]);
52
+
53
+ if (!selected || !binding) {
54
+ return (
55
+ <EmptyDebugState>Select a live entity with an XState animation binding.</EmptyDebugState>
56
+ );
57
+ }
58
+
59
+ return (
60
+ <div style={{ flex: 1, minHeight: 0, display: 'flex' }}>
61
+ <div
62
+ style={{
63
+ width: 190,
64
+ flexShrink: 0,
65
+ overflow: 'auto',
66
+ borderRight: `1px solid ${themeVars.boundary.default}`,
67
+ background: themeVars.surface.inset,
68
+ padding: 4,
69
+ }}
70
+ >
71
+ {machines.map((machine) => (
72
+ <Button
73
+ key={machine.nodeId}
74
+ type="button"
75
+ variant="ghost"
76
+ className="vgai-debugger-machine"
77
+ data-selected={machine.nodeId === selected.nodeId || undefined}
78
+ onClick={() => selectDebuggerMachine(machine.nodeId)}
79
+ >
80
+ <div>{machine.machineId}</div>
81
+ <div style={{ color: themeVars.content.dim, fontSize: 10 }}>{machine.label}</div>
82
+ </Button>
83
+ ))}
84
+ </div>
85
+ <div style={{ flex: 1, minWidth: 0, minHeight: 0 }}>
86
+ <XStateMachineInspector
87
+ machine={binding.actor.logic as AnyStateMachine}
88
+ collectMachineAnimationMeta={collectMachineAnimationMeta}
89
+ clipNamesOf={clipNamesOf}
90
+ actor={binding.actor}
91
+ />
92
+ </div>
93
+ </div>
94
+ );
95
+ }
96
+
97
+ export function DebuggerPanel() {
98
+ useSyncExternalStore(subscribeDebuggerPanel, debuggerPanelVersion, debuggerPanelVersion);
99
+ useAvailabilityTick();
100
+ const active = activeDebuggerTab();
101
+ const debugAvailable = getActiveDebug() !== null;
102
+ const networkAvailable = getActiveNetworking() !== null;
103
+ const machinesAvailable = listLiveMachines().length > 0;
104
+ const tabs: TabSpec[] = [
105
+ { id: 'state', label: 'State' },
106
+ { id: 'profiler', label: 'Profiler' },
107
+ { id: 'network', label: 'Network' },
108
+ { id: 'machines', label: 'Machines' },
109
+ { id: 'commands', label: 'Commands' },
110
+ ];
111
+ return (
112
+ <div
113
+ data-testid="debugger-panel"
114
+ style={{
115
+ flex: 1,
116
+ minHeight: 0,
117
+ display: 'flex',
118
+ flexDirection: 'column',
119
+ background: themeVars.surface.inset,
120
+ }}
121
+ >
122
+ <EditorTabList aria-label="Debugger views">
123
+ {tabs.map((tab) => (
124
+ <EditorTab
125
+ key={tab.id}
126
+ selected={active === tab.id}
127
+ data-testid={`debugger-tab-${tab.id}`}
128
+ onClick={() => setDebuggerTab(tab.id)}
129
+ >
130
+ {tab.label}
131
+ </EditorTab>
132
+ ))}
133
+ </EditorTabList>
134
+ <div role="tabpanel" style={{ flex: 1, minHeight: 0, display: 'flex' }}>
135
+ {active === 'state' &&
136
+ (debugAvailable ? (
137
+ <StateWatchPanel />
138
+ ) : (
139
+ <EmptyDebugState>
140
+ Enter Play mode to inspect registered state providers.
141
+ </EmptyDebugState>
142
+ ))}
143
+ {active === 'profiler' && <PerformancePanel />}
144
+ {active === 'network' &&
145
+ (networkAvailable ? (
146
+ <NetworkSection variant="panel" />
147
+ ) : (
148
+ <EmptyDebugState>No live networking adapter is registered.</EmptyDebugState>
149
+ ))}
150
+ {active === 'machines' &&
151
+ (machinesAvailable ? (
152
+ <MachinesPanel />
153
+ ) : (
154
+ <EmptyDebugState>No live XState animation bindings are registered.</EmptyDebugState>
155
+ ))}
156
+ {active === 'commands' &&
157
+ (debugAvailable ? (
158
+ <DebugConsolePanel />
159
+ ) : (
160
+ <EmptyDebugState>Enter Play mode to run registered debug commands.</EmptyDebugState>
161
+ ))}
162
+ </div>
163
+ </div>
164
+ );
165
+ }