@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,186 @@
1
+ /**
2
+ * WHAT THE GIZMO VIEWPORT ASKS THE SHELL — the one collaborator
3
+ * `editor-viewport.ts` declares and the shell installs at boot.
4
+ *
5
+ * ARCHITECTURE-CORE §Editor chrome, "The viewport stack is separable": a
6
+ * surface below the shell never imports the shell's transport, a world
7
+ * authoring adapter, or project discovery. The viewport was importing six
8
+ * `authoring/` modules to ask four questions —
9
+ *
10
+ * · which adapter am I driving, and which one do the shared panels drive?
11
+ * · what is under the pointer?
12
+ * · which native root owns the current selection, and is it painted here?
13
+ * · which three root is world-hidden, and how do I apply that?
14
+ *
15
+ * — and every one of those answers is a COMPOSITE fact. `layered-pick.ts`
16
+ * walks `CompositeAuthoringAdapter.childAdapters()` in manifest z-order;
17
+ * `panel-authoring.ts` reaches the workspace-document registry;
18
+ * `world-hidden-viewport.ts` and `viewport-tool-context.ts` resolve the
19
+ * composite's live three child. The viewport itself knows about none of that:
20
+ * it raycasts a scene and drags a gizmo. Measured, those six edges were 96 of
21
+ * its 193 files.
22
+ *
23
+ * ## The default is the NO-SHELL answer, and it is deliberate
24
+ *
25
+ * {@link DEFAULT_VIEWPORT_AUTHORING_POLICY} is what a viewport mounted with no
26
+ * shell above it (a bounded host; a fixture) gets: no composite exists,
27
+ * so there are no layers to walk, no other panel to agree with, no world-group
28
+ * eye to honour. Each default states that outright rather than half-answering.
29
+ * The ONE default that is real logic is {@link adapterOnlyToolOwner} — the
30
+ * structural single-adapter fallback `resolveViewportToolContext` already used
31
+ * for non-composite adapters, which lives here now and is imported BACK by
32
+ * `authoring/viewport-tool-context.ts` so there is one copy of it.
33
+ *
34
+ * In the editor the shell policy is installed once by `EditorProvider`
35
+ * (`EditorContext.tsx`), before any viewport mounts — including the Asset Lab
36
+ * document's own, which is why that document keeps today's behaviour exactly.
37
+ * The install site is the PROVIDER rather than `the world root's stage` because a
38
+ * workspace can have an Asset Lab document open with no scene the world root's stage
39
+ * mounted at all, and that document's viewport must not silently fall to the
40
+ * defaults.
41
+ */
42
+
43
+ import type { AuthoringAdapter } from '@volter/editor-project/adapter';
44
+ import type * as THREE from 'three';
45
+ import { makeNoAuthoringAdapter } from './authoring/no-authoring-adapter';
46
+ import type { EditorShellStore } from './editor-shell-store';
47
+
48
+ /**
49
+ * The native root whose viewport tools may claim the current selection, as far
50
+ * as the viewport cares: its KIND (only `three` lets the 3D chrome claim the
51
+ * surface) and its manifest root id (`null` for a single-adapter session).
52
+ *
53
+ * `authoring/viewport-tool-context.ts`'s `ViewportToolContext` is this plus the
54
+ * adapter, and is structurally assignable to it.
55
+ */
56
+ export interface ViewportToolOwner {
57
+ readonly worldId: string | null;
58
+ readonly kind: string;
59
+ }
60
+
61
+ export interface ViewportAuthoringPolicy {
62
+ /** The adapter this viewport drives when its host injected none. */
63
+ activeAuthoring(store: EditorShellStore): AuthoringAdapter;
64
+ /**
65
+ * The adapter a selection SCOPE is keyed on — the Hierarchy's own resolution,
66
+ * so a viewport drill-in and the panel breadcrumb name the same scope.
67
+ */
68
+ panelAuthoring(store: EditorShellStore): AuthoringAdapter;
69
+ /** Topmost-first hit test across every visible, pick-unlocked layer. */
70
+ pick(
71
+ store: EditorShellStore,
72
+ clientX: number,
73
+ clientY: number,
74
+ intent: 'normal' | 'deep',
75
+ ): string | null;
76
+ /** Which native root the selection resolves to, or `null` for empty,
77
+ * organizational and cross-root selections. */
78
+ toolOwner(adapter: AuthoringAdapter, selectedIds: Iterable<string>): ViewportToolOwner | null;
79
+ /** Is that owner's surface actually PAINTED in this viewport right now? */
80
+ toolOwnerPainted(store: EditorShellStore, owner: ViewportToolOwner | null): boolean;
81
+ /** Is a THREE stage painted here at all, selection or not — the gate for
82
+ * the grid and axis lines (Blender's floor is persistent; only the gizmos
83
+ * need an owner). */
84
+ threeSurfaceShowing(store: EditorShellStore, adapter: AuthoringAdapter): boolean;
85
+ /** The one three world rendered here, for the world-hidden eye. */
86
+ threeViewportRootId(store: EditorShellStore): string | null;
87
+ /** Apply the eye to every entity object (a no-op unless that root is hidden). */
88
+ applyRootHiddenVisibility(
89
+ objectMap: ReadonlyMap<string, THREE.Object3D>,
90
+ threeRootId: string | null,
91
+ ): void;
92
+ /** The scene-level half of the eye: background, fog, IBL, env objects. */
93
+ suppressRootEnvironment(scene: THREE.Scene): void;
94
+ }
95
+
96
+ /**
97
+ * Viewport-tool ownership for a SINGLE adapter — no composite, no manifest kind
98
+ * metadata to read.
99
+ *
100
+ * Structural and conservative, unchanged from where it was written
101
+ * (`authoring/viewport-tool-context.ts`, which now imports it): a rect-capable
102
+ * selection is DOM; a selection whose every node resolves to an `Object3D` is
103
+ * three; anything else advertises no kind-specific chrome rather than guessing.
104
+ * It speaks only the adapter contract, which is why it can be the default here.
105
+ */
106
+ export function adapterOnlyToolOwner(
107
+ adapter: AuthoringAdapter,
108
+ selectedIds: Iterable<string>,
109
+ ): ViewportToolOwner | null {
110
+ const ids = [...selectedIds];
111
+ if (ids.length === 0) return null;
112
+ if (ids.some((id) => adapter.hierarchy.node(id) === null)) return null;
113
+ if (adapter.rects) return { worldId: null, kind: 'dom' };
114
+ if (ids.every((id) => adapter.hierarchy.object3D?.(id) != null)) {
115
+ return { worldId: null, kind: 'three' };
116
+ }
117
+ return null;
118
+ }
119
+
120
+ /** Memoized per store, because the viewport calls `activeAuthoring` per gesture
121
+ * and adapter IDENTITY keys the selection scope and the handle cache. Mirrors
122
+ * `authoring/active-adapter.ts`'s own per-store memo. */
123
+ const _noAuthoringByStore = new WeakMap<EditorShellStore, AuthoringAdapter>();
124
+
125
+ export const DEFAULT_VIEWPORT_AUTHORING_POLICY: ViewportAuthoringPolicy = {
126
+ activeAuthoring(store) {
127
+ let adapter = _noAuthoringByStore.get(store);
128
+ if (!adapter) {
129
+ adapter = makeNoAuthoringAdapter(store, 'No authoring adapter');
130
+ _noAuthoringByStore.set(store, adapter);
131
+ }
132
+ return adapter;
133
+ },
134
+ panelAuthoring(store) {
135
+ // No shell means no shared panels to agree with.
136
+ return DEFAULT_VIEWPORT_AUTHORING_POLICY.activeAuthoring(store);
137
+ },
138
+ pick() {
139
+ // No shell means no layer stack to walk. A host that mounts this viewport
140
+ // for one document supplies its own hit test (`EditorViewportOptions.pick`),
141
+ // which is what the Asset Lab document does.
142
+ return null;
143
+ },
144
+ toolOwner: adapterOnlyToolOwner,
145
+ toolOwnerPainted() {
146
+ // No world-group eyes exist without a composite, so nothing can be hidden.
147
+ return true;
148
+ },
149
+ threeSurfaceShowing(_store, adapter) {
150
+ return !adapter.rects && typeof adapter.hierarchy.object3D === 'function';
151
+ },
152
+ threeViewportRootId() {
153
+ return null;
154
+ },
155
+ applyRootHiddenVisibility() {
156
+ // Unreachable while `threeViewportRootId` is null — stated rather than
157
+ // implemented, so the no-shell story is one story.
158
+ },
159
+ suppressRootEnvironment() {},
160
+ };
161
+
162
+ let _policy: ViewportAuthoringPolicy = DEFAULT_VIEWPORT_AUTHORING_POLICY;
163
+
164
+ /**
165
+ * Install the shell's composition. One owner, same rule as the store's
166
+ * `attachHistory`/`attachStatePersistence`: re-installing the SAME policy is a
167
+ * no-op (React strict-mode double-invokes the provider body), a DIFFERENT one
168
+ * throws rather than letting two shells disagree about what is under a pointer.
169
+ */
170
+ export function installViewportAuthoringPolicy(policy: ViewportAuthoringPolicy): void {
171
+ if (_policy === policy) return;
172
+ if (_policy !== DEFAULT_VIEWPORT_AUTHORING_POLICY) {
173
+ throw new Error('A viewport authoring policy is already installed.');
174
+ }
175
+ _policy = policy;
176
+ }
177
+
178
+ /** The installed policy, or the no-shell default. */
179
+ export function viewportAuthoringPolicy(): ViewportAuthoringPolicy {
180
+ return _policy;
181
+ }
182
+
183
+ /** Test seam: drop the installed policy. */
184
+ export function __resetViewportAuthoringPolicyForTest(): void {
185
+ _policy = DEFAULT_VIEWPORT_AUTHORING_POLICY;
186
+ }
@@ -0,0 +1,57 @@
1
+ /**
2
+ * Whether this user has learned the editor camera — the fact the viewport's
3
+ * on-canvas controls hint keys on.
4
+ *
5
+ * A 30-minute human build session (2026-08-28) asked "how do I move the
6
+ * camera" six-plus times and never found right-drag, on a build where
7
+ * right-drag orbit measured working: the gap was teaching, not mechanics.
8
+ * The hint carries the bindings until the user has REALLY learned them —
9
+ * three distinct orbit gestures, not one: dismissing on the first orbit
10
+ * meant one accidental right-drag hid the teaching before it was read
11
+ * (three human passes looked for the hint and found it gone — runhuman
12
+ * 15/17/31). Persisted per-user in localStorage like the inspector
13
+ * presentation; how you learned the camera is not a property of any game.
14
+ */
15
+
16
+ const STORAGE_KEY = 'vgai-viewport-orbit-gestures-v1';
17
+ const LEGACY_LEARNED_KEY = 'vgai-viewport-orbit-learned-v1';
18
+ const LEARNED_AFTER_GESTURES = 3;
19
+ const listeners = new Set<() => void>();
20
+ let gestures: number | null = null;
21
+
22
+ function storage(): Storage | null {
23
+ try {
24
+ return typeof window === 'undefined' ? null : window.localStorage;
25
+ } catch {
26
+ return null;
27
+ }
28
+ }
29
+
30
+ function count(): number {
31
+ if (gestures === null) {
32
+ const store = storage();
33
+ // A user the one-gesture era already marked stays learned.
34
+ if (store?.getItem(LEGACY_LEARNED_KEY) === '1') gestures = LEARNED_AFTER_GESTURES;
35
+ else gestures = Number(store?.getItem(STORAGE_KEY) ?? 0) || 0;
36
+ }
37
+ return gestures;
38
+ }
39
+
40
+ export function orbitLearned(): boolean {
41
+ return count() >= LEARNED_AFTER_GESTURES;
42
+ }
43
+
44
+ /** One distinct orbit gesture (one pointer-down-to-up that moved the camera). */
45
+ export function recordOrbitGesture(): void {
46
+ if (orbitLearned()) return;
47
+ gestures = count() + 1;
48
+ storage()?.setItem(STORAGE_KEY, String(gestures));
49
+ if (orbitLearned()) for (const listener of listeners) listener();
50
+ }
51
+
52
+ export function subscribeOrbitLearned(listener: () => void): () => void {
53
+ listeners.add(listener);
54
+ return () => {
55
+ listeners.delete(listener);
56
+ };
57
+ }
@@ -0,0 +1,237 @@
1
+ /**
2
+ * THE AUTHORED VIEWPORT'S DOOR — the host's side of `host.viewport` (WORK.md
3
+ * §Play leaves the host, P2). Every mounted 3D STAGE binds its rig and its
4
+ * presenter here under its own document id (ARCHITECTURE-CORE §One stage:
5
+ * there is one stage host, mounted once per 3D document, and the door is per
6
+ * stage) and drives its frame hook from its own RAF loop; the lanes that
7
+ * mount something (Play's adoption of the live scene, the play-entry camera
8
+ * flight) read here and never hold a panel.
9
+ *
10
+ * The SINGULAR members — `viewportRig`, `presentViewportRoots`,
11
+ * `setViewportHelper`, `onViewportFrame` — resolve THE PRIMARY STAGE at call
12
+ * time: the stage presenting live roots if one is, else the FOCUSED stage
13
+ * (`activeWorkspaceDocumentId()`'s), else the first bound. Focus and
14
+ * presentation are the two facts; nothing here is "the scene viewport" by
15
+ * name. `viewportStages()` is every stage, for the lane that must touch each
16
+ * one (a helper `Object3D` has one parent, so it is set per stage).
17
+ *
18
+ * Until the lanes move, the host's own lanes import this registry directly; a
19
+ * package reads `@volter/editor-sdk/host`'s `viewport` member, which is this.
20
+ */
21
+
22
+ import type { EditorHostStage, ViewportPresentation, ViewportRig } from '@volter/editor-sdk/host';
23
+ import type { ViewportRoot } from '@volter/editor-sdk/host';
24
+ import type * as THREE from 'three';
25
+ import { activeWorkspaceDocumentId } from './workspace-document-registry';
26
+
27
+ type Presenter = (roots: readonly ViewportRoot[]) => ViewportPresentation | null;
28
+ type HelperSink = (kind: string, object: THREE.Object3D | null) => void;
29
+
30
+ interface Binding {
31
+ readonly documentId: string;
32
+ readonly rig: ViewportRig;
33
+ readonly present: Presenter;
34
+ readonly setHelper: HelperSink;
35
+ readonly frameListeners: Set<(dtSeconds: number) => void>;
36
+ /** Helpers set on THIS stage by kind, so a re-bind restores them. */
37
+ readonly helpers: Map<string, THREE.Object3D | null>;
38
+ /** A presentation of live roots is alive on this stage right now. */
39
+ presenting: boolean;
40
+ }
41
+
42
+ /** Every bound stage, keyed by the document it draws; insertion-ordered, so
43
+ * "the first bound" is a real answer. */
44
+ const bound = new Map<string, Binding>();
45
+ /**
46
+ * What belongs to the STAGE rather than to its current canvas, held by
47
+ * document id so it OUTLIVES a binding: its frame subscribers and its
48
+ * helpers. A stage's viewport remounts (a dock re-layout, HMR) without its
49
+ * baked navmesh having to be re-baked — the `setHelper` contract the SDK
50
+ * states — and without a lane's `onFrame` going quiet.
51
+ */
52
+ const stageStateByDocument = new Map<
53
+ string,
54
+ {
55
+ readonly frameListeners: Set<(dtSeconds: number) => void>;
56
+ readonly helpers: Map<string, THREE.Object3D | null>;
57
+ }
58
+ >();
59
+
60
+ function stageStateFor(documentId: string): {
61
+ readonly frameListeners: Set<(dtSeconds: number) => void>;
62
+ readonly helpers: Map<string, THREE.Object3D | null>;
63
+ } {
64
+ let state = stageStateByDocument.get(documentId);
65
+ if (!state) {
66
+ state = { frameListeners: new Set(), helpers: new Map() };
67
+ stageStateByDocument.set(documentId, state);
68
+ }
69
+ return state;
70
+ }
71
+ /** Listeners on the singular `onViewportFrame`: they follow the PRIMARY
72
+ * stage, so they are held here and fanned in rather than added to a
73
+ * binding's own set, which would strand them on a stage that stops being
74
+ * primary (or unmounts). */
75
+ const primaryFrameListeners = new Set<(dtSeconds: number) => void>();
76
+ const stageListeners = new Set<(stages: readonly EditorHostStage[]) => void>();
77
+
78
+ /** THE PRIMARY STAGE: presenting live roots > focused > first bound. */
79
+ function primary(): Binding | null {
80
+ for (const binding of bound.values()) if (binding.presenting) return binding;
81
+ const focused = activeWorkspaceDocumentId();
82
+ if (focused !== null) {
83
+ const match = bound.get(focused);
84
+ if (match) return match;
85
+ }
86
+ return bound.values().next().value ?? null;
87
+ }
88
+
89
+ let stagesCache: readonly EditorHostStage[] | null = null;
90
+
91
+ function notifyStages(): void {
92
+ stagesCache = null;
93
+ const snapshot = viewportStages();
94
+ for (const fn of stageListeners) fn(snapshot);
95
+ }
96
+
97
+ /** A stage door resolves its binding BY ID on every call, so a door held
98
+ * across that stage's remount keeps driving the live canvas rather than the
99
+ * disposed one. */
100
+ function stageDoor(documentId: string, rig: ViewportRig): EditorHostStage {
101
+ const state = stageStateFor(documentId);
102
+ return {
103
+ documentId,
104
+ rig: () => bound.get(documentId)?.rig ?? rig,
105
+ setHelper: (kind, object) => {
106
+ state.helpers.set(kind, object);
107
+ bound.get(documentId)?.setHelper(kind, object);
108
+ },
109
+ onFrame: (fn) => {
110
+ state.frameListeners.add(fn);
111
+ return () => {
112
+ state.frameListeners.delete(fn);
113
+ };
114
+ },
115
+ };
116
+ }
117
+
118
+ /** A mounted stage binds its rig, how it presents live roots and how it shows
119
+ * a helper, under the id of the document it draws; the return unbinds (a
120
+ * re-bind for the same id REPLACES, and a stale binding's unbind never
121
+ * removes its successor). Helpers set through the singular door before the
122
+ * bind are applied now, the way they always were — but "before the bind" is
123
+ * now per stage: a helper shown on THIS document's stage returns to it, and
124
+ * a helper set while nothing is bound anywhere is dropped rather than
125
+ * appearing on whichever stage happens to mount next. */
126
+ export function bindViewportRig(
127
+ rig: ViewportRig,
128
+ present: Presenter,
129
+ setHelper: HelperSink,
130
+ options: { readonly documentId: string },
131
+ ): () => void {
132
+ const state = stageStateFor(options.documentId);
133
+ const next: Binding = {
134
+ documentId: options.documentId,
135
+ rig,
136
+ present,
137
+ setHelper,
138
+ frameListeners: state.frameListeners,
139
+ helpers: state.helpers,
140
+ presenting: false,
141
+ };
142
+ bound.set(options.documentId, next);
143
+ for (const [kind, object] of next.helpers) setHelper(kind, object);
144
+ notifyStages();
145
+ return () => {
146
+ if (bound.get(options.documentId) !== next) return;
147
+ bound.delete(options.documentId);
148
+ notifyStages();
149
+ };
150
+ }
151
+
152
+ /** Show (or clear with null) the editor-only helper of `kind` on the PRIMARY
153
+ * stage. A helper wanted on every stage is set per stage through
154
+ * {@link viewportStages} — an `Object3D` has one parent. */
155
+ export function setViewportHelper(kind: string, object: THREE.Object3D | null): void {
156
+ const stage = primary();
157
+ if (!stage) return;
158
+ stage.helpers.set(kind, object);
159
+ stage.setHelper(kind, object);
160
+ }
161
+
162
+ export function viewportRig(): ViewportRig | null {
163
+ return primary()?.rig ?? null;
164
+ }
165
+
166
+ export function presentViewportRoots(roots: readonly ViewportRoot[]): ViewportPresentation | null {
167
+ const stage = primary();
168
+ if (!stage) return null;
169
+ const presentation = stage.present(roots);
170
+ if (!presentation) return null;
171
+ // The stage stays PRIMARY for as long as it is showing live roots — that is
172
+ // what makes Play's own camera flight and frame hook keep finding it while
173
+ // focus moves to the live document.
174
+ stage.presenting = true;
175
+ let released = false;
176
+ return {
177
+ worldId: presentation.worldId,
178
+ dispose: () => {
179
+ if (!released) {
180
+ released = true;
181
+ stage.presenting = false;
182
+ }
183
+ presentation.dispose();
184
+ },
185
+ };
186
+ }
187
+
188
+ /** Runs after the PRIMARY stage's own per-frame update, and RE-TARGETS: the
189
+ * listener follows whichever stage is primary, not the one that was primary
190
+ * when it subscribed. */
191
+ export function onViewportFrame(fn: (dtSeconds: number) => void): () => void {
192
+ primaryFrameListeners.add(fn);
193
+ return () => {
194
+ primaryFrameListeners.delete(fn);
195
+ };
196
+ }
197
+
198
+ /** Every bound stage, in bind order. */
199
+ export function viewportStages(): readonly EditorHostStage[] {
200
+ if (!stagesCache)
201
+ stagesCache = [...bound.values()].map((binding) => stageDoor(binding.documentId, binding.rig));
202
+ return stagesCache;
203
+ }
204
+
205
+ /**
206
+ * WHICH HELPER KINDS A STAGE IS HOLDING — the kinds something has actually
207
+ * shown on it through `setHelper` (`@volter/editor-sdk/host`,
208
+ * `EditorHostStage.setHelper`), cleared ones excluded.
209
+ *
210
+ * It exists because a 3D document's own OVERLAYS MENU must follow what the
211
+ * document put there and nothing else (`Object3DDocumentToolbar`): Blender's
212
+ * viewport overlay popover lists Bones, and ours may not list a Bones row over
213
+ * a document that has no bones to show. Same rule as the Outliner's restriction
214
+ * columns — a control follows what the thing behind it ANSWERS, never a knob.
215
+ */
216
+ export function viewportStageHelperKinds(documentId: string): readonly string[] {
217
+ const state = stageStateByDocument.get(documentId);
218
+ if (!state) return [];
219
+ return [...state.helpers].filter(([, object]) => object !== null).map(([kind]) => kind);
220
+ }
221
+
222
+ export function onViewportStages(fn: (stages: readonly EditorHostStage[]) => void): () => void {
223
+ stageListeners.add(fn);
224
+ return () => {
225
+ stageListeners.delete(fn);
226
+ };
227
+ }
228
+
229
+ /** A stage's RAF loop calls this after its own update each frame. The stage's
230
+ * own listeners always run; the primary-stage listeners run here only when
231
+ * this stage IS the primary. */
232
+ export function runViewportFrame(documentId: string, dtSeconds: number): void {
233
+ const binding = bound.get(documentId);
234
+ if (!binding) return;
235
+ for (const fn of binding.frameListeners) fn(dtSeconds);
236
+ if (primary() === binding) for (const fn of primaryFrameListeners) fn(dtSeconds);
237
+ }
@@ -0,0 +1,12 @@
1
+ import { isEditorOwnedObject } from '@volter/editor-threejs/viewport/editor-layers';
2
+ import type { ViewportShadingRenderer } from '@volter/editor-threejs/render/viewport-shading';
3
+ import type * as THREE from 'three';
4
+
5
+ /**
6
+ * Scene diagnostic shading targets authored/runtime meshes only. Editor
7
+ * infrastructure shares the native scene for authoring, but its custom
8
+ * gizmo materials are part of the editor implementation and must stay native.
9
+ */
10
+ export const isEditorViewportShadingTarget: Parameters<ViewportShadingRenderer['render']>[3] = (
11
+ mesh: THREE.Mesh,
12
+ ) => !isEditorOwnedObject(mesh);
@@ -0,0 +1,141 @@
1
+ /**
2
+ * A Vite transform/build failure is REPORTED, never rendered over the app.
3
+ *
4
+ * The editor and the game it is authoring share one page, one Vite instance
5
+ * and one HMR client, so Vite's stock error overlay — fixed, full-screen,
6
+ * z-index 99999 — made a syntax error in the USER'S GAME SOURCE brick the
7
+ * whole editor: nothing behind it clickable, no way out but editing the file
8
+ * blind. Owner, watching it happen: "this error needs to be surfaced but while
9
+ * this error is up, the rest of the app cannot be used which is a problem."
10
+ * The overlay is therefore off (`server.hmr.overlay: false` in
11
+ * `server/dev.ts` and `server/packaged.ts`) and this module is what the
12
+ * payload goes to instead.
13
+ *
14
+ * WHERE IT GOES: the editor's ONE error home — a console line, the
15
+ * `console-counts` status item that counts it, and, for an EDITOR/engine-owned
16
+ * failure, the auto-revealed Console (the same non-blocking "in your face"
17
+ * move a mount failure already makes). No banner, no second surface: see
18
+ * `components/status-contributions.tsx` on why the shell's error banners were
19
+ * deleted.
20
+ *
21
+ * WHY CLASSIFY AT ALL: the two owners deserve different volume. A game that
22
+ * does not compile is ordinary authoring — say so precisely and get out of the
23
+ * way. Our own engine/editor code failing to compile is a defect in the tool
24
+ * the user is holding, so it also pulls the Console open.
25
+ *
26
+ * Vite ALSO logs its own `[vite] Internal Server Error` line to `console.error`
27
+ * whenever the overlay is off, and `installEditorConsoleCapture()` puts that in
28
+ * the console too. That raw line is the trace; the line this module writes is
29
+ * the classified summary — the same trace/summary split
30
+ * `authoring/mount-failure-report.ts` documents, not a second channel.
31
+ *
32
+ * The SAVE-TIME half of the same story is louder and lives on the server:
33
+ * `server/project-validation.ts` parses every `src/` write, and
34
+ * `server/editor-server.ts` prints `✖ Invalid project file`, broadcasts it to
35
+ * every tab, and holds it in `/__editor/state`'s `projectValidation` (what
36
+ * `vgai status` reads) until the file saves clean again. Recovery therefore
37
+ * needs nothing here: this module holds no state to clear.
38
+ */
39
+
40
+ import { editorConsole } from './editor-console';
41
+ import { showConsoleUtility } from './workspace-utility-commands';
42
+
43
+ /** The `err` half of Vite's `vite:error` HMR payload — only the fields read
44
+ * here, so a Vite version that adds more does not need this type updated. */
45
+ export interface ViteErrorLike {
46
+ readonly message?: string;
47
+ readonly frame?: string;
48
+ /** Vite's module id: an absolute path, possibly `/@fs`-prefixed and
49
+ * possibly carrying the `?vgai-mount=N` query `project-module-url.ts`
50
+ * minted. */
51
+ readonly id?: string;
52
+ readonly loc?: { readonly file?: string; readonly line?: number; readonly column?: number };
53
+ }
54
+
55
+ export type ViteErrorOwner = 'project' | 'editor';
56
+
57
+ /**
58
+ * The absolute filesystem path a payload blames, or `null` when it blames
59
+ * nothing identifiable.
60
+ *
61
+ * Both forms are normalized here because BOTH occur: `loc.file` is a plain
62
+ * absolute path, while `id` is the URL the browser asked for — which for a
63
+ * project module outside the Vite root is the `/@fs`-prefixed, query-carrying
64
+ * string `project-module-url.ts` builds (`fsImportPath` + `?vgai-mount=N`).
65
+ * Undoing exactly that construction is why the two `/@fs` shapes below mirror
66
+ * `fsImportPath`'s own posix/Windows split.
67
+ */
68
+ export function viteErrorFile(err: ViteErrorLike): string | null {
69
+ const raw = err.loc?.file ?? err.id ?? null;
70
+ if (!raw) return null;
71
+ const bare = raw.split('?')[0]!.split('#')[0]!;
72
+ if (!bare) return null;
73
+ if (!bare.startsWith('/@fs/')) return bare;
74
+ const unprefixed = bare.slice('/@fs'.length);
75
+ // `/@fs` + a posix root gives `/@fs/abs/path`; `/@fs/` + a Windows root
76
+ // gives `/@fs/C:/path`, whose leading slash is the separator, not the root.
77
+ return /^\/[A-Za-z]:/.test(unprefixed) ? unprefixed.slice(1) : unprefixed;
78
+ }
79
+
80
+ /**
81
+ * Whose code failed: the OPEN PROJECT's, or ours.
82
+ *
83
+ * "The project's own module" is the same question
84
+ * `server/game-globals-shadow.ts`'s `shouldShadowGameGlobals` answers on the
85
+ * server (a prefix test against the canonical project root) — asked here on
86
+ * the client, where the payload arrives as a URL rather than a path, hence the
87
+ * normalization above. An unattributable failure, or one with no project open,
88
+ * counts as ours: over-reporting our own breakage is the safe direction.
89
+ */
90
+ export function viteErrorOwner(err: ViteErrorLike, projectRoot: string): ViteErrorOwner {
91
+ const file = viteErrorFile(err);
92
+ if (!file || !projectRoot) return 'editor';
93
+ const root = projectRoot.endsWith('/') ? projectRoot.slice(0, -1) : projectRoot;
94
+ return file === root || file.startsWith(`${root}/`) ? 'project' : 'editor';
95
+ }
96
+
97
+ /** `file:line:col — message`, plus the code frame when the payload carries one
98
+ * (Babel/esbuild both do, and the frame is the part the deleted overlay was
99
+ * genuinely good at showing). */
100
+ export function formatViteError(err: ViteErrorLike): string {
101
+ const file = viteErrorFile(err);
102
+ const line = err.loc?.line;
103
+ const column = err.loc?.column;
104
+ const where = file
105
+ ? `${file}${line === undefined ? '' : `:${line}${column === undefined ? '' : `:${column}`}`}`
106
+ : null;
107
+ const head = err.message?.trim() || 'Vite could not build this module.';
108
+ const frame = err.frame?.replace(/\s+$/, '');
109
+ return [where ? `${where} — ${head}` : head, frame || null].filter(Boolean).join('\n');
110
+ }
111
+
112
+ /** The minimal slice of `import.meta.hot` this module needs — narrower than
113
+ * Vite's `ViteHotContext` so the unit test can call it with a fake. */
114
+ export interface ViteErrorHotContext {
115
+ on(event: 'vite:error', cb: (payload: { err?: ViteErrorLike }) => void): void;
116
+ }
117
+
118
+ /**
119
+ * Subscribe the editor's error home to `vite:error`. Called once from
120
+ * `main.tsx`; `getProjectRoot` is read per-event because a project can be
121
+ * opened, switched, or closed long after boot.
122
+ */
123
+ export function installViteErrorSurface(
124
+ hot: ViteErrorHotContext,
125
+ getProjectRoot: () => string,
126
+ ): void {
127
+ hot.on('vite:error', (payload) => {
128
+ const err = payload?.err;
129
+ if (!err) return;
130
+ const owner = viteErrorOwner(err, getProjectRoot());
131
+ if (owner === 'project') {
132
+ editorConsole.error(`This game's source did not build.\n${formatViteError(err)}`, 'game');
133
+ return;
134
+ }
135
+ editorConsole.error(
136
+ `The editor's own source did not build.\n${formatViteError(err)}`,
137
+ 'editor',
138
+ );
139
+ showConsoleUtility();
140
+ });
141
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * POLL UNTIL A LIVE PREDICATE HOLDS — the one wait the editor's async doors
3
+ * share, and the one place its cadence is spelled.
4
+ *
5
+ * It lived private in `editor-view-presentation.ts` while the presenter was
6
+ * the only module that addressed a document. Now that each document family
7
+ * answers its own address (`document-open-registry.ts`), the families do the
8
+ * waiting their own addresses need — a table entry that arrives on a later
9
+ * adapter resolution, a contribution that registers after the first
10
+ * discovery pass — so the helper is shared rather than duplicated four times.
11
+ *
12
+ * NOT a general scheduling utility: it polls, which is what a registry with no
13
+ * per-entry subscription leaves you. Where a seam DOES publish changes
14
+ * (`subscribeToolContributions`, `subscribeProjectAdapter`), subscribe to it.
15
+ */
16
+
17
+ /**
18
+ * How long an EXPLICIT address waits for the thing it names. A view link, a
19
+ * restored layout and an agent's `present` are all durable intent, so a
20
+ * document that is merely late must still land; the window is bounded because
21
+ * "it is not coming" has to be sayable.
22
+ */
23
+ export const DOCUMENT_REGISTRATION_TIMEOUT_MS = 10_000;
24
+
25
+ /** `true` once `predicate()` holds, `false` if `timeoutMs` elapses first. */
26
+ export async function waitUntil(predicate: () => boolean, timeoutMs = 4000): Promise<boolean> {
27
+ if (predicate()) return true;
28
+ const started = performance.now();
29
+ return new Promise((resolve) => {
30
+ const tick = () => {
31
+ if (predicate()) resolve(true);
32
+ else if (performance.now() - started >= timeoutMs) resolve(false);
33
+ else setTimeout(tick, 25);
34
+ };
35
+ setTimeout(tick, 0);
36
+ });
37
+ }