@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,100 @@
1
+ /**
2
+ * L1-equivalent for multiplayer (`docs/ACCEPTANCE-DRIVER-SPEC.md` §2.3's
3
+ * "Multiplayer lane", Acceptance Driver build plan Task 4.4): boots the
4
+ * shipped `server/loopback.ts` harness in-process (the REAL `startColyseus`
5
+ * bootstrap + shipped `GameRoom`, on an ephemeral port — no mocks) and
6
+ * round-trips ONE message: the `__vgai:debugCommand` handler
7
+ * (`server/rooms/game-room.ts`), gated open via the `allowDebugCommands` room
8
+ * option, with a real `@colyseus/sdk` client.
9
+ */
10
+
11
+ import { Client, type Room } from '@colyseus/sdk';
12
+ import { afterEach, describe, expect, it } from 'vitest';
13
+ import { type LoopbackColyseus, startLoopbackColyseus } from '../../server/loopback.js';
14
+
15
+ function withTimeout<T>(promise: Promise<T>, ms: number, label: string): Promise<T> {
16
+ return Promise.race([
17
+ promise,
18
+ new Promise<T>((_, reject) => {
19
+ setTimeout(() => reject(new Error(`timed out after ${ms}ms waiting for: ${label}`)), ms);
20
+ }),
21
+ ]);
22
+ }
23
+
24
+ describe('game_room debugCommand round-trip over a loopback Colyseus server (no mocks)', () => {
25
+ let server: LoopbackColyseus | null = null;
26
+ let room: Room | null = null;
27
+
28
+ afterEach(async () => {
29
+ await room?.leave().catch(() => {});
30
+ room = null;
31
+ server?.stop();
32
+ server = null;
33
+ });
34
+
35
+ it('give-score mutates authoritative state and replies via __vgai:debugCommandResult', async () => {
36
+ server = await startLoopbackColyseus();
37
+ const client = new Client(server.url);
38
+
39
+ // The room option this room's onCreate reads (server/rooms/game-room.ts)
40
+ // — off by default, exactly what `vgai probe`/this harness opts into.
41
+ room = await client.joinOrCreate('game_room', { allowDebugCommands: true });
42
+
43
+ const resultPromise = new Promise<{ requestId: string; ok: boolean; result?: unknown }>(
44
+ (resolve) => {
45
+ room!.onMessage('__vgai:debugCommandResult', (payload: unknown) => {
46
+ resolve(payload as { requestId: string; ok: boolean; result?: unknown });
47
+ });
48
+ },
49
+ );
50
+
51
+ room.send('__vgai:debugCommand', { name: 'give-score', args: [5], requestId: 'req-1' });
52
+
53
+ const reply = await withTimeout(resultPromise, 5000, '__vgai:debugCommandResult');
54
+ expect(reply.requestId).toBe('req-1');
55
+ expect(reply.ok).toBe(true);
56
+ expect(reply.result).toEqual({ score: 5 });
57
+ }, 15000);
58
+
59
+ // AC-A3.2's refusal half (Acceptance Driver build plan Appendix B, D18's
60
+ // "off otherwise" server-side gate): a plain `npm run server` boot — no
61
+ // `allowDebugCommands` room option AND no `VGAI_ALLOW_DEBUG_COMMANDS` env
62
+ // var — must refuse `__vgai:debugCommand` rather than silently execute it.
63
+ it('refuses __vgai:debugCommand when booted without allowDebugCommands or the env var', async () => {
64
+ // Defensive: this room's `onCreate` also honors the env var (frozen
65
+ // decision: env-var OR room-option) — guard against it leaking in from
66
+ // whatever booted this test process, so the refusal path is actually
67
+ // exercised rather than accidentally skipped.
68
+ const previousEnv = process.env['VGAI_ALLOW_DEBUG_COMMANDS'];
69
+ delete process.env['VGAI_ALLOW_DEBUG_COMMANDS'];
70
+ try {
71
+ server = await startLoopbackColyseus();
72
+ const client = new Client(server.url);
73
+
74
+ // No `allowDebugCommands` option at all — the default a plain `npm run
75
+ // server` boot gets.
76
+ room = await client.joinOrCreate('game_room', {});
77
+
78
+ const resultPromise = new Promise<{ requestId: string; ok: boolean; error?: unknown }>(
79
+ (resolve) => {
80
+ room!.onMessage('__vgai:debugCommandResult', (payload: unknown) => {
81
+ resolve(payload as { requestId: string; ok: boolean; error?: unknown });
82
+ });
83
+ },
84
+ );
85
+
86
+ room.send('__vgai:debugCommand', { name: 'give-score', args: [5], requestId: 'req-2' });
87
+
88
+ const reply = await withTimeout(resultPromise, 5000, '__vgai:debugCommandResult');
89
+ expect(reply.requestId).toBe('req-2');
90
+ expect(reply.ok).toBe(false);
91
+ expect(reply.error).toBe('debug commands disabled');
92
+ } finally {
93
+ if (previousEnv === undefined) {
94
+ delete process.env['VGAI_ALLOW_DEBUG_COMMANDS'];
95
+ } else {
96
+ process.env['VGAI_ALLOW_DEBUG_COMMANDS'] = previousEnv;
97
+ }
98
+ }
99
+ }, 15000);
100
+ });
@@ -0,0 +1,30 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "ESNext",
5
+ "moduleResolution": "bundler",
6
+ "lib": ["ES2022", "DOM"],
7
+ // `tests/logic/room.test.ts` (Task 4.4) relatively imports `../../server/
8
+ // loopback.ts`, which transitively pulls in `server/rooms/*.ts` — those
9
+ // use `@colyseus/schema`'s `@type(...)` property decorators, which only
10
+ // type-check under the legacy decorators calling convention (matches
11
+ // `server/tsconfig.json`'s own flags).
12
+ "experimentalDecorators": true,
13
+ "useDefineForClassFields": false,
14
+ "strict": true,
15
+ "noUncheckedIndexedAccess": true,
16
+ "noFallthroughCasesInSwitch": true,
17
+ "noPropertyAccessFromIndexSignature": true,
18
+ "exactOptionalPropertyTypes": true,
19
+ "noUnusedLocals": true,
20
+ "noUnusedParameters": true,
21
+ "verbatimModuleSyntax": true,
22
+ "esModuleInterop": true,
23
+ "forceConsistentCasingInFileNames": true,
24
+ "resolveJsonModule": true,
25
+ "isolatedModules": true,
26
+ "skipLibCheck": true,
27
+ "noEmit": true
28
+ },
29
+ "include": ["./**/*.ts"]
30
+ }
@@ -10,7 +10,7 @@ import { loadGameManifestFile } from '@vgai/engine/manifest/load-file';
10
10
  // gets a working `npm run validate-manifest`. Validates each given
