@volter/editor-core 0.5.57

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 (719) hide show
  1. package/BUNDLED_NOTICES +1527 -0
  2. package/LICENSE +686 -0
  3. package/LICENSE-APACHE +202 -0
  4. package/NOTICE +18 -0
  5. package/README.md +24 -0
  6. package/dist/build/chunk-JS4D4XZ3.js +175 -0
  7. package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
  8. package/dist/build/vite-plugin-product-contributions.js +100 -0
  9. package/dist/build/vite-plugin-product-contributions.js.map +7 -0
  10. package/dist/build/vite-plugin-shared-react.js +25 -0
  11. package/dist/build/vite-plugin-shared-react.js.map +7 -0
  12. package/dist/build/vite-plugin-shared-three.js +86 -0
  13. package/dist/build/vite-plugin-shared-three.js.map +7 -0
  14. package/dist/server/chunk-KMJC7AGO.js +98 -0
  15. package/dist/server/chunk-KMJC7AGO.js.map +7 -0
  16. package/dist/server/chunk-PSILUMGS.js +46 -0
  17. package/dist/server/chunk-PSILUMGS.js.map +7 -0
  18. package/dist/server/frame-proxy.js +255 -0
  19. package/dist/server/frame-proxy.js.map +7 -0
  20. package/dist/server/open-browser.js +53 -0
  21. package/dist/server/open-browser.js.map +7 -0
  22. package/dist/server/process-shutdown.js +127 -0
  23. package/dist/server/process-shutdown.js.map +7 -0
  24. package/dist/server/session-registry.js +141 -0
  25. package/dist/server/session-registry.js.map +7 -0
  26. package/dist/server/spawn-opener.js +11 -0
  27. package/dist/server/spawn-opener.js.map +7 -0
  28. package/dist/server/worktree-identity.js +11 -0
  29. package/dist/server/worktree-identity.js.map +7 -0
  30. package/dist-server/packaged.mjs +88816 -0
  31. package/package.json +118 -0
  32. package/scripts/build-plugins.mjs +14 -0
  33. package/scripts/build-server.mjs +26 -0
  34. package/scripts/build-session.mjs +9 -0
  35. package/server/account-credentials.ts +60 -0
  36. package/server/account-service.ts +1434 -0
  37. package/server/adapter-region-includes.ts +47 -0
  38. package/server/asset-catalog-v2.ts +175 -0
  39. package/server/asset-history-snapshots.ts +196 -0
  40. package/server/asset-ledger-store.ts +195 -0
  41. package/server/asset-library-routes.ts +1595 -0
  42. package/server/blender-wasm-artifact.ts +430 -0
  43. package/server/boot-timings.ts +106 -0
  44. package/server/canonical-path.ts +50 -0
  45. package/server/checkout-workspace-preflight.ts +349 -0
  46. package/server/cloud-asset-catalog.ts +158 -0
  47. package/server/coding-inference-launch.ts +237 -0
  48. package/server/collaboration-account-client.ts +202 -0
  49. package/server/collaboration-attribution.ts +122 -0
  50. package/server/collaboration-session.ts +934 -0
  51. package/server/comfyui-bridge.ts +248 -0
  52. package/server/console-ledger.ts +499 -0
  53. package/server/creation-site-transform.ts +304 -0
  54. package/server/creation-site-write.ts +648 -0
  55. package/server/data-file-serialize.ts +158 -0
  56. package/server/editor-brand-html.ts +72 -0
  57. package/server/editor-control-socket.ts +366 -0
  58. package/server/editor-server-options.ts +190 -0
  59. package/server/editor-server.ts +1483 -0
  60. package/server/editor-sse.ts +352 -0
  61. package/server/engine-provenance.ts +169 -0
  62. package/server/engine-source-restart.ts +117 -0
  63. package/server/frame-bridge.ts +115 -0
  64. package/server/frame-proxy.ts +490 -0
  65. package/server/frame-workbench.ts +259 -0
  66. package/server/frontend-handoff.ts +229 -0
  67. package/server/game-globals-shadow.ts +113 -0
  68. package/server/gameplay-session-retention.ts +149 -0
  69. package/server/gameplay-sessions.ts +123 -0
  70. package/server/generation-jobs.ts +201 -0
  71. package/server/generation-reconciler.ts +137 -0
  72. package/server/generative-execution-context.ts +59 -0
  73. package/server/git-workflow.ts +612 -0
  74. package/server/harness-chat-caller.ts +36 -0
  75. package/server/harness-chat-service.ts +1681 -0
  76. package/server/idle-shutdown.ts +170 -0
  77. package/server/js-profiling-policy.ts +52 -0
  78. package/server/launcher-settings.ts +84 -0
  79. package/server/local-asset-catalog.ts +410 -0
  80. package/server/managed-account-defaults.ts +22 -0
  81. package/server/mock-control-plane.ts +540 -0
  82. package/server/model-import-conversion.ts +345 -0
  83. package/server/native-credential-store.ts +162 -0
  84. package/server/open-browser.ts +118 -0
  85. package/server/packaged.ts +1192 -0
  86. package/server/play-stall.ts +126 -0
  87. package/server/process-shutdown.ts +218 -0
  88. package/server/product-presets.ts +55 -0
  89. package/server/project-build-artifact.ts +95 -0
  90. package/server/project-components.ts +100 -0
  91. package/server/project-dependency-invalidation.ts +114 -0
  92. package/server/project-file-scan.ts +235 -0
  93. package/server/project-hmr-files.ts +215 -0
  94. package/server/project-install-roots.ts +210 -0
  95. package/server/project-kinds.ts +71 -0
  96. package/server/project-mcp-servers.ts +82 -0
  97. package/server/project-module-freshness.ts +109 -0
  98. package/server/project-module-instance.ts +375 -0
  99. package/server/project-optimize-deps-entries.ts +827 -0
  100. package/server/project-output-writer.ts +679 -0
  101. package/server/project-package-origin.ts +63 -0
  102. package/server/project-root-surface.ts +831 -0
  103. package/server/project-scratch-path.ts +47 -0
  104. package/server/project-script-hmr.ts +619 -0
  105. package/server/project-serving-plugins.ts +236 -0
  106. package/server/project-tools.ts +653 -0
  107. package/server/project-validation.ts +250 -0
  108. package/server/project-verbs.ts +127 -0
  109. package/server/project-view.ts +52 -0
  110. package/server/project-watch.ts +1134 -0
  111. package/server/project-work-coordinator.ts +288 -0
  112. package/server/provider-credentials.ts +331 -0
  113. package/server/recent-projects-store.ts +98 -0
  114. package/server/redact-secrets.ts +71 -0
  115. package/server/repository-presence.ts +267 -0
  116. package/server/routes/account.ts +357 -0
  117. package/server/routes/agents.ts +60 -0
  118. package/server/routes/assets.ts +154 -0
  119. package/server/routes/build.ts +13 -0
  120. package/server/routes/collaboration.ts +595 -0
  121. package/server/routes/configurations.ts +419 -0
  122. package/server/routes/context.ts +264 -0
  123. package/server/routes/control-plane.ts +1811 -0
  124. package/server/routes/logs.ts +272 -0
  125. package/server/routes/project-identity.ts +302 -0
  126. package/server/routes/project-open.ts +429 -0
  127. package/server/routes/project-source.ts +686 -0
  128. package/server/routes/project-state.ts +383 -0
  129. package/server/routes/relay.ts +1029 -0
  130. package/server/routes/route-helpers.ts +29 -0
  131. package/server/routes/served-modules.ts +138 -0
  132. package/server/routes/session-tabs.ts +196 -0
  133. package/server/routes/settings.ts +121 -0
  134. package/server/routes/share-control.ts +486 -0
  135. package/server/routes/themes.ts +116 -0
  136. package/server/routes/tools.ts +230 -0
  137. package/server/routes/worktrees.ts +595 -0
  138. package/server/scoped-game-css.ts +461 -0
  139. package/server/server-utils.ts +1194 -0
  140. package/server/session-product.ts +112 -0
  141. package/server/session-registry.ts +230 -0
  142. package/server/share-claims.ts +138 -0
  143. package/server/share-host.ts +526 -0
  144. package/server/share-session-gateway.ts +1362 -0
  145. package/server/share-tunnel.ts +123 -0
  146. package/server/spawn-opener.ts +74 -0
  147. package/server/support/play/log-format.ts +76 -0
  148. package/server/support/play/session-record.ts +199 -0
  149. package/server/support/project/build-discipline.ts +718 -0
  150. package/server/support/project/inspection-node.ts +119 -0
  151. package/server/support/project/log-naming.ts +54 -0
  152. package/server/support/project/provenance.ts +290 -0
  153. package/server/support/project/run-name.ts +18 -0
  154. package/server/support/project/session-journal.ts +830 -0
  155. package/server/support/project/shared.ts +327 -0
  156. package/server/tab-bootstrap.ts +62 -0
  157. package/server/tab-heartbeat.ts +477 -0
  158. package/server/tab-lifecycle.ts +550 -0
  159. package/server/tab-presence.ts +1508 -0
  160. package/server/team-agent-mirror.ts +95 -0
  161. package/server/twin-auth.ts +138 -0
  162. package/server/vendored-lock-recorder.ts +968 -0
  163. package/server/worktree-identity.ts +121 -0
  164. package/server/worktree-management.ts +398 -0
  165. package/server/worktree-retention.d.mts +13 -0
  166. package/server/worktree-retention.mjs +205 -0
  167. package/src/EditorContext.tsx +169 -0
  168. package/src/account.ts +333 -0
  169. package/src/action-registry.ts +532 -0
  170. package/src/active-product.ts +74 -0
  171. package/src/active-project.ts +155 -0
  172. package/src/adapter-editor-config.ts +25 -0
  173. package/src/adapter-observation.ts +49 -0
  174. package/src/animation/stage-transport.ts +379 -0
  175. package/src/animation/three-clips-subject.ts +172 -0
  176. package/src/api/asset-library-wire.ts +45 -0
  177. package/src/api/assets.ts +365 -0
  178. package/src/api/base.ts +10 -0
  179. package/src/api/build.ts +99 -0
  180. package/src/api/git-wire.ts +56 -0
  181. package/src/api/logs.ts +92 -0
  182. package/src/api/project-identity.ts +74 -0
  183. package/src/api/project-open.ts +355 -0
  184. package/src/api/project-source.ts +162 -0
  185. package/src/api/project-state.ts +107 -0
  186. package/src/api/relay.ts +268 -0
  187. package/src/api/settings.ts +36 -0
  188. package/src/api/themes.ts +45 -0
  189. package/src/api/worktrees.ts +257 -0
  190. package/src/asset-compare-core.ts +171 -0
  191. package/src/asset-compare.ts +294 -0
  192. package/src/asset-editor-context.tsx +100 -0
  193. package/src/asset-events.ts +97 -0
  194. package/src/asset-inspector-actions.ts +87 -0
  195. package/src/asset-preview-framing.ts +357 -0
  196. package/src/asset-preview.ts +2802 -0
  197. package/src/asset-selection-viewer-registry.ts +113 -0
  198. package/src/asset-selection.ts +133 -0
  199. package/src/asset-workflow/asset-capabilities.ts +344 -0
  200. package/src/asset-workflow/asset-import-jobs.ts +106 -0
  201. package/src/asset-workflow/asset-ledger-backend.ts +126 -0
  202. package/src/asset-workflow/asset-ledger.ts +156 -0
  203. package/src/asset-workflow/asset-materialization-report.ts +140 -0
  204. package/src/asset-workflow/asset-pack-manifest.ts +320 -0
  205. package/src/asset-workflow/asset-types.ts +142 -0
  206. package/src/asset-workflow/asset-workflow-quality.ts +61 -0
  207. package/src/asset-workflow/audio-preview-player.ts +193 -0
  208. package/src/asset-workflow/audio-waveform.ts +22 -0
  209. package/src/asset-workflow/cloud-asset-client.ts +263 -0
  210. package/src/asset-workflow/folder-preview.ts +345 -0
  211. package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
  212. package/src/asset-workflow/image-view-scale.ts +32 -0
  213. package/src/asset-workflow/import-contract.ts +124 -0
  214. package/src/asset-workflow/ledger-write-lock.ts +244 -0
  215. package/src/asset-workflow/model-inspection.ts +818 -0
  216. package/src/asset-workflow/pixi-spritesheet.ts +197 -0
  217. package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
  218. package/src/asset-workflow/project-asset-commands.ts +23 -0
  219. package/src/asset-workflow/project-asset-health.ts +139 -0
  220. package/src/asset-workflow/project-asset-operations.ts +154 -0
  221. package/src/asset-workflow/project-asset-roots.ts +68 -0
  222. package/src/asset-workflow/project-content.ts +288 -0
  223. package/src/asset-workflow/project-source-index.ts +550 -0
  224. package/src/asset-workflow/thumbnail-system.ts +256 -0
  225. package/src/authoring/active-adapter.ts +199 -0
  226. package/src/authoring/active-systems.ts +422 -0
  227. package/src/authoring/adapter-key.ts +18 -0
  228. package/src/authoring/authoring-asset-url.ts +27 -0
  229. package/src/authoring/bootstrap-state.ts +49 -0
  230. package/src/authoring/boundary-authoring-adapter.ts +184 -0
  231. package/src/authoring/breakpoint-state.ts +43 -0
  232. package/src/authoring/canvas-scene-guides.ts +76 -0
  233. package/src/authoring/component-instance-root.ts +171 -0
  234. package/src/authoring/composite-authoring-adapter.ts +2110 -0
  235. package/src/authoring/consumer-actions.ts +520 -0
  236. package/src/authoring/css-numeric-style.ts +97 -0
  237. package/src/authoring/design-time-layers.ts +849 -0
  238. package/src/authoring/design-time-mount-registry.ts +235 -0
  239. package/src/authoring/design-time-settle.ts +343 -0
  240. package/src/authoring/edit-mode-authoring.ts +619 -0
  241. package/src/authoring/eyedropper-session.ts +60 -0
  242. package/src/authoring/instance-source-menu-register.ts +13 -0
  243. package/src/authoring/instance-source-menu.ts +135 -0
  244. package/src/authoring/layered-pick.ts +183 -0
  245. package/src/authoring/live-gesture-lock.ts +50 -0
  246. package/src/authoring/live-object-transform.ts +62 -0
  247. package/src/authoring/mount-failure-report.ts +154 -0
  248. package/src/authoring/mounted-root-subjects.ts +144 -0
  249. package/src/authoring/no-authoring-adapter.ts +55 -0
  250. package/src/authoring/null-inspection-subjects.tsx +75 -0
  251. package/src/authoring/object3d-document-persistence.ts +106 -0
  252. package/src/authoring/object3d-document-session-registry.ts +120 -0
  253. package/src/authoring/object3d-document-session.ts +1326 -0
  254. package/src/authoring/object3d-gesture-controller.ts +113 -0
  255. package/src/authoring/panel-authoring.ts +121 -0
  256. package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
  257. package/src/authoring/prefab-instance-section-model.ts +55 -0
  258. package/src/authoring/project-authoring-session.ts +105 -0
  259. package/src/authoring/provenance.ts +99 -0
  260. package/src/authoring/quarks-particle-systems.ts +19 -0
  261. package/src/authoring/react-canvas-navigation.ts +255 -0
  262. package/src/authoring/react-design-canvas-style.ts +20 -0
  263. package/src/authoring/react-story-board.ts +937 -0
  264. package/src/authoring/selection-scope.ts +195 -0
  265. package/src/authoring/shell-document-ops.ts +169 -0
  266. package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
  267. package/src/authoring/shell-viewport-policy.ts +48 -0
  268. package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
  269. package/src/authoring/stories-scope.ts +35 -0
  270. package/src/authoring/story-board-chrome-fit.ts +107 -0
  271. package/src/authoring/story-board-presentation.ts +111 -0
  272. package/src/authoring/three-projection-core.ts +226 -0
  273. package/src/authoring/viewport-pick-context.ts +40 -0
  274. package/src/authoring/viewport-raycast.ts +240 -0
  275. package/src/authoring/viewport-tool-context.ts +73 -0
  276. package/src/authoring/world-canvas-viewport-state.ts +35 -0
  277. package/src/authoring/world-hidden-viewport.ts +152 -0
  278. package/src/authoring/world-pan-state.ts +198 -0
  279. package/src/authoring/world-session-state.ts +101 -0
  280. package/src/authoring/write-pipe.ts +173 -0
  281. package/src/availability-tick.ts +66 -0
  282. package/src/bitmap-label.ts +120 -0
  283. package/src/blender-tab-metrics.ts +161 -0
  284. package/src/board-open-actions.ts +20 -0
  285. package/src/boot-routing.ts +391 -0
  286. package/src/build-identity.ts +15 -0
  287. package/src/bytes-codec.ts +62 -0
  288. package/src/camera-authoring.ts +175 -0
  289. package/src/cancellation-reason.ts +58 -0
  290. package/src/canvas-preview-frames.ts +482 -0
  291. package/src/capture-camera-pose.ts +77 -0
  292. package/src/chrome-registry.ts +159 -0
  293. package/src/chrome-slot-registry.ts +91 -0
  294. package/src/collaboration-client.ts +264 -0
  295. package/src/collaboration-presence.ts +41 -0
  296. package/src/command-dispatch.ts +19 -0
  297. package/src/command-listener.ts +2743 -0
  298. package/src/command-registry.ts +70 -0
  299. package/src/component-board-registry.ts +205 -0
  300. package/src/component-states-registry.ts +200 -0
  301. package/src/components/AgentPresentationNotice.tsx +75 -0
  302. package/src/components/AlignToolbar.tsx +204 -0
  303. package/src/components/AppRoot.tsx +394 -0
  304. package/src/components/ApplicationMenus.tsx +415 -0
  305. package/src/components/AssetBrowser.tsx +2843 -0
  306. package/src/components/AssetEditorShell.tsx +216 -0
  307. package/src/components/AssetInspectorToolSection.tsx +124 -0
  308. package/src/components/BoardRulers.tsx +354 -0
  309. package/src/components/CameraInfo.tsx +81 -0
  310. package/src/components/CanvasSceneViewport.tsx +556 -0
  311. package/src/components/CapabilityCoverageSection.tsx +185 -0
  312. package/src/components/CenterDocuments.tsx +22 -0
  313. package/src/components/ChromeSlot.tsx +20 -0
  314. package/src/components/CodeView.tsx +470 -0
  315. package/src/components/CollaborationHeaderControl.css +74 -0
  316. package/src/components/CompactInspectorCard.tsx +190 -0
  317. package/src/components/CompactInspectorShell.tsx +39 -0
  318. package/src/components/ConsolePanel.css +55 -0
  319. package/src/components/ConsolePanel.tsx +270 -0
  320. package/src/components/DefaultEditorLayout.tsx +106 -0
  321. package/src/components/DocumentHeaderStrip.tsx +96 -0
  322. package/src/components/DocumentShelfRail.tsx +45 -0
  323. package/src/components/DocumentThumbnail.tsx +345 -0
  324. package/src/components/EditorLeaseGuard.tsx +372 -0
  325. package/src/components/ErrorBanner.tsx +123 -0
  326. package/src/components/FolderPreviewTile.tsx +159 -0
  327. package/src/components/GameHierarchy.tsx +3842 -0
  328. package/src/components/GameplaySessionTimeline.tsx +295 -0
  329. package/src/components/InspectionProjection.tsx +968 -0
  330. package/src/components/Inspector.tsx +233 -0
  331. package/src/components/InspectorCanvasPreview.tsx +35 -0
  332. package/src/components/InspectorFieldsSection.tsx +290 -0
  333. package/src/components/InspectorObjectPreview.tsx +57 -0
  334. package/src/components/InspectorStoriesSection.tsx +92 -0
  335. package/src/components/InspectorToolSection.tsx +96 -0
  336. package/src/components/InspectorTransformSection.tsx +245 -0
  337. package/src/components/LightExplorerPanel.tsx +433 -0
  338. package/src/components/MediaProperties.tsx +145 -0
  339. package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
  340. package/src/components/Object3DDocumentToolbar.css +100 -0
  341. package/src/components/Object3DDocumentToolbar.tsx +454 -0
  342. package/src/components/Object3DDocumentViewport.tsx +58 -0
  343. package/src/components/ProjectHeader.css +617 -0
  344. package/src/components/ProjectHeader.tsx +328 -0
  345. package/src/components/ProjectLayout.tsx +249 -0
  346. package/src/components/ReactCanvasControls.tsx +284 -0
  347. package/src/components/RootSelectionOverlay.tsx +3162 -0
  348. package/src/components/RootTextEditor.tsx +79 -0
  349. package/src/components/SaveStatus.tsx +70 -0
  350. package/src/components/StageHost.tsx +1954 -0
  351. package/src/components/StageOverlays.tsx +21 -0
  352. package/src/components/StartupErrorScreen.tsx +76 -0
  353. package/src/components/StartupLoadingScreen.tsx +65 -0
  354. package/src/components/StatsOverlay.tsx +78 -0
  355. package/src/components/SurfaceStateOverlay.tsx +24 -0
  356. package/src/components/ToolContributionSurfaces.tsx +65 -0
  357. package/src/components/ToolHost.tsx +370 -0
  358. package/src/components/ToolObject3DPreview.tsx +39 -0
  359. package/src/components/Toolbar.tsx +595 -0
  360. package/src/components/TransientHint.tsx +44 -0
  361. package/src/components/TransportStrip.tsx +174 -0
  362. package/src/components/VersionControlSection.tsx +470 -0
  363. package/src/components/VgaiLogo.css +83 -0
  364. package/src/components/VgaiLogo.tsx +35 -0
  365. package/src/components/ViewportControlsHint.tsx +60 -0
  366. package/src/components/ViewportFurniture.tsx +401 -0
  367. package/src/components/ViewportOverlay.tsx +145 -0
  368. package/src/components/ViewportOverlaysMenu.tsx +153 -0
  369. package/src/components/ViewportShadingMenu.tsx +300 -0
  370. package/src/components/ViewportViewMenu.tsx +101 -0
  371. package/src/components/WorkspaceDocumentSurface.tsx +204 -0
  372. package/src/components/WorkspaceUtilitySurface.tsx +22 -0
  373. package/src/components/WorktreeSwitcher.css +239 -0
  374. package/src/components/WorktreeSwitcher.tsx +890 -0
  375. package/src/components/account-documents.tsx +1162 -0
  376. package/src/components/asset-documents.tsx +812 -0
  377. package/src/components/asset-editor-persistence.ts +216 -0
  378. package/src/components/asset-selection-section.tsx +535 -0
  379. package/src/components/asset-thumbnails.tsx +312 -0
  380. package/src/components/asset-viewers/AudioViewer.tsx +201 -0
  381. package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
  382. package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
  383. package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
  384. package/src/components/asset-viewers/ImageViewer.tsx +300 -0
  385. package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
  386. package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
  387. package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
  388. package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
  389. package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
  390. package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
  391. package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
  392. package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
  393. package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
  394. package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
  395. package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
  396. package/src/components/asset-viewers/VideoViewer.tsx +101 -0
  397. package/src/components/asset-viewers/shader-source.ts +144 -0
  398. package/src/components/asset-workflow.css +731 -0
  399. package/src/components/board-guides.ts +150 -0
  400. package/src/components/compact-inspector.css +539 -0
  401. package/src/components/core-utilities.tsx +90 -0
  402. package/src/components/editor-notifications.css +40 -0
  403. package/src/components/engine-workspace.css +274 -0
  404. package/src/components/inspector-preview-section.tsx +238 -0
  405. package/src/components/inspector-property-grouping.ts +64 -0
  406. package/src/components/inspector-revert-label.ts +20 -0
  407. package/src/components/inspector-selection.ts +42 -0
  408. package/src/components/inspector-stories-gating.ts +171 -0
  409. package/src/components/inspector-transform-subject.ts +11 -0
  410. package/src/components/inspector-transform.ts +75 -0
  411. package/src/components/kind-documents.tsx +500 -0
  412. package/src/components/palette-action-publisher.tsx +140 -0
  413. package/src/components/primitives/DraftColorInput.tsx +74 -0
  414. package/src/components/product-shell.css +1829 -0
  415. package/src/components/project-tool-documents.tsx +410 -0
  416. package/src/components/scene-documents.tsx +223 -0
  417. package/src/components/stage-keyboard.tsx +37 -0
  418. package/src/components/stage-overlay-set.tsx +107 -0
  419. package/src/components/stage-presence-markers.ts +478 -0
  420. package/src/components/standard-viewport-dressing.ts +417 -0
  421. package/src/components/status-contributions.tsx +403 -0
  422. package/src/components/tool-documents.tsx +309 -0
  423. package/src/components/tool-schema-form.tsx +262 -0
  424. package/src/components/use-after-paint.ts +41 -0
  425. package/src/components/use-project-image-assets.ts +86 -0
  426. package/src/components/viewport-header-controls.css +90 -0
  427. package/src/components/viewport-surface-status.tsx +55 -0
  428. package/src/components/workspace-history.ts +32 -0
  429. package/src/components/workspace-static-panel-registry.tsx +152 -0
  430. package/src/components/workspace-surfaces.css +621 -0
  431. package/src/components/world-documents.tsx +586 -0
  432. package/src/components/world-overlay-gestures.ts +1694 -0
  433. package/src/composite-screenshot.ts +1641 -0
  434. package/src/console-sync.ts +131 -0
  435. package/src/constraint-helper.ts +338 -0
  436. package/src/content-entry-source-registry.ts +184 -0
  437. package/src/coverage/authoring-seam-evidence.ts +300 -0
  438. package/src/coverage/canvas-reveal.ts +192 -0
  439. package/src/coverage/design-time-surfaces.ts +101 -0
  440. package/src/coverage/live-seam-evidence.ts +11 -0
  441. package/src/coverage/ontology-invariants.ts +466 -0
  442. package/src/coverage/session-vitals.ts +501 -0
  443. package/src/coverage/system-seam-evidence.ts +72 -0
  444. package/src/crash-null-boundary.ts +36 -0
  445. package/src/creation-site-edit.ts +1479 -0
  446. package/src/creation-site-registry.ts +160 -0
  447. package/src/delegate-harness-registry.ts +143 -0
  448. package/src/document-context-registry.ts +177 -0
  449. package/src/document-open-registry.ts +200 -0
  450. package/src/document-preview-source.ts +20 -0
  451. package/src/document-renderer-session.ts +138 -0
  452. package/src/editor-api.ts +46 -0
  453. package/src/editor-chrome-capture.ts +139 -0
  454. package/src/editor-commands.ts +164 -0
  455. package/src/editor-console.ts +563 -0
  456. package/src/editor-current-view.ts +82 -0
  457. package/src/editor-document-probe.ts +881 -0
  458. package/src/editor-git-client.ts +115 -0
  459. package/src/editor-host-door.ts +462 -0
  460. package/src/editor-hotkeys.ts +842 -0
  461. package/src/editor-lease-view.ts +39 -0
  462. package/src/editor-lease.ts +415 -0
  463. package/src/editor-mode.ts +19 -0
  464. package/src/editor-notifications.ts +140 -0
  465. package/src/editor-presence.ts +563 -0
  466. package/src/editor-presentation-activity.ts +50 -0
  467. package/src/editor-presentation-notice.ts +42 -0
  468. package/src/editor-runtime.tsx +145 -0
  469. package/src/editor-server-response.ts +86 -0
  470. package/src/editor-session-attribution.ts +75 -0
  471. package/src/editor-session-mode.ts +54 -0
  472. package/src/editor-shell-store.ts +1304 -0
  473. package/src/editor-state-facets.ts +74 -0
  474. package/src/editor-styles.css +33 -0
  475. package/src/editor-view-presentation.ts +810 -0
  476. package/src/editor-viewport.ts +5302 -0
  477. package/src/entity-lod.ts +31 -0
  478. package/src/entity-object.ts +91 -0
  479. package/src/files/file-provider.ts +62 -0
  480. package/src/files/project-files.ts +264 -0
  481. package/src/finders/index.ts +136 -0
  482. package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
  483. package/src/frame/bridge.tsx +1408 -0
  484. package/src/frame/product.ts +77 -0
  485. package/src/gameplay-dom-recording.ts +319 -0
  486. package/src/gameplay-export-state.ts +14 -0
  487. package/src/gameplay-replay.ts +417 -0
  488. package/src/gameplay-session-time.ts +9 -0
  489. package/src/gameplay-sessions.ts +204 -0
  490. package/src/harness-chat-types.ts +253 -0
  491. package/src/hierarchy-component-marks.ts +298 -0
  492. package/src/hierarchy-drop.ts +91 -0
  493. package/src/hierarchy-expansion-state.ts +80 -0
  494. package/src/hierarchy-header-slot.ts +52 -0
  495. package/src/hierarchy-internals.ts +197 -0
  496. package/src/hierarchy-kind-icon.ts +217 -0
  497. package/src/hierarchy-mark-reader.ts +73 -0
  498. package/src/hierarchy-menu-registry.ts +67 -0
  499. package/src/hierarchy-node-rows.ts +307 -0
  500. package/src/hierarchy-panel-view.ts +280 -0
  501. package/src/hierarchy-projection.ts +76 -0
  502. package/src/hierarchy-row-cache.ts +243 -0
  503. package/src/hierarchy-row-model.ts +308 -0
  504. package/src/hierarchy-rows.ts +11 -0
  505. package/src/hierarchy-walk.ts +86 -0
  506. package/src/history/editor-session.ts +25 -0
  507. package/src/history/history-commands.ts +147 -0
  508. package/src/history/history-delegate.ts +163 -0
  509. package/src/history/history-limit-notices.ts +43 -0
  510. package/src/history/history-service.ts +1173 -0
  511. package/src/history/persistence-coordinator.ts +35 -0
  512. package/src/history/project-file-history.ts +386 -0
  513. package/src/history/project-root-history-backends.ts +139 -0
  514. package/src/history/resource-registry.ts +209 -0
  515. package/src/history/snapshot-store.ts +103 -0
  516. package/src/history/source-history-backend.ts +546 -0
  517. package/src/history/types.ts +124 -0
  518. package/src/hmr-registration-group.ts +67 -0
  519. package/src/hmr-stable-react-context.ts +23 -0
  520. package/src/hotkeys.ts +188 -0
  521. package/src/inference-diagnostics.ts +69 -0
  522. package/src/initial-project.ts +80 -0
  523. package/src/inspection/active-subject.ts +578 -0
  524. package/src/inspection/active-surface.ts +142 -0
  525. package/src/inspection/compose.ts +1064 -0
  526. package/src/inspection/display.ts +170 -0
  527. package/src/inspection/document-subject.ts +109 -0
  528. package/src/inspection/game-subject.ts +85 -0
  529. package/src/inspection/model.ts +542 -0
  530. package/src/inspection/null-subject.ts +115 -0
  531. package/src/inspection/serialize.ts +357 -0
  532. package/src/inspection/use-active-inspection.ts +180 -0
  533. package/src/inspector-presentation.ts +201 -0
  534. package/src/inspector-section-registry.ts +221 -0
  535. package/src/instance-source-actions.ts +163 -0
  536. package/src/instanced-presentation.ts +164 -0
  537. package/src/js-heap.ts +71 -0
  538. package/src/key-actions.ts +91 -0
  539. package/src/keymap-presets.ts +401 -0
  540. package/src/layout-policy.ts +31 -0
  541. package/src/learn-links.ts +73 -0
  542. package/src/light-explorer-model.ts +134 -0
  543. package/src/live-canvas-frame.ts +55 -0
  544. package/src/live-document.ts +279 -0
  545. package/src/live-module-source.ts +230 -0
  546. package/src/live-session-registry.ts +220 -0
  547. package/src/live-transition.ts +633 -0
  548. package/src/manifest-project.ts +107 -0
  549. package/src/model-thumbnail.ts +523 -0
  550. package/src/native-selection-style.ts +202 -0
  551. package/src/object3d-document-write-policy.ts +137 -0
  552. package/src/packaged-runtime.ts +108 -0
  553. package/src/palettes/maya.palette.json +57 -0
  554. package/src/palettes/substance.palette.json +57 -0
  555. package/src/pasteboard-module.ts +81 -0
  556. package/src/performance-profiler.ts +367 -0
  557. package/src/performance-sources.ts +69 -0
  558. package/src/play-boot-phase.ts +145 -0
  559. package/src/presentation-surface.ts +248 -0
  560. package/src/project-adapter.ts +1143 -0
  561. package/src/project-asset-refresh.ts +26 -0
  562. package/src/project-declaration-refresh.ts +31 -0
  563. package/src/project-local-state.ts +118 -0
  564. package/src/project-manager.ts +243 -0
  565. package/src/project-module-changes.ts +163 -0
  566. package/src/project-module-split.ts +266 -0
  567. package/src/project-provenance.ts +115 -0
  568. package/src/project-ready.ts +42 -0
  569. package/src/project-session-reset.ts +67 -0
  570. package/src/project-shape.ts +68 -0
  571. package/src/project-tool-discovery.ts +66 -0
  572. package/src/project-tools.ts +107 -0
  573. package/src/project-work-types.ts +149 -0
  574. package/src/projection/three.ts +898 -0
  575. package/src/projection/types.ts +44 -0
  576. package/src/readiness.ts +113 -0
  577. package/src/reflection-probe-helper.ts +142 -0
  578. package/src/reported-play-state.ts +90 -0
  579. package/src/resolve-relative-specifier.ts +33 -0
  580. package/src/scene-document-plan.ts +315 -0
  581. package/src/scene-framing.ts +315 -0
  582. package/src/scene-live-open.ts +210 -0
  583. package/src/scene-view-fog.ts +89 -0
  584. package/src/scoped-game-css.ts +152 -0
  585. package/src/session-orphan-record.ts +193 -0
  586. package/src/session-tombstone.ts +126 -0
  587. package/src/settings/settings-provider.ts +82 -0
  588. package/src/settings-store.ts +345 -0
  589. package/src/shared-view-restore.ts +42 -0
  590. package/src/shell-store-door.ts +45 -0
  591. package/src/source-conflict.ts +122 -0
  592. package/src/spatial-handle-visuals.ts +332 -0
  593. package/src/stage-context.ts +341 -0
  594. package/src/stage-store-registry.ts +63 -0
  595. package/src/stale-chunk-recovery.ts +34 -0
  596. package/src/state-report-deferral.ts +73 -0
  597. package/src/storage/host-files-storage.ts +97 -0
  598. package/src/storage/http-storage.ts +174 -0
  599. package/src/storage/index.ts +75 -0
  600. package/src/storage/mem-storage.ts +149 -0
  601. package/src/storage/path-lock.ts +44 -0
  602. package/src/storage/paths.ts +26 -0
  603. package/src/storage/types.ts +116 -0
  604. package/src/stories/StoryComponentThumbnail.tsx +184 -0
  605. package/src/stories/StoryPreviewMount.tsx +306 -0
  606. package/src/stories/component-content-source.tsx +106 -0
  607. package/src/stories/component-states-source.ts +78 -0
  608. package/src/stories/compose-project-stories.ts +255 -0
  609. package/src/stories/pixi-story-model.ts +30 -0
  610. package/src/stories/prefabs-finder.ts +54 -0
  611. package/src/stories/prefabs-from-stories.ts +182 -0
  612. package/src/stories/project-story-discovery.ts +78 -0
  613. package/src/stories/project-story-regions.ts +24 -0
  614. package/src/stories/story-actions.ts +54 -0
  615. package/src/stories/story-capture-command.ts +124 -0
  616. package/src/stories/story-capture.ts +584 -0
  617. package/src/stories/story-declared-medium.ts +126 -0
  618. package/src/stories/story-discovery.ts +176 -0
  619. package/src/stories/story-document-openers.ts +36 -0
  620. package/src/stories/story-dom-runtime.ts +78 -0
  621. package/src/stories/story-grouping.ts +111 -0
  622. package/src/stories/story-lane.ts +88 -0
  623. package/src/stories/story-mount-turn.ts +27 -0
  624. package/src/stories/story-opener.ts +260 -0
  625. package/src/stories/story-pixi-preview.ts +408 -0
  626. package/src/stories/story-presentation.ts +215 -0
  627. package/src/stories/story-registry.ts +517 -0
  628. package/src/stories/story-three-preview.ts +807 -0
  629. package/src/stories/three-story-model.ts +96 -0
  630. package/src/story-three-preview-runtime.ts +56 -0
  631. package/src/surface-keyboard.ts +112 -0
  632. package/src/surface-state.ts +124 -0
  633. package/src/tab-bootstrap.js +628 -0
  634. package/src/tab-census.ts +198 -0
  635. package/src/tab-lifecycle-client.ts +196 -0
  636. package/src/theme-library.ts +844 -0
  637. package/src/theme-preference.ts +378 -0
  638. package/src/theme.css +3437 -0
  639. package/src/three-viewport/bone-selection-highlight.ts +119 -0
  640. package/src/three-viewport/camera-fit.ts +41 -0
  641. package/src/three-viewport/interactive-renderer.ts +132 -0
  642. package/src/three-viewport/selection-brackets.ts +310 -0
  643. package/src/three-viewport/selection-outline.ts +183 -0
  644. package/src/three-viewport/skeleton-helper.ts +61 -0
  645. package/src/three-viewport/source-color.ts +167 -0
  646. package/src/three-viewport/studio-environment.ts +96 -0
  647. package/src/three-viewport-presentation.ts +23 -0
  648. package/src/tool-contribution-play.ts +74 -0
  649. package/src/tool-loader.ts +1798 -0
  650. package/src/transform-mode-request.ts +57 -0
  651. package/src/transient-hint.ts +78 -0
  652. package/src/trigger-volume-helper.ts +116 -0
  653. package/src/ui-source/adapter-region-includes.ts +241 -0
  654. package/src/ui-source/ensure-import.ts +132 -0
  655. package/src/ui-source/file-region-resolver.ts +302 -0
  656. package/src/ui-source/inspect.ts +775 -0
  657. package/src/ui-source/oid-transform.ts +1845 -0
  658. package/src/ui-source/plan-csf-story.ts +196 -0
  659. package/src/ui-source/plan-extract-component.ts +421 -0
  660. package/src/ui-source/plan-fork-component.ts +621 -0
  661. package/src/ui-source/plan-named-style.ts +95 -0
  662. package/src/ui-source/plan-source-edit.ts +353 -0
  663. package/src/ui-source/r3f-contract-resolver.ts +327 -0
  664. package/src/ui-source/r3f-diagnostic-index.ts +165 -0
  665. package/src/ui-source/r3f-environment-binding.ts +133 -0
  666. package/src/ui-source/r3f-joint-binding.ts +251 -0
  667. package/src/ui-source/r3f-lod-binding.ts +91 -0
  668. package/src/ui-source/r3f-particle-binding.ts +235 -0
  669. package/src/ui-source/r3f-physics-binding.ts +483 -0
  670. package/src/ui-source/r3f-project-contracts.ts +444 -0
  671. package/src/ui-source/relative-import-specifier.ts +34 -0
  672. package/src/ui-source/reparent-guard.ts +544 -0
  673. package/src/ui-source/source-edit-request.ts +97 -0
  674. package/src/ui-source/source-write-backend.ts +618 -0
  675. package/src/ui-source/syntactic-prop-specs.ts +296 -0
  676. package/src/ui-source/tier-source-write-backend.ts +279 -0
  677. package/src/ui-source/ts-ast.ts +171 -0
  678. package/src/ui-source/utility-class-support.ts +169 -0
  679. package/src/ui-source/write-component-default.ts +133 -0
  680. package/src/ui-source/writer.ts +1989 -0
  681. package/src/viewport-activation-timings.ts +840 -0
  682. package/src/viewport-authoring-policy.ts +186 -0
  683. package/src/viewport-controls-hint.ts +57 -0
  684. package/src/viewport-door.ts +237 -0
  685. package/src/viewport-shading-boundary.ts +12 -0
  686. package/src/vite-error-surface.ts +141 -0
  687. package/src/wait-until.ts +37 -0
  688. package/src/workspace-areas.ts +156 -0
  689. package/src/workspace-aux-commands.ts +11 -0
  690. package/src/workspace-available-documents.ts +127 -0
  691. package/src/workspace-core-utilities.ts +31 -0
  692. package/src/workspace-document-ids.ts +59 -0
  693. package/src/workspace-document-registry.ts +612 -0
  694. package/src/workspace-document-restore.ts +145 -0
  695. package/src/workspace-host-commands.ts +141 -0
  696. package/src/workspace-persistence-gate.ts +40 -0
  697. package/src/workspace-play-utilities.ts +44 -0
  698. package/src/workspace-presets.ts +425 -0
  699. package/src/workspace-regions.ts +294 -0
  700. package/src/workspace-state-persistence.ts +536 -0
  701. package/src/workspace-static-panels.ts +73 -0
  702. package/src/workspace-status-registry.ts +121 -0
  703. package/src/workspace-style.ts +239 -0
  704. package/src/workspace-utility-commands.ts +74 -0
  705. package/src/workspace-utility-registry.ts +263 -0
  706. package/src/workspace-viewport-rect.ts +97 -0
  707. package/src/world-adoption.ts +115 -0
  708. package/src/world-document-routing.ts +104 -0
  709. package/vite-plugin-creation-site-write.ts +184 -0
  710. package/vite-plugin-creation-site.ts +80 -0
  711. package/vite-plugin-game-static.ts +303 -0
  712. package/vite-plugin-module-doorways.ts +336 -0
  713. package/vite-plugin-product-contributions.ts +197 -0
  714. package/vite-plugin-project-game-static.ts +125 -0
  715. package/vite-plugin-project-jsx-js.ts +65 -0
  716. package/vite-plugin-project-root-absolute-assets.ts +359 -0
  717. package/vite-plugin-shared-react.ts +420 -0
  718. package/vite-plugin-shared-three.ts +203 -0
  719. package/vite-plugin-ui-oid.ts +2106 -0