11
11
  // `vgai.game.json` path via `loadGameManifestFile` (parse -> cross-field
12
12
  // checks -> resolution, see docs/GAME-MANIFEST-DESIGN.md §5) and prints the
13
- // resolved world list (id, kind, resolved adapter identity, per-context
13
+ // resolved adapter-root list (id, adapter identity, per-context
14
14
  // capability tiers) on success. Any failure prints a descriptive error and
15
15
  // exits 1.
16
16
  //
@@ -32,13 +32,13 @@ for (const manifestPath of manifestPaths) {
32
32
  console.log(
33
33
  `${manifestPath}: OK — "${resolved.name}" v${resolved.version} (engine ${resolved.engine.version})`,
34
34
  );
35
- for (const world of resolved.worlds) {
36
- const { adapter } = world;
35
+ for (const root of resolved.roots) {
36
+ const { adapter } = root;
37
37
  const adapterLabel =
38
38
  adapter.type === 'ingest' ? `${adapter.identity} (${adapter.strategy})` : adapter.identity;
39
39
  console.log(
40
- ` world "${world.id}" kind=${world.kind} adapter=${adapterLabel} ` +
41
- `tiers={local: ${world.capabilities.local}, hosted: ${world.capabilities.hosted}}`,
40
+ ` root "${root.id}" adapter=${adapterLabel} ` +
41
+ `tiers={local: ${root.capabilities.local}, hosted: ${root.capabilities.hosted}}`,
42
42
  );
43
43
  }
44
44
  } catch (e) {
@@ -6,7 +6,7 @@ import {
6
6
  isGameComponentClass,
7
7
  } from '@vgai/engine/scene/component-registry';
8
8
  import { parsePrefabFile, parseSceneFile, SceneParseError } from '@vgai/engine/scene/parse';
9
- import type { SceneEntity } from '@vgai/engine/scene/scene-types';
9
+ import type { PrefabFile, SceneEntity, SceneFile } from '@vgai/engine/scene/scene-types';
10
10
  import { ASSET_CONTENT_EXTENSIONS, validateAssetContentFile } from './validate-asset-content';
11
11
 
12
12
  // ---------------------------------------------------------------------------
@@ -30,7 +30,21 @@ import { ASSET_CONTENT_EXTENSIONS, validateAssetContentFile } from './validate-a
30
30
  // 1. Structural validity (Zod schema parse) — scenes, prefabs, AND the
31
31
  // fetched-asset formats (.mat.json/.inputmap.json/.instances.json)
32
32
  // 2. Asset references point to files that exist on disk
33
- // 3. Components exist in the registry (if --components flag provided)
33
+ // 3. Components exist in the registry, AND every authored field is one the
34
+ // component's schema actually declares — run BY DEFAULT (no flag
35
+ // needed): a leftover scene referencing a component that was renamed or
36
+ // deleted used to pass "all OK" as long as it was --components-checked
37
+ // by hand. `src/scripts/registry(.ts)` is imported opportunistically —
38
+ // if it imports cleanly, component checks run; if it can't be imported
39
+ // (missing, or a real syntax/type error), ONE line explains that
40
+ // component-level validation was SKIPPED and why, and the command still
41
+ // exits 0 on structural success (a broken registry blocks its own
42
+ // typecheck already; this command must not become a second, confusing
43
+ // way to learn that).
44
+ // `--components` upgrades this to STRICT mode: a registry that can't be
45
+ // imported is then a hard failure (exit 1) instead of a soft skip — for
46
+ // callers (CI, a pre-release check) that need to assert component
47
+ // validation definitely ran, not merely attempted.
34
48
  // ---------------------------------------------------------------------------
35
49
 
36
50
  const args = process.argv.slice(2);
@@ -42,29 +56,47 @@ if (!existsSync(publicDir)) {
42
56
  process.exit(1);
43
57
  }
44
58
 
45
- // Optionally load component registry for component-level validation.
46
- // Pass --components to enable (requires boilerplate examples to be available).
47
- const validateComponents = args.includes('--components');
59
+ // Component-level validation is opt-OUT (default ON), not opt-in.
60
+ // `--components` only changes what happens when the registry can't be
61
+ // imported: soft-skip (default) vs. hard-fail (strict).
62
+ const strictComponents = args.includes('--components');
48
63
  let componentRegistry: ComponentRegistry | null = null;
49
64
 
50
- if (validateComponents) {
51
- // Import the project's component registry.
52
- // The registry path is relative to the root folder being validated.
53
- const registryPath = join(rootDir, 'src/scripts/registry');
65
+ // The registry path is relative to the root folder being validated.
66
+ const registryPath = join(rootDir, 'src/scripts/registry');
67
+ const hasComponentDocuments =
68
+ collectFiles(publicDir, '.vscn.json').length > 0 ||
69
+ collectFiles(publicDir, '.prefab.json').length > 0;
70
+ // React-only projects deliberately have no scene documents or component
71
+ // registry. Silence is the honest result there: there is nothing whose
72
+ // component names could be checked, even in --components mode.
73
+ if (hasComponentDocuments) {
54
74
  try {
55
75
  const mod = await import(registryPath);
56
- componentRegistry = mod.componentRegistry;
57
- if (!componentRegistry) {
76
+ if (mod.componentRegistry) {
77
+ componentRegistry = mod.componentRegistry;
78
+ } else if (strictComponents) {
58
79
  console.error(`Registry at ${registryPath} does not export "componentRegistry"`);
59
80
  process.exit(1);
81
+ } else {
82
+ console.warn(
83
+ `Component-level validation skipped — ${registryPath} does not export "componentRegistry" ` +
84
+ '(pass --components to make this a hard failure). Continuing with structural checks only.',
85
+ );
60
86
  }
61
87
  } catch (e) {
62
- console.error(
63
- `--components requires a project with src/scripts/registry.ts exporting componentRegistry.\n` +
64
- ` Looked in: ${registryPath}\n` +
65
- ` Error: ${e}`,
88
+ if (strictComponents) {
89
+ console.error(
90
+ `--components requires a project with src/scripts/registry.ts exporting componentRegistry.\n` +
91
+ ` Looked in: ${registryPath}\n` +
92
+ ` Error: ${e}`,
93
+ );
94
+ process.exit(1);
95
+ }
96
+ console.warn(
97
+ `Component-level validation skipped — could not import registry at ${registryPath}: ${e} ` +
98
+ '(pass --components to make this a hard failure). Continuing with structural checks only.',
66
99
  );
67
- process.exit(1);
68
100
  }
69
101
  }
70
102
 
@@ -149,7 +181,7 @@ for (const path of assetContentFiles) {
149
181
  for (const path of sceneFiles) {
150
182
  const raw = JSON.parse(readFileSync(path, 'utf-8'));
151
183
 
152
- let data;
184
+ let data: SceneFile;
153
185
  try {
154
186
  data = parseSceneFile(raw);
155
187
  } catch (e) {
@@ -177,7 +209,7 @@ for (const path of sceneFiles) {
177
209
  for (const path of prefabFiles) {
178
210
  const raw = JSON.parse(readFileSync(path, 'utf-8'));
179
211
 
180
- let data;
212
+ let data: PrefabFile;
181
213
  try {
182
214
  data = parsePrefabFile(raw);
183
215
  } catch (e) {
@@ -1,21 +1,28 @@
1
1
  {
2
- "manifestVersion": 1,
3
- "name": "my-game",
2
+ "$schema": "./packages/engine/schemas/vgai-game.schema.json",
3
+ "manifestVersion": 2,
4
+ "name": "My Game",
5
+ "appId": "com.example.mygame",
6
+ "editorPort": 5173,
4
7
  "version": "0.1.0",
5
8
  "engine": {
6
- "version": "0.2.0"
9
+ "version": "0.4.0-canary.20260715.0"
7
10
  },
8
- "worlds": [
9
- {
10
- "id": "main",
11
- "kind": "threejs",
12
- "adapter": "default",
13
- "entry": "src/scripts/main.ts",
14
- "scene": "scenes/default.vscn.json"
15
- }
16
- ],
17
11
  "resolution": {
18
12
  "width": 1280,
19
13
  "height": 720
20
- }
14
+ },
15
+ "roots": [
16
+ {
17
+ "id": "world",
18
+ "adapter": "threejs",
19
+ "scene": "scenes/default.vscn.json"
20
+ },
21
+ {
22
+ "id": "ui",
23
+ "adapter": "react",
24
+ "entry": "src/ui/game.tsx",
25
+ "zOrder": 100
26
+ }
27
+ ]
21
28
  }
@@ -8,7 +8,9 @@ import { defineConfig } from 'vite';
8
8
  import { vgaiDataCheck } from '../../engine/src/data/vite-plugin-data';
9
9
  // Config-relative TS imports get bundled the same way — that is what lets the
10
10
  // project's executable Zod schemas reach the build-time check below.
11
+ import { manifestEntryModulesPlugin } from './manifest-entry-modules-plugin';
11
12
  import { dataAssets } from './src/data/assets';
13
+ import manifest from './vgai.game.json';
12
14
 
13
15
  // P2P builds (launched with `?net=p2p-host` / `?net=p2p-join`) route the Colyseus
14
16
  // packages onto @vgai/p2p-colyseus's browser-safe compat shims: `browser.ts` exposes
@@ -33,6 +35,41 @@ const p2pAliases = p2pBuild
33
35
  }
34
36
  : {};
35
37
 
38
+ /**
39
+ * Run-4 dry-run friction #2 — auto-detect drvfs the SAME way the editor dev
40
+ * server does (`packages/editor/server/server-utils.ts`'s
41
+ * `resolveWatcherPollOptions`, and `dev.ts`'s own `projectOnDrvfs` check):
42
+ * on WSL, a project living on a Windows drive (`/mnt/<drive>/…`) never fires
43
+ * inotify, so without polling this standalone server (`npm run game`)
44
+ * silently misses every external file edit — the same failure mode
45
+ * `dev.ts`'s comment documents for the editor. Before this fix, this file
46
+ * read ONLY `VGAI_WATCH_POLL`, so a project on drvfs polled in the editor
47
+ * but NOT in the standalone server — the two disagreed for no reason a
48
+ * developer could see.
49
+ *
50
+ * Not a shared import: this file cannot reach
51
+ * `packages/editor/server/server-utils.ts` the way it reaches the engine
52
+ * (`../../engine/src/...` above) — a scaffolded project depends on
53
+ * `@vgai/engine` and gets the CLI scaffolder's engine-relative path rewrite
54
+ * (`rewriteEngineRelativeFilePath`, `create-vgai-project/src/scaffold.ts`);
55
+ * there is no equivalent rewrite (or dependency) for the editor's `server/`
56
+ * code, which is never vendored into a scaffolded project at all. So this
57
+ * duplicates the tiny drvfs check rather than reaching across a package
58
+ * boundary that doesn't exist here — same contract as the editor's own
59
+ * helper: `VGAI_WATCH_POLL=0` forces polling off anywhere, `=1`/`=<ms>`
60
+ * forces it on with that interval, unset auto-enables on a drvfs mount.
61
+ */
62
+ function resolveWatchOption(): { usePolling: true; interval: number } | undefined {
63
+ const raw = process.env.VGAI_WATCH_POLL;
64
+ if (raw !== undefined && raw !== '') {
65
+ if (raw === '0') return undefined;
66
+ const ms = Number(raw);
67
+ return { usePolling: true, interval: Number.isFinite(ms) && ms > 1 ? ms : 1000 };
68
+ }
69
+ const onDrvfs = process.platform === 'linux' && /^\/mnt\/[a-z]\//i.test(__dirname);
70
+ return onDrvfs ? { usePolling: true, interval: 1000 } : undefined;
71
+ }
72
+
36
73
  export default defineConfig({
37
74
  // Build-path validation (docs/DATA-TOOLS-DESIGN.md §6.7, build-only): every
38
75
  // registered data asset must still parse through its schema (the EXACT
@@ -40,6 +77,7 @@ export default defineConfig({
40
77
  // no `src/tools/` module may reach the shipped bundle (§4: tools are
41
78
  // editor-only — never serve testers a build with dev/cheat surfaces).
42
79
  plugins: [
80
+ manifestEntryModulesPlugin(manifest),
43
81
  vgaiDataCheck({
44
82
  root: __dirname,
45
83
  assets: dataAssets.map((a) => ({
@@ -53,6 +91,22 @@ export default defineConfig({
53
91
  '@engine': path.resolve(__dirname, '../../engine/src'),
54
92
  ...p2pAliases,
55
93
  },
94
+ // react/react-dom dedupe (GH #123): the '@engine' alias above resolves
95
+ // at the SOURCE-LINKED engine checkout, so when Vite bundles the
96
+ // engine's react bridge module (`src/react/game-state.tsx` — the
97
+ // `<GameProvider>` / `useGameState` HUD bridge), module resolution walks
98
+ // up from THAT file and finds the CHECKOUT's `node_modules/react` — a
99
+ // different physical copy (often a different version) than this
100
+ // project's own. Two Reacts in one page means the Context object
101
+ // `GameProvider` creates is not the one this project's tree looks up
102
+ // via `useContext`, so the documented HUD pattern crashes with "Invalid
103
+ // hook call" / "Cannot read properties of null (reading 'useContext')"
104
+ // on first render.
105
+ // `dedupe` forces Vite to collapse both import paths onto a single
106
+ // physical copy. Same fix, same reasoning, already applied for the
107
+ // identical dual-instance failure in this repo's own root
108
+ // `vite.config.ts` and in `examples/r3f-probe/vite.config.ts`.
109
+ dedupe: ['react', 'react-dom'],
56
110
  },
57
111
  optimizeDeps: {
58
112
  // Pre-bundle deps that are only reached through the dynamically imported
@@ -94,22 +148,29 @@ export default defineConfig({
94
148
  // observed causing a CI e2e spec to hang waiting on the wrong server. See
95
149
  // packages/editor/e2e/helpers/server.ts's `startStandaloneServer`.
96
150
  strictPort: true,
97
- // VGAI_WATCH_POLL=1 (or =<ms>): poll for file changes instead of relying
98
- // on inotify — REQUIRED on WSL when the project lives on a Windows drive
99
- // (/mnt/c, drvfs: inotify never fires there), or edits to
100
- // src/data/*.data.json silently never hot-reload into the running game
101
- // (docs/DATA-TOOLS-DESIGN.md §2.3). Same env var the EDITOR dev server
102
- // honors, so one knob covers both surfaces. Safe to enable here: this
103
- // standalone server only watches the project tree, which is small.
104
- ...(process.env.VGAI_WATCH_POLL
105
- ? {
106
- watch: {
107
- usePolling: true,
108
- interval:
109
- Number(process.env.VGAI_WATCH_POLL) > 1 ? Number(process.env.VGAI_WATCH_POLL) : 1000,
110
- },
111
- }
112
- : {}),
151
+ // Poll for file changes instead of relying on inotify — AUTO-ENABLED on
152
+ // WSL when the project lives on a Windows drive (/mnt/c, drvfs: inotify
153
+ // never fires there), or edits to src/data/*.data.json silently never
154
+ // hot-reload into the running game (docs/DATA-TOOLS-DESIGN.md §2.3).
155
+ // `VGAI_WATCH_POLL` is an explicit override (`=0` off anywhere, `=1`/
156
+ // `=<ms>` on anywhere) — see `resolveWatchOption` above, which the
157
+ // EDITOR dev server's own auto-detect mirrors, so one behavior covers
158
+ // both surfaces without the developer having to set anything. Safe to
159
+ // enable here: this standalone server only watches the project tree,
160
+ // which is small.
161
+ //
162
+ // VGAI_NO_WATCH=1 (`vgai probe`, Acceptance Driver build plan Task 4.1):
163
+ // disable watching entirely — a mid-run Vite reload resets
164
+ // `window.__vgai`/whatever is driving the standalone page out from under
165
+ // an in-flight acceptance run (the hollowstone reload-kills-the-run
166
+ // lesson). Mutually exclusive with the poll option (same `server.watch`
167
+ // key) — NO_WATCH wins when both would otherwise apply.
168
+ ...(process.env.VGAI_NO_WATCH
169
+ ? { watch: null }
170
+ : (() => {
171
+ const watch = resolveWatchOption();
172
+ return watch ? { watch } : {};
173
+ })()),
113
174
  allowedHosts:
114
175
  process.env.VITE_ALLOWED_HOSTS === 'all'
115
176
  ? true