@@ -0,0 +1,563 @@
1
+ /**
2
+ * THE EDITOR CONSOLE - and the one thing to know before wiring it into a host.
3
+ *
4
+ * THE BOTTOM BAR'S ERROR COUNT AND THE SET `vgai console` PRINTS ARE ONE SET.
5
+ * The status bar, the Console panel and the Console utility's badge all read
6
+ * this store; `vgai console` reads the SERVER's ledger; and `console-sync.ts`
7
+ * is the only thing that makes them the same set, by forwarding every error and
8
+ * warning captured here to that ledger. An error the bottom bar counts MUST be
9
+ * an error `vgai console` prints and exits non-zero on - that equality IS the
10
+ * loudness convention, not an implementation detail of it.
11
+ *
12
+ * So `installEditorConsoleCapture()` is HALF of an act and never a whole one. A
13
+ * host boots the editor through `console-sync.ts`'s
14
+ * `installEditorConsoleReporting()`, which does both and cannot be half-called.
15
+ * Calling the capture alone (measured 2026-09-19, on a boot path that did)
16
+ * gives a page whose red errors are visible only to somebody
17
+ * LOOKING at the editor and a CLI that calls the session clean. This function
18
+ * stays exported for tests and for `console-sync.ts` itself; it is not a boot
19
+ * step.
20
+ */
21
+ import { captureOwnerStack } from 'react';
22
+ import { isCancellationReason } from './cancellation-reason';
23
+
24
+ export type ConsoleLevel = 'info' | 'warn' | 'error';
25
+
26
+ export interface ConsoleEntry {
27
+ id: number;
28
+ timestamp: number;
29
+ level: ConsoleLevel;
30
+ message: string;
31
+ source?: string;
32
+ subsystem?: string;
33
+ metadata?: Record<string, unknown>;
34
+ count: number;
35
+ }
36
+
37
+ const MAX_ENTRIES = 1000;
38
+
39
+ class EditorConsole {
40
+ private _entries: ConsoleEntry[] = [];
41
+ private _listeners = new Set<() => void>();
42
+ private _nextId = 0;
43
+ private _version = 0;
44
+ private _notifyScheduled = false;
45
+ private _sink: ((entry: ConsoleEntry) => void) | null = null;
46
+
47
+ /** Register (or clear) a callback invoked for every console entry. */
48
+ setSink(fn: ((entry: ConsoleEntry) => void) | null): void {
49
+ this._sink = fn;
50
+ }
51
+
52
+ counts = { info: 0, warn: 0, error: 0 };
53
+
54
+ log(message: string, source?: string): void {
55
+ this._push('info', message, source);
56
+ }
57
+
58
+ warn(message: string, source?: string): void {
59
+ this._push('warn', message, source);
60
+ }
61
+
62
+ error(message: string, source?: string): void {
63
+ this._push('error', message, source);
64
+ }
65
+
66
+ /** Log with structured metadata (used by the engine logger). */
67
+ logStructured(
68
+ level: ConsoleLevel,
69
+ message: string,
70
+ source: string,
71
+ subsystem?: string,
72
+ metadata?: Record<string, unknown>,
73
+ ): void {
74
+ this._push(level, message, source, subsystem, metadata);
75
+ }
76
+
77
+ clear(): void {
78
+ this._entries = [];
79
+ this.counts = { info: 0, warn: 0, error: 0 };
80
+ this._notify();
81
+ }
82
+
83
+ getEntries(): readonly ConsoleEntry[] {
84
+ return this._entries;
85
+ }
86
+
87
+ // useSyncExternalStore compatible
88
+ subscribe = (cb: () => void): (() => void) => {
89
+ this._listeners.add(cb);
90
+ return () => this._listeners.delete(cb);
91
+ };
92
+
93
+ getSnapshot = (): number => this._version;
94
+
95
+ private _push(
96
+ level: ConsoleLevel,
97
+ message: string,
98
+ source?: string,
99
+ subsystem?: string,
100
+ metadata?: Record<string, unknown>,
101
+ ): void {
102
+ // Collapse identical consecutive messages
103
+ const last = this._entries[this._entries.length - 1];
104
+ if (
105
+ last &&
106
+ last.level === level &&
107
+ last.message === message &&
108
+ last.source === source &&
109
+ last.metadata?.['instanceId'] === metadata?.['instanceId']
110
+ ) {
111
+ last.count++;
112
+ last.timestamp = Date.now();
113
+ this._sink?.(last);
114
+ this._notify();
115
+ return;
116
+ }
117
+
118
+ const entry: ConsoleEntry = {
119
+ id: this._nextId++,
120
+ timestamp: Date.now(),
121
+ level,
122
+ message,
123
+ count: 1,
124
+ };
125
+ if (source) entry.source = source;
126
+ if (subsystem) entry.subsystem = subsystem;
127
+ if (metadata) entry.metadata = metadata;
128
+ this._entries.push(entry);
129
+ this.counts[level]++;
130
+ this._sink?.(entry);
131
+
132
+ // Cap at MAX_ENTRIES, drop oldest
133
+ if (this._entries.length > MAX_ENTRIES) {
134
+ const removed = this._entries.shift()!;
135
+ this.counts[removed.level] = Math.max(0, this.counts[removed.level] - 1);
136
+ }
137
+
138
+ this._notify();
139
+ }
140
+
141
+ /**
142
+ * Bump the snapshot NOW; wake subscribers on a microtask.
143
+ *
144
+ * Every subscriber of this store is a React `useSyncExternalStore`
145
+ * (`ConsolePanel`, `HarnessConversationTray`, `HarnessChatPanel`, the status
146
+ * bar's error count, the Console utility's badge), and this store's writers
147
+ * are unbounded: `installEditorConsoleCapture` routes the session's WHOLE
148
+ * `console.error`/`console.warn` into it — including React's own DEV
149
+ * warnings, which React logs FROM INSIDE THE RENDER PHASE. A synchronous
150
+ * fan-out therefore schedules a subscriber's setState while some other
151
+ * component is rendering, which React reports as
152
+ * `Cannot update a component (HarnessConversationTray) while rendering a
153
+ * different component` — measured on the owner's session
154
+ * 2026-08-16, where a single dev warning logged during the workspace host's
155
+ * render produced that error in the editor's own console at boot.
156
+ *
157
+ * A microtask cannot run inside a render pass (React restores its execution
158
+ * context before the stack unwinds), so deferring the wake-up is what makes
159
+ * the write legal from anywhere. `_version` is bumped synchronously, so
160
+ * `getSnapshot()` is never stale for a render already in flight; only the
161
+ * notification waits. Coalescing is the bonus: a burst of game logs now
162
+ * costs one re-render instead of one per line.
163
+ *
164
+ * Do not "simplify" this back to a synchronous loop.
165
+ */
166
+ private _notify(): void {
167
+ this._version++;
168
+ if (this._notifyScheduled) return;
169
+ this._notifyScheduled = true;
170
+ queueMicrotask(() => {
171
+ this._notifyScheduled = false;
172
+ for (const fn of this._listeners) fn();
173
+ });
174
+ }
175
+ }
176
+
177
+ export const editorConsole = new EditorConsole();
178
+
179
+ // Test-only hook (e2e) — the window mirror A4(f) anticipates: direct read access to console entries without DOM-scraping
180
+ // `ConsolePanel` (which has no per-entry testids). Same ad-hoc `window.__vgai*`
181
+ // convention as every other dev-only hook in `test-window.ts`.
182
+ //
183
+ // Guarded on `window`: this module is now imported by `three-authoring-adapter.ts`
184
+ // (to report a failed history journal loudly), which is exercised by node-env
185
+ // vitest suites where `window` does not exist. A bare module-scope reference
186
+ // throws `ReferenceError: window is not defined` at COLLECTION time — before any
187
+ // test body runs — so the guard belongs here at the source rather than as a
188
+ // `vi.mock` repeated in every importing test file.
189
+ if (typeof window !== 'undefined') {
190
+ (window as unknown as { __vgaiEditorConsole?: EditorConsole })['__vgaiEditorConsole'] =
191
+ editorConsole;
192
+ }
193
+
194
+ // --- Console argument formatting ---
195
+
196
+ /** Ceiling on one `%o`/`%O`/`%j` rendering. Game code logs whole scene graphs;
197
+ * a JSON dump of one is megabytes, and this store keeps up to `MAX_ENTRIES` of
198
+ * them for the session's life. */
199
+ const INSPECT_CAP = 1000;
200
+ const ERROR_ATTRIBUTION_CAP = 4000;
201
+
202
+ /** `String(value)`, but a value whose `toString` throws (a null-prototype
203
+ * object, a revoked proxy) must not take the console down with it. */
204
+ function safeString(value: unknown): string {
205
+ try {
206
+ return String(value);
207
+ } catch {
208
+ return Object.prototype.toString.call(value);
209
+ }
210
+ }
211
+
212
+ /** Object rendering for the directives that ask for one (`%o`, `%O`, `%j`).
213
+ * Circular-safe and bounded — see `INSPECT_CAP`. */
214
+ function inspectArg(value: unknown): string {
215
+ if (typeof value !== 'object' || value === null) return safeString(value);
216
+ const seen = new WeakSet<object>();
217
+ let json: string | undefined;
218
+ try {
219
+ json = JSON.stringify(value, (_key, val) => {
220
+ if (typeof val !== 'object' || val === null) return val;
221
+ if (seen.has(val)) return '[Circular]';
222
+ seen.add(val);
223
+ return val;
224
+ });
225
+ } catch {
226
+ json = undefined;
227
+ }
228
+ if (json === undefined) return safeString(value);
229
+ return json.length > INSPECT_CAP ? `${json.slice(0, INSPECT_CAP)}…` : json;
230
+ }
231
+
232
+ /**
233
+ * Render `console.error(...)`-style arguments the way the console itself does:
234
+ * interpolate the format directives in a leading format string against the
235
+ * following arguments, then append whatever arguments are left over,
236
+ * space-separated.
237
+ *
238
+ * Why this exists rather than `args.map(String).join(' ')`: React logs with
239
+ * printf-style format strings, so the naive join stored
240
+ * "React does not recognize the `%s` prop on a DOM element…" with `%s`
241
+ * UNINTERPOLATED and the prop name riding in a later argument — which the
242
+ * summary's per-message truncation (`command-listener.ts`) then cut off
243
+ * entirely. `vgai status` is the one channel agents are told to trust, and it
244
+ * was delivering evidence with the identifying detail amputated.
245
+ *
246
+ * Behaviour follows the WHATWG console Formatter: directives are consumed
247
+ * left-to-right; a directive with no argument left is emitted literally; `%%`
248
+ * is an escaped percent and consumes nothing; `%c` consumes its argument and
249
+ * renders nothing (this store has no styling). A first argument that is not a
250
+ * string means no format string, so every argument is simply stringified.
251
+ */
252
+ export function formatConsoleArgs(args: readonly unknown[]): string {
253
+ if (args.length === 0) return '';
254
+ const [first, ...rest] = args;
255
+ if (typeof first !== 'string' || rest.length === 0) {
256
+ return args.map(safeString).join(' ');
257
+ }
258
+
259
+ let consumed = 0;
260
+ const head = first.replace(/%([sdifoOjc%])/g, (match, kind: string) => {
261
+ if (kind === '%') return '%';
262
+ if (consumed >= rest.length) return match;
263
+ const arg = rest[consumed++];
264
+ switch (kind) {
265
+ case 's':
266
+ return typeof arg === 'string' ? arg : safeString(arg);
267
+ case 'd':
268
+ case 'i': {
269
+ if (typeof arg === 'symbol') return 'NaN';
270
+ if (typeof arg === 'bigint') return String(arg);
271
+ const n = Number(arg);
272
+ return Number.isFinite(n) ? String(Math.trunc(n)) : String(n);
273
+ }
274
+ case 'f': {
275
+ if (typeof arg === 'symbol') return 'NaN';
276
+ return String(Number(arg));
277
+ }
278
+ case 'c':
279
+ return '';
280
+ default:
281
+ return inspectArg(arg);
282
+ }
283
+ });
284
+
285
+ const leftovers = rest.slice(consumed);
286
+ return leftovers.length === 0 ? head : `${head} ${leftovers.map(safeString).join(' ')}`;
287
+ }
288
+
289
+ /**
290
+ * React 19 prints a DEV warning's component tree through the browser's own
291
+ * console task stack, never as an argument — so a duplicate-key or
292
+ * setState-in-effect warning reached `vgai console` as one sentence with no
293
+ * hint of WHICH list. `captureOwnerStack()` is React's door to that tree and
294
+ * is only populated while React itself is calling `console.error`, which is
295
+ * exactly when this wrapper runs. Appended for React's warning shapes only;
296
+ * everything else keeps its exact message.
297
+ */
298
+ function withReactOwnerStack(args: readonly unknown[], message: string): string {
299
+ const first = args[0];
300
+ if (typeof first !== 'string') return message;
301
+ if (
302
+ !/^(Encountered two children with the same key|Each child in a list should have a unique|Maximum update depth exceeded|Cannot update a component)/.test(
303
+ first,
304
+ )
305
+ ) {
306
+ return message;
307
+ }
308
+ try {
309
+ const stack = captureOwnerStack?.();
310
+ return stack ? `${message}\nOwner stack:${stack}` : message;
311
+ } catch {
312
+ return message;
313
+ }
314
+ }
315
+
316
+ /** Preserve the component and source evidence a render error already owns. */
317
+ export function formatAttributedError(
318
+ error: unknown,
319
+ options: { readonly source?: string; readonly componentStack?: string | null } = {},
320
+ ): string {
321
+ const message = error instanceof Error ? `${error.name}: ${error.message}` : safeString(error);
322
+ const parts = [options.source ? `[${options.source}] ${message}` : message];
323
+ const componentStack = options.componentStack?.trim();
324
+ if (componentStack) parts.push(`Component stack:\n${componentStack}`);
325
+ if (error instanceof Error && error.stack && error.stack !== message) {
326
+ parts.push(`JavaScript stack:\n${error.stack}`);
327
+ }
328
+ const formatted = parts.join('\n');
329
+ return formatted.length > ERROR_ATTRIBUTION_CAP
330
+ ? `${formatted.slice(0, ERROR_ATTRIBUTION_CAP)}…`
331
+ : formatted;
332
+ }
333
+
334
+ // --- Session-lifetime console capture ---
335
+
336
+ /**
337
+ * THE LAYERING (read this together with `play-mode.ts`'s
338
+ * `patchConsole()`/`unpatchConsole()` — the two patches are one design):
339
+ *
340
+ * 1. `installEditorConsoleCapture()` runs ONCE at editor boot (`main.tsx`) and
341
+ * wraps `console.error`/`console.warn` for the WHOLE session, tagging what
342
+ * it captures `'editor'`. Before it existed, play-mode's patch was the ONLY
343
+ * funnel from a raw `console.error` into this store — and it is installed at
344
+ * play START and removed at play STOP. So an editor-frame error outside play
345
+ * (measured: Content-tab story previews throwing `useRapier must be used
346
+ * within <Physics>`) reached this store never, and `vgai status` answered
347
+ * `consoleErrors: {count: 0}` to a console full of red.
348
+ * 2. Play-mode's patch is installed LATER, so it sits OUTSIDE this one: it
349
+ * captures whatever `console.error` currently is (this wrapper) as its
350
+ * "original" and calls through to it. While a run is live play's patch OWNS
351
+ * the funnel — it tags `'game'`, which is the more specific and more useful
352
+ * answer — so this wrapper suspends its own store push for the duration and
353
+ * only forwards to the native console. One error, ONE entry, source
354
+ * `'game'`. `unpatchConsole()` resumes it, and session-lifetime capture
355
+ * picks straight back up.
356
+ *
357
+ * Uncaught page errors (`window.onerror`/`unhandledrejection`) are the other
358
+ * half of the same job and are captured here too, tagged `'runtime'` — the
359
+ * source `command-listener.ts`'s `collectPageErrors` reads. They live at boot
360
+ * rather than on the viewport panel so an error thrown BEFORE the viewport
361
+ * mounts is still recorded, and so there is exactly one owner of the listeners
362
+ * for the session's whole life.
363
+ */
364
+ /**
365
+ * WHO IS SPEAKING, when a raw `console.error`/`warn` fires — asked, never
366
+ * named.
367
+ *
368
+ * The console is a SINK the shell feeds; the closure ratchet's own rule is
369
+ * that a surface below the shell never imports the shell's world adapters
370
+ * (`scripts/validate-editor-closure.mjs`'s header). It was importing one:
371
+ * `currentGameRealmMountId` from `gated-globals.ts` pulled the whole game
372
+ * REALM SHIM — the page-in-a-box, its storage facade, its navigation guard and
373
+ * its loop gate — into this surface's pinned closure, so 7 of the console's 8
374
+ * files were the game realm and a Blender-only build's console carried a
375
+ * game's page shim (measured 2026-09-18, phase 1 of the open-source launch).
376
+ *
377
+ * The realm is the thing that knows a realm is running, so the realm
378
+ * REGISTERS its reader here (`gated-globals.ts`, at module scope: any realm
379
+ * existing implies that module loaded, so the registration cannot be late for
380
+ * a message the realm itself produced). One named slot rather than a list,
381
+ * because there is exactly one realm shim and a second claimant would be a
382
+ * design decision, not a registration.
383
+ */
384
+ let _realmAttribution: (() => string | null) | null = null;
385
+
386
+ /** Publish the "which realm is synchronously executing?" reader. */
387
+ export function setConsoleRealmAttribution(read: () => string | null): void {
388
+ _realmAttribution = read;
389
+ }
390
+
391
+ let _nativeConsoleError: typeof console.error | null = null;
392
+ let _nativeConsoleWarn: typeof console.warn | null = null;
393
+ let _captureSuspensions = 0;
394
+
395
+ /** Play-mode's patch takes precedence while a run is live — see the layering
396
+ * note above. Paired with `resumeEditorConsoleCapture`; counted rather than
397
+ * boolean so a nested/retried patch cannot leave capture off forever. */
398
+ export function suspendEditorConsoleCapture(): void {
399
+ _captureSuspensions++;
400
+ }
401
+
402
+ export function resumeEditorConsoleCapture(): void {
403
+ if (_captureSuspensions > 0) _captureSuspensions--;
404
+ }
405
+
406
+ /** Test-only: whether the session-lifetime capture is currently pushing to the
407
+ * store. Exists so the layering above is assertable without reaching into
408
+ * module privates. */
409
+ export function isEditorConsoleCaptureActive(): boolean {
410
+ return _nativeConsoleError !== null && _captureSuspensions === 0;
411
+ }
412
+
413
+ /**
414
+ * Install the session-lifetime capture. Idempotent; returns a teardown that
415
+ * restores the native console and removes the page-error listeners.
416
+ */
417
+ export function installEditorConsoleCapture(): () => void {
418
+ if (_nativeConsoleError) return () => {};
419
+ const nativeError = console.error;
420
+ const nativeWarn = console.warn;
421
+ _nativeConsoleError = nativeError;
422
+ _nativeConsoleWarn = nativeWarn;
423
+
424
+ /**
425
+ * A raw console call is the GAME's statement when game-realm code is
426
+ * synchronously executing. The registered realm attribution above is the
427
+ * door built for exactly this label (`gated-globals.ts`'s
428
+ * `currentGameRealmMountId` — the realm's contextual console runs every
429
+ * method `inRealm`), and play-mode's patch already reads it — but
430
+ * a game's module-scope warns fire at graph EVALUATION (racing's Supabase
431
+ * client is the measured case), which happens at mount, before any play run
432
+ * installs that patch. Without this read, every such row landed in the
433
+ * ledger as editor-owned noise, telling an agent to fix editor code for a
434
+ * warning the game's own library printed. The label changes; the loudness
435
+ * does not — a game-sourced warning still gates `vgai` exit-0 exactly like
436
+ * an editor one (severity decides, never source), because exempting a
437
+ * source would teach the gate to find less.
438
+ */
439
+ const captured = (level: 'error' | 'warn', args: unknown[]): void => {
440
+ if (_captureSuspensions !== 0) return;
441
+ const realmMountId = _realmAttribution?.() ?? null;
442
+ if (realmMountId !== null) {
443
+ // `''` is the DEFAULT game realm (every ingest mount) — still the game's
444
+ // statement, just not a named multi-instance mount.
445
+ editorConsole.logStructured(
446
+ level,
447
+ formatConsoleArgs(args),
448
+ 'game',
449
+ undefined,
450
+ realmMountId ? { instanceId: realmMountId } : undefined,
451
+ );
452
+ return;
453
+ }
454
+ editorConsole.logStructured(
455
+ level,
456
+ withReactOwnerStack(args, formatConsoleArgs(args)),
457
+ 'editor',
458
+ );
459
+ };
460
+
461
+ console.error = (...args: unknown[]) => {
462
+ nativeError.apply(console, args);
463
+ captured('error', args);
464
+ };
465
+ console.warn = (...args: unknown[]) => {
466
+ nativeWarn.apply(console, args);
467
+ captured('warn', args);
468
+ };
469
+
470
+ const onError = (e: ErrorEvent) => {
471
+ const source = e.filename
472
+ ? `${e.filename}${e.lineno ? `:${e.lineno}${e.colno ? `:${e.colno}` : ''}` : ''}`
473
+ : undefined;
474
+ editorConsole.error(
475
+ formatAttributedError(e.error ?? e.message, source ? { source } : undefined),
476
+ 'runtime',
477
+ );
478
+ };
479
+ const onUnhandledRejection = (e: PromiseRejectionEvent) => {
480
+ // A CANCELLATION IS NOT AN ERROR, and this is the one exception the
481
+ // severity-decides-never-source doctrine above admits — because it is not
482
+ // about source. `cancellation-reason.ts` carries the whole reasoning and
483
+ // the measurement (the Code-OSS frame's `Canceled: Canceled`); the short
484
+ // version is that an operation which was asked to stop and did is what
485
+ // `AbortError` and `CancellationError` MEAN, for our code and anyone
486
+ // else's, and a page-level listener cannot ask whose it was.
487
+ if (isCancellationReason(e.reason)) return;
488
+ editorConsole.error(
489
+ `Unhandled promise rejection: ${formatAttributedError(e.reason)}`,
490
+ 'runtime',
491
+ );
492
+ };
493
+ const hasWindow = typeof window !== 'undefined';
494
+ if (hasWindow) {
495
+ window.addEventListener('error', onError);
496
+ window.addEventListener('unhandledrejection', onUnhandledRejection);
497
+ }
498
+
499
+ return () => {
500
+ if (_nativeConsoleError) console.error = _nativeConsoleError;
501
+ if (_nativeConsoleWarn) console.warn = _nativeConsoleWarn;
502
+ _nativeConsoleError = null;
503
+ _nativeConsoleWarn = null;
504
+ _captureSuspensions = 0;
505
+ if (hasWindow) {
506
+ window.removeEventListener('error', onError);
507
+ window.removeEventListener('unhandledrejection', onUnhandledRejection);
508
+ }
509
+ };
510
+ }
511
+
512
+ /**
513
+ * Listen for `console-bridge` postMessage events from a game's own console
514
+ * bridge and pipe them into the editor console.
515
+ */
516
+ const BRIDGE_LEVEL_MAP: Record<string, ConsoleLevel> = {
517
+ log: 'info',
518
+ warn: 'warn',
519
+ error: 'error',
520
+ };
521
+
522
+ /** LogLevel string → ConsoleLevel for engine-log messages. */
523
+ const ENGINE_LEVEL_MAP: Record<string, ConsoleLevel> = {
524
+ trace: 'info',
525
+ debug: 'info',
526
+ info: 'info',
527
+ warn: 'warn',
528
+ error: 'error',
529
+ fatal: 'error',
530
+ };
531
+
532
+ // Same `window` guard as the test hook above — see the comment there.
533
+ if (typeof window !== 'undefined') {
534
+ window.addEventListener('message', (e: MessageEvent) => {
535
+ // Structured engine-log messages (from engine logger)
536
+ if (e.data?.type === 'engine-log') {
537
+ const level = ENGINE_LEVEL_MAP[e.data.level];
538
+ if (!level) return;
539
+ editorConsole.logStructured(
540
+ level,
541
+ e.data.message,
542
+ 'engine',
543
+ e.data.subsystem,
544
+ e.data.metadata,
545
+ );
546
+ return;
547
+ }
548
+
549
+ // Plain console-bridge messages (from game code)
550
+ if (e.data?.type === 'console-bridge') {
551
+ const level = BRIDGE_LEVEL_MAP[e.data.level];
552
+ if (!level) return;
553
+ editorConsole[level === 'info' ? 'log' : level](e.data.message, 'engine');
554
+ }
555
+ });
556
+ }
557
+
558
+ /** Render one `server-log` payload — live or replayed — into the console. */
559
+ export function emitServerLogEntry(entry: { level: string; message: string }): void {
560
+ const level = BRIDGE_LEVEL_MAP[entry.level];
561
+ if (!level) return;
562
+ editorConsole[level === 'info' ? 'log' : level](entry.message, 'server');
563
+ }
@@ -0,0 +1,82 @@
1
+ import { type EditorView, editorViewUrl, isEditorViewUtility } from '@volter/editor-sdk';
2
+ import { object3DDocumentSession } from './authoring/object3d-document-session-registry';
3
+ import type { EditorShellStore } from './editor-shell-store';
4
+ import { activeEditorKeymap } from './keymap-presets';
5
+ import {
6
+ activeWorkspaceDocument,
7
+ activeWorkspaceDocumentSelection,
8
+ } from './workspace-document-registry';
9
+ import { activeWorkspaceStaticPanel, activeWorkspaceUtility } from './workspace-host-commands';
10
+ import { activeEditorWorkspace } from './workspace-presets';
11
+ import { activeWorkspaceStyleId } from './workspace-style';
12
+
13
+ function cameraState(
14
+ position: readonly [number, number, number] | { x: number; y: number; z: number },
15
+ target: readonly [number, number, number] | { x: number; y: number; z: number },
16
+ fov?: number,
17
+ ) {
18
+ const vector = (value: typeof position) =>
19
+ 'x' in value
20
+ ? { x: value.x, y: value.y, z: value.z }
21
+ : { x: value[0]!, y: value[1]!, z: value[2]! };
22
+ return { position: vector(position), target: vector(target), ...(fov ? { fov } : {}) };
23
+ }
24
+
25
+ /** Inverse of `revealUtility` (editor-view-presentation.ts): map the live
26
+ * utility id back into `@volter/editor-sdk`'s public link vocabulary — one of
27
+ * the editor's own named instruments, or a `tool:` tab a package or the open
28
+ * project contributes. A live utility the vocabulary cannot name (the story
29
+ * addons) reads as no utility rather than as a fabricated one. */
30
+ function presentedUtility(): EditorView['utility'] {
31
+ const utility = activeWorkspaceUtility();
32
+ return utility && isEditorViewUtility(utility) ? utility : undefined;
33
+ }
34
+
35
+ /** Derive the projection from live document/session state. This is the
36
+ * inverse of presentEditorView, not a cache of the last agent request. */
37
+ export function currentEditorView(store: EditorShellStore): EditorView {
38
+ const active = activeWorkspaceDocument();
39
+ const document = active?.descriptor.presentation?.() ?? undefined;
40
+ const session = active ? object3DDocumentSession(active.descriptor.id) : null;
41
+ const documentSelection = activeWorkspaceDocumentSelection();
42
+ const selected = session
43
+ ? session.selection()
44
+ : (documentSelection?.adapter?.selection?.get() ??
45
+ (active?.descriptor.id === 'workspace:scene' ? [...store.selectedEntityIds] : []));
46
+ let viewport: EditorView['viewport'];
47
+ if (session) {
48
+ const pose = session.cameraPose();
49
+ const presentation = session.presentation();
50
+ viewport = {
51
+ camera: cameraState(pose.position, pose.target, pose.fov),
52
+ diagnostic: presentation.skeleton ? 'skeleton' : presentation.mode,
53
+ grid: presentation.grid,
54
+ };
55
+ } else if (active?.descriptor.id === 'workspace:scene' && store.cameraPose) {
56
+ const pose = store.cameraPose;
57
+ viewport = {
58
+ camera: cameraState(pose.position, pose.target, pose.fov),
59
+ diagnostic: store.shadingMode,
60
+ grid: store.showGrid,
61
+ };
62
+ }
63
+ const utility = presentedUtility();
64
+ // The static panel holding the dock's focus, straight from the dock's own
65
+ // active-panel readout — the inverse of `revealStaticPanel`.
66
+ const panel = activeWorkspaceStaticPanel();
67
+ return {
68
+ version: 1,
69
+ workspace: activeEditorWorkspace(),
70
+ ...(activeWorkspaceStyleId() === null ? {} : { style: activeWorkspaceStyleId() as string }),
71
+ keymap: activeEditorKeymap(),
72
+ ...(document ? { document } : {}),
73
+ ...(selected.length > 0 ? { selection: { ids: [...selected] } } : {}),
74
+ ...(viewport ? { viewport } : {}),
75
+ ...(panel ? { panel } : {}),
76
+ ...(utility ? { utility } : {}),
77
+ };
78
+ }
79
+
80
+ export function currentEditorViewUrl(store: EditorShellStore): string {
81
+ return editorViewUrl(currentEditorView(store), window.location.href);
82
+ }