@volter/sdk 0.0.0-stage → 0.5.204

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 (523) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +20 -0
  3. package/README.md +38 -3
  4. package/package.json +510 -4
  5. package/src/account.ts +210 -0
  6. package/src/chrome.ts +88 -0
  7. package/src/client.ts +1646 -0
  8. package/src/commands.ts +66 -0
  9. package/src/contributions.ts +619 -0
  10. package/src/css-numeric-style.ts +97 -0
  11. package/src/document-probe.ts +282 -0
  12. package/src/editor-view.ts +225 -0
  13. package/src/extension.ts +40 -0
  14. package/src/generations.ts +178 -0
  15. package/src/host.ts +1157 -0
  16. package/src/http-transport.browser.ts +14 -0
  17. package/src/http-transport.node.ts +19 -0
  18. package/src/index.ts +131 -0
  19. package/src/kit/CapabilityCoverageSection.tsx +185 -0
  20. package/src/kit/account-client.ts +333 -0
  21. package/src/kit/action-registry.ts +317 -0
  22. package/src/kit/active-product.ts +76 -0
  23. package/src/kit/active-project.ts +155 -0
  24. package/src/kit/adapter-editor-config.ts +25 -0
  25. package/src/kit/adapter-module.ts +7 -0
  26. package/src/kit/adapter-observation.ts +49 -0
  27. package/src/kit/animation/animation-clock.ts +479 -0
  28. package/src/kit/animation/stage-transport.ts +385 -0
  29. package/src/kit/api/assets.ts +365 -0
  30. package/src/kit/api/project-open.ts +355 -0
  31. package/src/kit/api/project-source.ts +180 -0
  32. package/src/kit/api/project-state.ts +110 -0
  33. package/src/kit/api/relay.ts +270 -0
  34. package/src/kit/api/themes.ts +45 -0
  35. package/src/kit/api-asset-library-wire.ts +45 -0
  36. package/src/kit/api-base.ts +10 -0
  37. package/src/kit/api-build.ts +99 -0
  38. package/src/kit/api-git-wire.ts +56 -0
  39. package/src/kit/api-logs.ts +92 -0
  40. package/src/kit/api-project-identity.ts +74 -0
  41. package/src/kit/api-settings.ts +36 -0
  42. package/src/kit/api-worktrees.ts +205 -0
  43. package/src/kit/asset-capabilities.ts +344 -0
  44. package/src/kit/asset-compare-core.ts +171 -0
  45. package/src/kit/asset-editor-context.tsx +101 -0
  46. package/src/kit/asset-events.ts +96 -0
  47. package/src/kit/asset-inspector-actions.ts +87 -0
  48. package/src/kit/asset-selection-viewer-registry.ts +113 -0
  49. package/src/kit/asset-selection.ts +146 -0
  50. package/src/kit/asset-thumbnails.ts +25 -0
  51. package/src/kit/asset-viewers.ts +115 -0
  52. package/src/kit/asset-workflow/asset-import-jobs.ts +106 -0
  53. package/src/kit/asset-workflow/asset-ledger-backend.ts +126 -0
  54. package/src/kit/asset-workflow/asset-ledger.ts +156 -0
  55. package/src/kit/asset-workflow/asset-materialization-report.ts +140 -0
  56. package/src/kit/asset-workflow/asset-pack-manifest.ts +320 -0
  57. package/src/kit/asset-workflow/asset-types.ts +142 -0
  58. package/src/kit/asset-workflow/audio-preview-player.ts +193 -0
  59. package/src/kit/asset-workflow/audio-waveform.ts +22 -0
  60. package/src/kit/asset-workflow/cloud-asset-client.ts +263 -0
  61. package/src/kit/asset-workflow/hosted-asset-materialization.ts +236 -0
  62. package/src/kit/asset-workflow/image-view-scale.ts +31 -0
  63. package/src/kit/asset-workflow/import-contract.ts +124 -0
  64. package/src/kit/asset-workflow/ledger-write-lock.ts +244 -0
  65. package/src/kit/asset-workflow/pixi-spritesheet.ts +197 -0
  66. package/src/kit/asset-workflow/preview-resource-lifetime.ts +44 -0
  67. package/src/kit/asset-workflow/project-asset-commands.ts +20 -0
  68. package/src/kit/asset-workflow/project-content.ts +288 -0
  69. package/src/kit/asset-workflow/project-source-index.ts +545 -0
  70. package/src/kit/asset-workflow/thumbnail-system.ts +256 -0
  71. package/src/kit/authoring/active-adapter.ts +200 -0
  72. package/src/kit/authoring/active-systems.ts +422 -0
  73. package/src/kit/authoring/adapter-key.ts +18 -0
  74. package/src/kit/authoring/authoring-asset-url.ts +27 -0
  75. package/src/kit/authoring/bootstrap-state.ts +49 -0
  76. package/src/kit/authoring/boundary-authoring-adapter.ts +189 -0
  77. package/src/kit/authoring/canvas-scene-guides.ts +84 -0
  78. package/src/kit/authoring/composite-authoring-adapter.ts +2109 -0
  79. package/src/kit/authoring/consumer-actions.ts +531 -0
  80. package/src/kit/authoring/design-time-layers.ts +852 -0
  81. package/src/kit/authoring/design-time-mount-registry.ts +244 -0
  82. package/src/kit/authoring/edit-mode-authoring.ts +637 -0
  83. package/src/kit/authoring/empty-project-authoring.ts +22 -0
  84. package/src/kit/authoring/instance-source-menu.ts +135 -0
  85. package/src/kit/authoring/layered-pick.ts +185 -0
  86. package/src/kit/authoring/mounted-root-subjects.ts +146 -0
  87. package/src/kit/authoring/no-authoring-adapter.ts +59 -0
  88. package/src/kit/authoring/object3d-document-persistence.ts +122 -0
  89. package/src/kit/authoring/panel-authoring.ts +121 -0
  90. package/src/kit/authoring/project-authoring-session.ts +105 -0
  91. package/src/kit/authoring/provenance.ts +99 -0
  92. package/src/kit/authoring/react-canvas-navigation.ts +259 -0
  93. package/src/kit/authoring/react-design-canvas-style.ts +20 -0
  94. package/src/kit/authoring/react-story-board.ts +917 -0
  95. package/src/kit/authoring/selection-scope.ts +195 -0
  96. package/src/kit/authoring/shell-document-ops.ts +169 -0
  97. package/src/kit/authoring/story-board-chrome-fit.ts +107 -0
  98. package/src/kit/authoring/story-board-presentation.ts +111 -0
  99. package/src/kit/authoring/three-root.ts +67 -0
  100. package/src/kit/authoring/viewport-tool-context.ts +73 -0
  101. package/src/kit/authoring/viewport-tool-owner.ts +38 -0
  102. package/src/kit/authoring/world-session-state.ts +101 -0
  103. package/src/kit/authoring-seam-evidence.ts +300 -0
  104. package/src/kit/availability-tick.ts +66 -0
  105. package/src/kit/bitmap-label.ts +120 -0
  106. package/src/kit/boot-routing.ts +392 -0
  107. package/src/kit/breakpoint-state.ts +43 -0
  108. package/src/kit/build-identity.ts +16 -0
  109. package/src/kit/bytes-codec.ts +62 -0
  110. package/src/kit/cancellation-reason.ts +58 -0
  111. package/src/kit/canvas-frames.ts +88 -0
  112. package/src/kit/capture-camera-pose.ts +77 -0
  113. package/src/kit/capture-size.ts +88 -0
  114. package/src/kit/chrome-registry.ts +159 -0
  115. package/src/kit/chrome-slot-registry.ts +91 -0
  116. package/src/kit/collaboration-client.ts +264 -0
  117. package/src/kit/collaboration-presence.ts +41 -0
  118. package/src/kit/command-dispatch.ts +19 -0
  119. package/src/kit/command-listener.ts +2182 -0
  120. package/src/kit/command-registry.ts +71 -0
  121. package/src/kit/component-board-registry.ts +205 -0
  122. package/src/kit/component-states-registry.ts +199 -0
  123. package/src/kit/components/AlignToolbar.tsx +204 -0
  124. package/src/kit/components/ApplicationMenus.tsx +372 -0
  125. package/src/kit/components/AssetEditorShell.tsx +216 -0
  126. package/src/kit/components/AssetInspectorToolSection.tsx +124 -0
  127. package/src/kit/components/BoardRulers.tsx +354 -0
  128. package/src/kit/components/CanvasAddNodeDialogs.tsx +529 -0
  129. package/src/kit/components/CanvasSceneViewport.tsx +1195 -0
  130. package/src/kit/components/ChromeSlot.tsx +20 -0
  131. package/src/kit/components/CodeView.tsx +470 -0
  132. package/src/kit/components/CompactInspectorShell.tsx +39 -0
  133. package/src/kit/components/ConsolePanel.tsx +273 -0
  134. package/src/kit/components/GameplaySessionTimeline.tsx +295 -0
  135. package/src/kit/components/InspectionProjection.tsx +932 -0
  136. package/src/kit/components/Inspector.tsx +270 -0
  137. package/src/kit/components/InspectorCanvasPreview.tsx +35 -0
  138. package/src/kit/components/InspectorFieldsSection.tsx +290 -0
  139. package/src/kit/components/InspectorStoriesSection.tsx +92 -0
  140. package/src/kit/components/InspectorToolSection.tsx +96 -0
  141. package/src/kit/components/InspectorTransformSection.tsx +245 -0
  142. package/src/kit/components/LightExplorerPanel.tsx +433 -0
  143. package/src/kit/components/MediaProperties.tsx +145 -0
  144. package/src/kit/components/ProjectHeader.tsx +328 -0
  145. package/src/kit/components/ReactCanvasControls.tsx +358 -0
  146. package/src/kit/components/RootSelectionOverlay.tsx +3688 -0
  147. package/src/kit/components/RootTextEditor.tsx +79 -0
  148. package/src/kit/components/SaveStatus.tsx +70 -0
  149. package/src/kit/components/SurfaceCrashBoundary.tsx +105 -0
  150. package/src/kit/components/SurfaceStateOverlay.tsx +24 -0
  151. package/src/kit/components/ToolContributionSurfaces.tsx +49 -0
  152. package/src/kit/components/ToolHost.tsx +380 -0
  153. package/src/kit/components/Toolbar.tsx +811 -0
  154. package/src/kit/components/TransientHint.tsx +44 -0
  155. package/src/kit/components/VersionControlSection.tsx +470 -0
  156. package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
  157. package/src/kit/components/VolterLogo.tsx +18 -0
  158. package/src/kit/components/WorktreeSwitcher.tsx +712 -0
  159. package/src/kit/components/account-documents.tsx +1162 -0
  160. package/src/kit/components/asset-documents.tsx +794 -0
  161. package/src/kit/components/asset-editor-persistence.ts +216 -0
  162. package/src/kit/components/asset-selection-section.tsx +545 -0
  163. package/src/kit/components/asset-thumbnails.tsx +307 -0
  164. package/src/kit/components/asset-viewers/AudioViewer.tsx +201 -0
  165. package/src/kit/components/asset-viewers/GenericJsonViewer.tsx +102 -0
  166. package/src/kit/components/asset-viewers/ImageViewer.tsx +300 -0
  167. package/src/kit/components/asset-viewers/JsonAssetDocument.tsx +98 -0
  168. package/src/kit/components/asset-viewers/OnlineAssetDetail.tsx +426 -0
  169. package/src/kit/components/asset-viewers/SourceAssetViewer.tsx +356 -0
  170. package/src/kit/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
  171. package/src/kit/components/asset-viewers/VideoViewer.tsx +101 -0
  172. package/src/kit/components/asset-viewers/shader-source.ts +144 -0
  173. package/src/kit/components/board-guides.ts +150 -0
  174. package/src/kit/components/canvas-scene-hotkeys.ts +37 -0
  175. package/src/kit/components/canvas-temporary-pivot.ts +34 -0
  176. package/src/kit/components/core-utilities.tsx +94 -0
  177. package/src/kit/components/inspector-preview-section.tsx +223 -0
  178. package/src/kit/components/inspector-revert-label.ts +20 -0
  179. package/src/kit/components/inspector-selection.ts +42 -0
  180. package/src/kit/components/inspector-stories-gating.ts +171 -0
  181. package/src/kit/components/inspector-transform-subject.ts +11 -0
  182. package/src/kit/components/inspector-transform.ts +88 -0
  183. package/src/kit/components/kind-documents.tsx +544 -0
  184. package/src/kit/components/primitives/DraftColorInput.tsx +74 -0
  185. package/src/kit/components/project-tool-documents.tsx +402 -0
  186. package/src/kit/components/scene-documents.tsx +221 -0
  187. package/src/kit/components/status-contributions.tsx +407 -0
  188. package/src/kit/components/tool-documents.tsx +302 -0
  189. package/src/kit/components/tool-schema-form.tsx +262 -0
  190. package/src/kit/components/use-after-paint.ts +41 -0
  191. package/src/kit/components/use-project-image-assets.ts +86 -0
  192. package/src/kit/components/workspace-history.ts +32 -0
  193. package/src/kit/components/world-documents.tsx +570 -0
  194. package/src/kit/components/world-overlay-gestures.ts +1939 -0
  195. package/src/kit/composite-screenshot.ts +2238 -0
  196. package/src/kit/content-entry-source-registry.ts +184 -0
  197. package/src/kit/contribution-surfaces.ts +48 -0
  198. package/src/kit/coverage/canvas-reveal.ts +192 -0
  199. package/src/kit/coverage/design-time-surfaces.ts +101 -0
  200. package/src/kit/coverage/ontology-invariants.ts +466 -0
  201. package/src/kit/coverage/session-vitals.ts +503 -0
  202. package/src/kit/crash-null-boundary.ts +36 -0
  203. package/src/kit/creation-site-edit.ts +1491 -0
  204. package/src/kit/creation-site-registry.ts +160 -0
  205. package/src/kit/delegate-harness-registry.ts +134 -0
  206. package/src/kit/document-areas.ts +70 -0
  207. package/src/kit/document-context-registry.ts +193 -0
  208. package/src/kit/document-open-registry.ts +200 -0
  209. package/src/kit/document-play-extension.ts +221 -0
  210. package/src/kit/document-preview-source.ts +20 -0
  211. package/src/kit/document-renderer-session.ts +138 -0
  212. package/src/kit/document-stage-sessions.ts +26 -0
  213. package/src/kit/document-viewports.ts +120 -0
  214. package/src/kit/editor-api.ts +46 -0
  215. package/src/kit/editor-chrome-capture.ts +136 -0
  216. package/src/kit/editor-commands.ts +176 -0
  217. package/src/kit/editor-console.ts +580 -0
  218. package/src/kit/editor-current-view.ts +56 -0
  219. package/src/kit/editor-document-probe.ts +1168 -0
  220. package/src/kit/editor-git-client.ts +115 -0
  221. package/src/kit/editor-hotkeys.ts +728 -0
  222. package/src/kit/editor-lease-view.ts +39 -0
  223. package/src/kit/editor-lease.ts +415 -0
  224. package/src/kit/editor-mode.ts +19 -0
  225. package/src/kit/editor-notifications.ts +140 -0
  226. package/src/kit/editor-presence.ts +563 -0
  227. package/src/kit/editor-presentation-activity.ts +58 -0
  228. package/src/kit/editor-presentation-notice.ts +42 -0
  229. package/src/kit/editor-runtime.tsx +147 -0
  230. package/src/kit/editor-server-response.ts +86 -0
  231. package/src/kit/editor-session-attribution.ts +85 -0
  232. package/src/kit/editor-session-mode.ts +54 -0
  233. package/src/kit/editor-state-facets.ts +74 -0
  234. package/src/kit/editor-view-presentation.ts +777 -0
  235. package/src/kit/environment-images.ts +58 -0
  236. package/src/kit/eyedropper-session.ts +60 -0
  237. package/src/kit/files/file-provider.ts +62 -0
  238. package/src/kit/files/project-files.ts +270 -0
  239. package/src/kit/finders/index.ts +137 -0
  240. package/src/kit/finders/scenes-from-entrypoint-selection.ts +387 -0
  241. package/src/kit/frame/frame-parts.ts +30 -0
  242. package/src/kit/framed-document-capture.ts +34 -0
  243. package/src/kit/game-globals-prelude.ts +143 -0
  244. package/src/kit/game-surface-defaults.ts +33 -0
  245. package/src/kit/gameplay-dom-recording.ts +318 -0
  246. package/src/kit/gameplay-export-state.ts +14 -0
  247. package/src/kit/gameplay-replay.ts +417 -0
  248. package/src/kit/gameplay-session-time.ts +9 -0
  249. package/src/kit/gameplay-sessions.ts +204 -0
  250. package/src/kit/hierarchy-component-marks.ts +298 -0
  251. package/src/kit/hierarchy-internals.ts +197 -0
  252. package/src/kit/hierarchy-kind-icon.ts +217 -0
  253. package/src/kit/hierarchy-menu-registry.ts +67 -0
  254. package/src/kit/hierarchy-node-rows.ts +307 -0
  255. package/src/kit/hierarchy-panel-view.ts +280 -0
  256. package/src/kit/hierarchy-projection.ts +76 -0
  257. package/src/kit/hierarchy-row-media.ts +45 -0
  258. package/src/kit/hierarchy-row-model.ts +308 -0
  259. package/src/kit/hierarchy-rows.ts +11 -0
  260. package/src/kit/hierarchy-walk.ts +86 -0
  261. package/src/kit/history/editor-session.ts +25 -0
  262. package/src/kit/history/history-commands.ts +147 -0
  263. package/src/kit/history/history-delegate.ts +187 -0
  264. package/src/kit/history/history-limit-notices.ts +43 -0
  265. package/src/kit/history/history-service.ts +1189 -0
  266. package/src/kit/history/persistence-coordinator.ts +35 -0
  267. package/src/kit/history/project-file-history.ts +386 -0
  268. package/src/kit/history/project-root-history-backends.ts +139 -0
  269. package/src/kit/history/resource-registry.ts +209 -0
  270. package/src/kit/history/snapshot-store.ts +103 -0
  271. package/src/kit/history/source-history-backend.ts +546 -0
  272. package/src/kit/history-types.ts +124 -0
  273. package/src/kit/hmr-registration-group.ts +67 -0
  274. package/src/kit/hmr-stable-react-context.ts +23 -0
  275. package/src/kit/hotkeys.ts +190 -0
  276. package/src/kit/inference-diagnostics.ts +69 -0
  277. package/src/kit/initial-project.ts +80 -0
  278. package/src/kit/inspection/active-subject.ts +571 -0
  279. package/src/kit/inspection/active-surface.ts +142 -0
  280. package/src/kit/inspection/compose-subject.ts +1055 -0
  281. package/src/kit/inspection/compose.ts +7 -0
  282. package/src/kit/inspection/display.ts +171 -0
  283. package/src/kit/inspection/document-subject.ts +109 -0
  284. package/src/kit/inspection/game-subject.ts +85 -0
  285. package/src/kit/inspection/null-subject.ts +119 -0
  286. package/src/kit/inspection/serialize.ts +357 -0
  287. package/src/kit/inspection/use-active-inspection.ts +180 -0
  288. package/src/kit/inspection-model.ts +542 -0
  289. package/src/kit/inspection-node-media.ts +58 -0
  290. package/src/kit/inspector-presentation.ts +203 -0
  291. package/src/kit/inspector-property-grouping.ts +64 -0
  292. package/src/kit/inspector-section-registry.ts +221 -0
  293. package/src/kit/instance-source-actions.ts +163 -0
  294. package/src/kit/js-heap.ts +71 -0
  295. package/src/kit/key-actions.ts +91 -0
  296. package/src/kit/keymap-presets.ts +428 -0
  297. package/src/kit/layout-policy.ts +31 -0
  298. package/src/kit/light-explorer-model.ts +134 -0
  299. package/src/kit/live-canvas-frame.ts +55 -0
  300. package/src/kit/live-document.ts +296 -0
  301. package/src/kit/live-gesture-lock.ts +50 -0
  302. package/src/kit/live-seam-evidence.ts +11 -0
  303. package/src/kit/live-session-registry.ts +220 -0
  304. package/src/kit/live-transition.ts +391 -0
  305. package/src/kit/manifest-project.ts +107 -0
  306. package/src/kit/module-fetch-diagnosis.ts +192 -0
  307. package/src/kit/mount-failure-report.ts +154 -0
  308. package/src/kit/native-selection-style.ts +497 -0
  309. package/src/kit/object3d-document-write-policy.ts +137 -0
  310. package/src/kit/packaged-runtime.ts +108 -0
  311. package/src/kit/palettes/maya.palette.json +57 -0
  312. package/src/kit/palettes/substance.palette.json +57 -0
  313. package/src/kit/performance-profiler.ts +367 -0
  314. package/src/kit/performance-sources.ts +69 -0
  315. package/src/kit/photograph-notice.ts +141 -0
  316. package/src/kit/play-boot-phase.ts +166 -0
  317. package/src/kit/play-camera-flight.ts +35 -0
  318. package/src/kit/png-encode.worker.ts +26 -0
  319. package/src/kit/presentation-surface.ts +248 -0
  320. package/src/kit/product-command.ts +90 -0
  321. package/src/kit/project-adapter.ts +1140 -0
  322. package/src/kit/project-asset-refresh.ts +23 -0
  323. package/src/kit/project-asset-roots.ts +68 -0
  324. package/src/kit/project-local-state.ts +151 -0
  325. package/src/kit/project-manager.ts +243 -0
  326. package/src/kit/project-module-changes.ts +201 -0
  327. package/src/kit/project-module-split.ts +270 -0
  328. package/src/kit/project-play-layers.ts +25 -0
  329. package/src/kit/project-provenance.ts +115 -0
  330. package/src/kit/project-ready.ts +42 -0
  331. package/src/kit/project-shape.ts +68 -0
  332. package/src/kit/project-tools.ts +107 -0
  333. package/src/kit/projection-types.ts +44 -0
  334. package/src/kit/readiness.ts +113 -0
  335. package/src/kit/renderer-resource-counts.ts +27 -0
  336. package/src/kit/reported-play-state.ts +90 -0
  337. package/src/kit/resolve-contributed-command.ts +14 -0
  338. package/src/kit/resolve-relative-specifier.ts +33 -0
  339. package/src/kit/retained-document-states.ts +91 -0
  340. package/src/kit/scene-document-plan.ts +320 -0
  341. package/src/kit/scene-live-open.ts +210 -0
  342. package/src/kit/scoped-game-css.ts +152 -0
  343. package/src/kit/served-url.ts +5 -0
  344. package/src/kit/session-close.ts +17 -0
  345. package/src/kit/session-tombstone.ts +127 -0
  346. package/src/kit/settings/settings-provider.ts +82 -0
  347. package/src/kit/settings-store.ts +348 -0
  348. package/src/kit/shell-document-state.ts +27 -0
  349. package/src/kit/shell-store-door.ts +45 -0
  350. package/src/kit/shell-store.ts +722 -0
  351. package/src/kit/source-conflict.ts +122 -0
  352. package/src/kit/stage-context.ts +377 -0
  353. package/src/kit/stage-invalidation.ts +25 -0
  354. package/src/kit/stage-store-registry.ts +69 -0
  355. package/src/kit/startup-failure.ts +80 -0
  356. package/src/kit/state-report-deferral.ts +73 -0
  357. package/src/kit/storage/host-files-storage.ts +97 -0
  358. package/src/kit/storage/http-storage.ts +174 -0
  359. package/src/kit/storage/index.ts +75 -0
  360. package/src/kit/storage/mem-storage.ts +158 -0
  361. package/src/kit/storage/path-lock.ts +44 -0
  362. package/src/kit/storage/paths.ts +26 -0
  363. package/src/kit/storage-types.ts +127 -0
  364. package/src/kit/stories/StoryPreviewMount.tsx +306 -0
  365. package/src/kit/stories/compose-project-stories.ts +255 -0
  366. package/src/kit/stories/prefabs-finder.ts +54 -0
  367. package/src/kit/stories/prefabs-from-stories.ts +182 -0
  368. package/src/kit/stories/project-story-regions.ts +24 -0
  369. package/src/kit/stories/story-capture.ts +579 -0
  370. package/src/kit/stories/story-declared-medium.ts +126 -0
  371. package/src/kit/stories/story-discovery.ts +176 -0
  372. package/src/kit/stories/story-dom-runtime.ts +78 -0
  373. package/src/kit/stories/story-grouping.ts +111 -0
  374. package/src/kit/stories/story-mount-turn.ts +27 -0
  375. package/src/kit/stories/story-presentation.ts +215 -0
  376. package/src/kit/stories/story-preview-component.ts +7 -0
  377. package/src/kit/stories/story-registry.ts +530 -0
  378. package/src/kit/stories-scope.ts +35 -0
  379. package/src/kit/story-document-openers.ts +36 -0
  380. package/src/kit/story-thumbnails.ts +47 -0
  381. package/src/kit/surface-keyboard.ts +101 -0
  382. package/src/kit/surface-state.ts +135 -0
  383. package/src/kit/system-seam-evidence.ts +72 -0
  384. package/src/kit/tab-census.ts +202 -0
  385. package/src/kit/tab-lifecycle-client.ts +227 -0
  386. package/src/kit/theme-library.ts +897 -0
  387. package/src/kit/theme-preference.ts +429 -0
  388. package/src/kit/three-viewport-presentation.ts +23 -0
  389. package/src/kit/tool-contribution-play.ts +74 -0
  390. package/src/kit/tool-loader.ts +1918 -0
  391. package/src/kit/transform-mode-request.ts +66 -0
  392. package/src/kit/transient-hint.ts +78 -0
  393. package/src/kit/transport-strip.tsx +174 -0
  394. package/src/kit/ui-source/adapter-region-includes.ts +238 -0
  395. package/src/kit/ui-source/file-region-resolver.ts +302 -0
  396. package/src/kit/ui-source/inspect.ts +775 -0
  397. package/src/kit/ui-source/source-write-backend.ts +605 -0
  398. package/src/kit/ui-source/tier-source-write-backend.ts +279 -0
  399. package/src/kit/user-local-state.ts +105 -0
  400. package/src/kit/viewport-activation-timings.ts +840 -0
  401. package/src/kit/viewport-editor-controls.ts +22 -0
  402. package/src/kit/viewport-presentation.ts +668 -0
  403. package/src/kit/viewport-surface-status.tsx +55 -0
  404. package/src/kit/wait-until.ts +37 -0
  405. package/src/kit/worker-call-metrics.ts +166 -0
  406. package/src/kit/workspace-areas.ts +191 -0
  407. package/src/kit/workspace-aux-commands.ts +11 -0
  408. package/src/kit/workspace-available-documents.ts +142 -0
  409. package/src/kit/workspace-core-utilities.ts +31 -0
  410. package/src/kit/workspace-document-ids.ts +59 -0
  411. package/src/kit/workspace-document-registry.ts +624 -0
  412. package/src/kit/workspace-document-restore.ts +146 -0
  413. package/src/kit/workspace-host-commands.ts +141 -0
  414. package/src/kit/workspace-persistence-gate.ts +40 -0
  415. package/src/kit/workspace-play-utilities.ts +44 -0
  416. package/src/kit/workspace-presets.ts +446 -0
  417. package/src/kit/workspace-regions.ts +276 -0
  418. package/src/kit/workspace-static-panels.ts +73 -0
  419. package/src/kit/workspace-status-registry.ts +121 -0
  420. package/src/kit/workspace-storage.ts +35 -0
  421. package/src/kit/workspace-style.ts +226 -0
  422. package/src/kit/workspace-utility-commands.ts +74 -0
  423. package/src/kit/workspace-utility-registry.ts +263 -0
  424. package/src/kit/world-adoption-event.ts +23 -0
  425. package/src/kit/world-adoption.ts +115 -0
  426. package/src/kit/world-canvas-viewport-state.ts +35 -0
  427. package/src/kit/world-document-routing.ts +104 -0
  428. package/src/kit/world-pan-state.ts +198 -0
  429. package/src/kit/write-pipe.ts +173 -0
  430. package/src/layout-arrangements.ts +5 -0
  431. package/src/layouts.tsx +108 -0
  432. package/src/looks.ts +16 -0
  433. package/src/project/output-roots.ts +73 -0
  434. package/src/project/tab-census.ts +155 -0
  435. package/src/project-tool-catalog.ts +104 -0
  436. package/src/selection.tsx +107 -0
  437. package/src/services.ts +18 -0
  438. package/src/session/build-report.ts +22 -0
  439. package/src/session/collaboration-types.ts +262 -0
  440. package/src/session/command-table.ts +327 -0
  441. package/src/session/discovery.ts +100 -0
  442. package/src/session/editor-brand.ts +48 -0
  443. package/src/session/editor-compatibility.ts +329 -0
  444. package/src/session/editor-control-lifecycle.ts +68 -0
  445. package/src/session/editor-control-protocol.ts +5 -0
  446. package/src/session/entrypoint-selection-readers.ts +66 -0
  447. package/src/session/entrypoint-selection-source.ts +120 -0
  448. package/src/session/game-css-scope.ts +30 -0
  449. package/src/session/hosted-attachment.ts +225 -0
  450. package/src/session/limited-view.ts +82 -0
  451. package/src/session/product-create.ts +24 -0
  452. package/src/session/product-locator.ts +478 -0
  453. package/src/session/project-module-url.ts +242 -0
  454. package/src/session/project-serving.ts +164 -0
  455. package/src/session/project-upgrade.ts +669 -0
  456. package/src/session/registry-format.ts +210 -0
  457. package/src/session/relative-path-guard.ts +56 -0
  458. package/src/session/scoped-game-css.ts +461 -0
  459. package/src/session/source-glob.ts +15 -0
  460. package/src/session/tool-contribution-convention.ts +123 -0
  461. package/src/session/workbench-locator.ts +712 -0
  462. package/src/session.ts +41 -0
  463. package/src/share.ts +160 -0
  464. package/src/source-analysis.ts +28 -0
  465. package/src/source-authoring.ts +439 -0
  466. package/src/tools/errors.ts +91 -0
  467. package/src/tools/provider-execution.ts +70 -0
  468. package/src/tools/registry.ts +341 -0
  469. package/src/tools/types.ts +159 -0
  470. package/src/transport.ts +100 -0
  471. package/src/types.ts +1693 -0
  472. package/src/views.ts +164 -0
  473. package/src/widgets/design-system.ts +93 -0
  474. package/src/widgets/editor-appearance.ts +151 -0
  475. package/src/widgets/editor-material.ts +83 -0
  476. package/src/widgets/icon-set-registry.ts +105 -0
  477. package/src/widgets/index.ts +71 -0
  478. package/src/widgets/inspector-widgets/AlignmentGrid.tsx +182 -0
  479. package/src/widgets/inspector-widgets/AssetSlotPicker.tsx +123 -0
  480. package/src/widgets/inspector-widgets/BorderEditor.tsx +309 -0
  481. package/src/widgets/inspector-widgets/ColorPicker.tsx +549 -0
  482. package/src/widgets/inspector-widgets/CurveEditor.tsx +359 -0
  483. package/src/widgets/inspector-widgets/FilterEditor.tsx +108 -0
  484. package/src/widgets/inspector-widgets/FontPicker.tsx +191 -0
  485. package/src/widgets/inspector-widgets/GradientEditor.tsx +623 -0
  486. package/src/widgets/inspector-widgets/ScrubbableInput.tsx +180 -0
  487. package/src/widgets/inspector-widgets/ShadowEditor.tsx +319 -0
  488. package/src/widgets/inspector-widgets/color-utils.ts +201 -0
  489. package/src/widgets/inspector-widgets/curve-utils.ts +212 -0
  490. package/src/widgets/inspector-widgets/index.ts +25 -0
  491. package/src/widgets/inspector-widgets/shared.tsx +140 -0
  492. package/src/widgets/interactive-edit-scope.ts +33 -0
  493. package/src/widgets/patterns/Dialog.tsx +140 -0
  494. package/src/widgets/patterns/Fields.tsx +44 -0
  495. package/src/widgets/patterns/List.tsx +25 -0
  496. package/src/widgets/patterns/StateSurface.tsx +40 -0
  497. package/src/widgets/patterns/Surfaces.tsx +122 -0
  498. package/src/widgets/patterns/Tabs.tsx +80 -0
  499. package/src/widgets/patterns/Toolbar.tsx +72 -0
  500. package/src/widgets/patterns/Tree.tsx +72 -0
  501. package/src/widgets/primitives/AnchoredMenu.tsx +260 -0
  502. package/src/widgets/primitives/Button.tsx +62 -0
  503. package/src/widgets/primitives/ColorInput.tsx +78 -0
  504. package/src/widgets/primitives/DraftTextInput.tsx +63 -0
  505. package/src/widgets/primitives/EditorIcon.tsx +157 -0
  506. package/src/widgets/primitives/FormControls.tsx +88 -0
  507. package/src/widgets/primitives/HoverPreview.tsx +96 -0
  508. package/src/widgets/primitives/JsonInput.tsx +113 -0
  509. package/src/widgets/primitives/Layout.tsx +100 -0
  510. package/src/widgets/primitives/Menu.tsx +161 -0
  511. package/src/widgets/primitives/NumberInput.tsx +169 -0
  512. package/src/widgets/primitives/Panel.tsx +80 -0
  513. package/src/widgets/primitives/SectionHeader.tsx +77 -0
  514. package/src/widgets/primitives/Text.tsx +54 -0
  515. package/src/widgets/primitives/ThemeRootPortal.tsx +52 -0
  516. package/src/widgets/primitives/Tooltip.tsx +204 -0
  517. package/src/widgets/primitives/Vec3Input.tsx +70 -0
  518. package/src/widgets/primitives/banner-tones.ts +32 -0
  519. package/src/widgets/primitives/clamp-to-viewport.ts +44 -0
  520. package/src/widgets/primitives/editor-icons.ts +254 -0
  521. package/src/widgets/primitives/panel-header-styles.ts +42 -0
  522. package/src/widgets/theme.ts +2841 -0
  523. package/src/widgets/z-index.ts +25 -0
@@ -0,0 +1,580 @@
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 the editor's `console` command PRINTS ARE ONE SET.
5
+ * The status bar, the Console panel and the Console utility's badge all read
6
+ * this store; the editor's `console` command 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 the editor's `console` command 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.__volter*`
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 { __volterEditorConsole?: EditorConsole })['__volterEditorConsole'] =
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
+ // An Error prints with its stack, as the browser's own console prints one: the throw that
207
+ // explains a failure is only useful where it says where it threw.
208
+ // Duck-typed: an Error from the game's own realm is not `instanceof` this one's.
209
+ const error = value as { stack?: unknown; message?: unknown } | null;
210
+ if (
211
+ typeof value === 'object' &&
212
+ error !== null &&
213
+ typeof error.stack === 'string' &&
214
+ error.stack !== '' &&
215
+ typeof error.message === 'string'
216
+ ) {
217
+ return error.stack.includes(error.message) ? error.stack : `${String(value)}\n${error.stack}`;
218
+ }
219
+ return String(value);
220
+ } catch {
221
+ return Object.prototype.toString.call(value);
222
+ }
223
+ }
224
+
225
+ /** Object rendering for the directives that ask for one (`%o`, `%O`, `%j`).
226
+ * Circular-safe and bounded — see `INSPECT_CAP`. */
227
+ function inspectArg(value: unknown): string {
228
+ if (typeof value !== 'object' || value === null) return safeString(value);
229
+ const seen = new WeakSet<object>();
230
+ let json: string | undefined;
231
+ try {
232
+ json = JSON.stringify(value, (_key, val) => {
233
+ if (typeof val !== 'object' || val === null) return val;
234
+ if (seen.has(val)) return '[Circular]';
235
+ seen.add(val);
236
+ return val;
237
+ });
238
+ } catch {
239
+ json = undefined;
240
+ }
241
+ if (json === undefined) return safeString(value);
242
+ return json.length > INSPECT_CAP ? `${json.slice(0, INSPECT_CAP)}…` : json;
243
+ }
244
+
245
+ /**
246
+ * Render `console.error(...)`-style arguments the way the console itself does:
247
+ * interpolate the format directives in a leading format string against the
248
+ * following arguments, then append whatever arguments are left over,
249
+ * space-separated.
250
+ *
251
+ * Why this exists rather than `args.map(String).join(' ')`: React logs with
252
+ * printf-style format strings, so the naive join stored
253
+ * "React does not recognize the `%s` prop on a DOM element…" with `%s`
254
+ * UNINTERPOLATED and the prop name riding in a later argument — which the
255
+ * summary's per-message truncation (`command-listener.ts`) then cut off
256
+ * entirely. the editor's `status` command is the one channel agents are told to trust, and it
257
+ * was delivering evidence with the identifying detail amputated.
258
+ *
259
+ * Behaviour follows the WHATWG console Formatter: directives are consumed
260
+ * left-to-right; a directive with no argument left is emitted literally; `%%`
261
+ * is an escaped percent and consumes nothing; `%c` consumes its argument and
262
+ * renders nothing (this store has no styling). A first argument that is not a
263
+ * string means no format string, so every argument is simply stringified.
264
+ */
265
+ export function formatConsoleArgs(args: readonly unknown[]): string {
266
+ if (args.length === 0) return '';
267
+ const [first, ...rest] = args;
268
+ if (typeof first !== 'string' || rest.length === 0) {
269
+ return args.map(safeString).join(' ');
270
+ }
271
+
272
+ let consumed = 0;
273
+ const head = first.replace(/%([sdifoOjc%])/g, (match, kind: string) => {
274
+ if (kind === '%') return '%';
275
+ if (consumed >= rest.length) return match;
276
+ const arg = rest[consumed++];
277
+ switch (kind) {
278
+ case 's':
279
+ return typeof arg === 'string' ? arg : safeString(arg);
280
+ case 'd':
281
+ case 'i': {
282
+ if (typeof arg === 'symbol') return 'NaN';
283
+ if (typeof arg === 'bigint') return String(arg);
284
+ const n = Number(arg);
285
+ return Number.isFinite(n) ? String(Math.trunc(n)) : String(n);
286
+ }
287
+ case 'f': {
288
+ if (typeof arg === 'symbol') return 'NaN';
289
+ return String(Number(arg));
290
+ }
291
+ case 'c':
292
+ return '';
293
+ default:
294
+ return inspectArg(arg);
295
+ }
296
+ });
297
+
298
+ const leftovers = rest.slice(consumed);
299
+ return leftovers.length === 0 ? head : `${head} ${leftovers.map(safeString).join(' ')}`;
300
+ }
301
+
302
+ /**
303
+ * React 19 prints a DEV warning's component tree through the browser's own
304
+ * console task stack, never as an argument — so a duplicate-key or
305
+ * setState-in-effect warning reached the editor's `console` command as one sentence with no
306
+ * hint of WHICH list. `captureOwnerStack()` is React's door to that tree and
307
+ * is only populated while React itself is calling `console.error`, which is
308
+ * exactly when this wrapper runs. Appended for React's warning shapes only;
309
+ * everything else keeps its exact message.
310
+ */
311
+ function withReactOwnerStack(args: readonly unknown[], message: string): string {
312
+ const first = args[0];
313
+ if (typeof first !== 'string') return message;
314
+ if (
315
+ !/^(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(
316
+ first,
317
+ )
318
+ ) {
319
+ return message;
320
+ }
321
+ try {
322
+ const stack = captureOwnerStack?.();
323
+ return stack ? `${message}\nOwner stack:${stack}` : message;
324
+ } catch {
325
+ return message;
326
+ }
327
+ }
328
+
329
+ /** Preserve the component and source evidence a render error already owns. */
330
+ export function formatAttributedError(
331
+ error: unknown,
332
+ options: { readonly source?: string; readonly componentStack?: string | null } = {},
333
+ ): string {
334
+ const message = error instanceof Error ? `${error.name}: ${error.message}` : safeString(error);
335
+ const parts = [options.source ? `[${options.source}] ${message}` : message];
336
+ const componentStack = options.componentStack?.trim();
337
+ if (componentStack) parts.push(`Component stack:\n${componentStack}`);
338
+ if (error instanceof Error && error.stack && error.stack !== message) {
339
+ parts.push(`JavaScript stack:\n${error.stack}`);
340
+ }
341
+ const formatted = parts.join('\n');
342
+ return formatted.length > ERROR_ATTRIBUTION_CAP
343
+ ? `${formatted.slice(0, ERROR_ATTRIBUTION_CAP)}…`
344
+ : formatted;
345
+ }
346
+
347
+ // --- Session-lifetime console capture ---
348
+
349
+ /**
350
+ * THE LAYERING (read this together with `play-mode.ts`'s
351
+ * `patchConsole()`/`unpatchConsole()` — the two patches are one design):
352
+ *
353
+ * 1. `installEditorConsoleCapture()` runs ONCE at editor boot (`main.tsx`) and
354
+ * wraps `console.error`/`console.warn` for the WHOLE session, tagging what
355
+ * it captures `'editor'`. Before it existed, play-mode's patch was the ONLY
356
+ * funnel from a raw `console.error` into this store — and it is installed at
357
+ * play START and removed at play STOP. So an editor-frame error outside play
358
+ * (measured: Content-tab story previews throwing `useRapier must be used
359
+ * within <Physics>`) reached this store never, and the editor's `status` command answered
360
+ * `consoleErrors: {count: 0}` to a console full of red.
361
+ * 2. Play-mode's patch is installed LATER, so it sits OUTSIDE this one: it
362
+ * captures whatever `console.error` currently is (this wrapper) as its
363
+ * "original" and calls through to it. While a run is live play's patch OWNS
364
+ * the funnel — it tags `'game'`, which is the more specific and more useful
365
+ * answer — so this wrapper suspends its own store push for the duration and
366
+ * only forwards to the native console. One error, ONE entry, source
367
+ * `'game'`. `unpatchConsole()` resumes it, and session-lifetime capture
368
+ * picks straight back up.
369
+ *
370
+ * Uncaught page errors (`window.onerror`/`unhandledrejection`) are the other
371
+ * half of the same job and are captured here too, tagged `'runtime'` — the
372
+ * source `command-listener.ts`'s `collectPageErrors` reads. They live at boot
373
+ * rather than on the viewport panel so an error thrown BEFORE the viewport
374
+ * mounts is still recorded, and so there is exactly one owner of the listeners
375
+ * for the session's whole life.
376
+ */
377
+ /**
378
+ * WHO IS SPEAKING, when a raw `console.error`/`warn` fires — asked, never
379
+ * named.
380
+ *
381
+ * The console is a SINK the shell feeds; the closure ratchet's own rule is
382
+ * that a surface below the shell never imports the shell's world adapters
383
+ * (`scripts/validate-editor-closure.mjs`'s header). It was importing one:
384
+ * `currentGameRealmMountId` from `gated-globals.ts` pulled the whole game
385
+ * REALM SHIM — the page-in-a-box, its storage facade, its navigation guard and
386
+ * its loop gate — into this surface's pinned closure, so 7 of the console's 8
387
+ * files were the game realm and a Blender-only build's console carried a
388
+ * game's page shim (measured 2026-09-18, phase 1 of the open-source launch).
389
+ *
390
+ * The realm is the thing that knows a realm is running, so the realm
391
+ * REGISTERS its reader here (`gated-globals.ts`, at module scope: any realm
392
+ * existing implies that module loaded, so the registration cannot be late for
393
+ * a message the realm itself produced). One named slot rather than a list,
394
+ * because there is exactly one realm shim and a second claimant would be a
395
+ * design decision, not a registration.
396
+ */
397
+ let _realmAttribution: (() => string | null) | null = null;
398
+
399
+ /** Publish the "which realm is synchronously executing?" reader. */
400
+ export function setConsoleRealmAttribution(read: () => string | null): void {
401
+ _realmAttribution = read;
402
+ }
403
+
404
+ let _nativeConsoleError: typeof console.error | null = null;
405
+ let _nativeConsoleWarn: typeof console.warn | null = null;
406
+ let _captureSuspensions = 0;
407
+
408
+ /** Play-mode's patch takes precedence while a run is live — see the layering
409
+ * note above. Paired with `resumeEditorConsoleCapture`; counted rather than
410
+ * boolean so a nested/retried patch cannot leave capture off forever. */
411
+ export function suspendEditorConsoleCapture(): void {
412
+ _captureSuspensions++;
413
+ }
414
+
415
+ export function resumeEditorConsoleCapture(): void {
416
+ if (_captureSuspensions > 0) _captureSuspensions--;
417
+ }
418
+
419
+ /** Test-only: whether the session-lifetime capture is currently pushing to the
420
+ * store. Exists so the layering above is assertable without reaching into
421
+ * module privates. */
422
+ export function isEditorConsoleCaptureActive(): boolean {
423
+ return _nativeConsoleError !== null && _captureSuspensions === 0;
424
+ }
425
+
426
+ /**
427
+ * Install the session-lifetime capture. Idempotent; returns a teardown that
428
+ * restores the native console and removes the page-error listeners.
429
+ */
430
+ export function installEditorConsoleCapture(): () => void {
431
+ if (_nativeConsoleError) return () => {};
432
+ const nativeError = console.error;
433
+ const nativeWarn = console.warn;
434
+ _nativeConsoleError = nativeError;
435
+ _nativeConsoleWarn = nativeWarn;
436
+
437
+ /**
438
+ * A raw console call is the GAME's statement when game-realm code is
439
+ * synchronously executing. The registered realm attribution above is the
440
+ * door built for exactly this label (`gated-globals.ts`'s
441
+ * `currentGameRealmMountId` — the realm's contextual console runs every
442
+ * method `inRealm`), and play-mode's patch already reads it — but
443
+ * a game's module-scope warns fire at graph EVALUATION (racing's Supabase
444
+ * client is the measured case), which happens at mount, before any play run
445
+ * installs that patch. Without this read, every such row landed in the
446
+ * ledger as editor-owned noise, telling an agent to fix editor code for a
447
+ * warning the game's own library printed. The label changes; the loudness
448
+ * does not — a game-sourced warning lands in the unresolved set exactly like
449
+ * an editor one (severity decides, never source), because exempting a
450
+ * source would teach the gate to find less. What that set gates differs by
451
+ * severity: since editor#129 the CLI (`control.ts`) exits 1 only for an
452
+ * unresolved ERROR, in both editors; a warning prints to stderr and exits 0.
453
+ * So the game template's "`console` must be silent" step holds for warnings
454
+ * only through that stderr output, never through the exit code.
455
+ */
456
+ const captured = (level: 'error' | 'warn', args: unknown[]): void => {
457
+ if (_captureSuspensions !== 0) return;
458
+ const realmMountId = _realmAttribution?.() ?? null;
459
+ if (realmMountId !== null) {
460
+ // `''` is the DEFAULT game realm (every ingest mount) — still the game's
461
+ // statement, just not a named multi-instance mount.
462
+ editorConsole.logStructured(
463
+ level,
464
+ formatConsoleArgs(args),
465
+ 'game',
466
+ undefined,
467
+ realmMountId ? { instanceId: realmMountId } : undefined,
468
+ );
469
+ return;
470
+ }
471
+ editorConsole.logStructured(
472
+ level,
473
+ withReactOwnerStack(args, formatConsoleArgs(args)),
474
+ 'editor',
475
+ );
476
+ };
477
+
478
+ console.error = (...args: unknown[]) => {
479
+ nativeError.apply(console, args);
480
+ captured('error', args);
481
+ };
482
+ console.warn = (...args: unknown[]) => {
483
+ nativeWarn.apply(console, args);
484
+ captured('warn', args);
485
+ };
486
+
487
+ const onError = (e: ErrorEvent) => {
488
+ const source = e.filename
489
+ ? `${e.filename}${e.lineno ? `:${e.lineno}${e.colno ? `:${e.colno}` : ''}` : ''}`
490
+ : undefined;
491
+ editorConsole.error(
492
+ formatAttributedError(e.error ?? e.message, source ? { source } : undefined),
493
+ 'runtime',
494
+ );
495
+ };
496
+ const onUnhandledRejection = (e: PromiseRejectionEvent) => {
497
+ // A CANCELLATION IS NOT AN ERROR, and this is the one exception the
498
+ // severity-decides-never-source doctrine above admits — because it is not
499
+ // about source. `cancellation-reason.ts` carries the whole reasoning and
500
+ // the measurement (the Code-OSS frame's `Canceled: Canceled`); the short
501
+ // version is that an operation which was asked to stop and did is what
502
+ // `AbortError` and `CancellationError` MEAN, for our code and anyone
503
+ // else's, and a page-level listener cannot ask whose it was.
504
+ if (isCancellationReason(e.reason)) return;
505
+ editorConsole.error(
506
+ `Unhandled promise rejection: ${formatAttributedError(e.reason)}`,
507
+ 'runtime',
508
+ );
509
+ };
510
+ const hasWindow = typeof window !== 'undefined';
511
+ if (hasWindow) {
512
+ window.addEventListener('error', onError);
513
+ window.addEventListener('unhandledrejection', onUnhandledRejection);
514
+ }
515
+
516
+ return () => {
517
+ if (_nativeConsoleError) console.error = _nativeConsoleError;
518
+ if (_nativeConsoleWarn) console.warn = _nativeConsoleWarn;
519
+ _nativeConsoleError = null;
520
+ _nativeConsoleWarn = null;
521
+ _captureSuspensions = 0;
522
+ if (hasWindow) {
523
+ window.removeEventListener('error', onError);
524
+ window.removeEventListener('unhandledrejection', onUnhandledRejection);
525
+ }
526
+ };
527
+ }
528
+
529
+ /**
530
+ * Listen for `console-bridge` postMessage events from a game's own console
531
+ * bridge and pipe them into the editor console.
532
+ */
533
+ const BRIDGE_LEVEL_MAP: Record<string, ConsoleLevel> = {
534
+ log: 'info',
535
+ warn: 'warn',
536
+ error: 'error',
537
+ };
538
+
539
+ /** LogLevel string → ConsoleLevel for engine-log messages. */
540
+ const ENGINE_LEVEL_MAP: Record<string, ConsoleLevel> = {
541
+ trace: 'info',
542
+ debug: 'info',
543
+ info: 'info',
544
+ warn: 'warn',
545
+ error: 'error',
546
+ fatal: 'error',
547
+ };
548
+
549
+ // Same `window` guard as the test hook above — see the comment there.
550
+ if (typeof window !== 'undefined') {
551
+ window.addEventListener('message', (e: MessageEvent) => {
552
+ // Structured engine-log messages (from engine logger)
553
+ if (e.data?.type === 'engine-log') {
554
+ const level = ENGINE_LEVEL_MAP[e.data.level];
555
+ if (!level) return;
556
+ editorConsole.logStructured(
557
+ level,
558
+ e.data.message,
559
+ 'engine',
560
+ e.data.subsystem,
561
+ e.data.metadata,
562
+ );
563
+ return;
564
+ }
565
+
566
+ // Plain console-bridge messages (from game code)
567
+ if (e.data?.type === 'console-bridge') {
568
+ const level = BRIDGE_LEVEL_MAP[e.data.level];
569
+ if (!level) return;
570
+ editorConsole[level === 'info' ? 'log' : level](e.data.message, 'engine');
571
+ }
572
+ });
573
+ }
574
+
575
+ /** Render one `server-log` payload — live or replayed — into the console. */
576
+ export function emitServerLogEntry(entry: { level: string; message: string }): void {
577
+ const level = BRIDGE_LEVEL_MAP[entry.level];
578
+ if (!level) return;
579
+ editorConsole[level === 'info' ? 'log' : level](entry.message, 'server');
580
+ }
@@ -0,0 +1,56 @@
1
+ import { type EditorView, editorViewUrl, isEditorViewUtility } from '@volter/sdk';
2
+ import { documentViewport } from '@volter/sdk/kit/document-viewports';
3
+ import type { ShellStore } from '@volter/sdk/kit/shell-store';
4
+ import { activeEditorKeymap } from '@volter/sdk/kit/keymap-presets';
5
+ import {
6
+ activeWorkspaceDocument,
7
+ activeWorkspaceDocumentSelection,
8
+ } from '@volter/sdk/kit/workspace-document-registry';
9
+ import { activeWorkspaceStaticPanel, activeWorkspaceUtility } from '@volter/sdk/kit/workspace-host-commands';
10
+ import { activeEditorWorkspace } from '@volter/sdk/kit/workspace-presets';
11
+ import { activeWorkspaceStyleId } from '@volter/sdk/kit/workspace-style';
12
+
13
+ /** Inverse of `revealUtility` (editor-view-presentation.ts): map the live
14
+ * utility id back into `@volter/sdk`'s public link vocabulary — one of
15
+ * the editor's own named instruments, or a `tool:` tab a package or the open
16
+ * project contributes. A live utility the vocabulary cannot name (the story
17
+ * addons) reads as no utility rather than as a fabricated one. */
18
+ function presentedUtility(): EditorView['utility'] {
19
+ const utility = activeWorkspaceUtility();
20
+ return utility && isEditorViewUtility(utility) ? utility : undefined;
21
+ }
22
+
23
+ /** Derive the projection from live document/session state. This is the
24
+ * inverse of presentEditorView, not a cache of the last agent request. */
25
+ export function currentEditorView(store: ShellStore): EditorView {
26
+ const active = activeWorkspaceDocument();
27
+ const document = active?.descriptor.presentation?.() ?? undefined;
28
+ // The stage showing the active document answers for its viewport
29
+ // (`@volter/sdk/kit/document-viewports`), and for its selection when
30
+ // it keeps its own; a document with no viewport has neither.
31
+ const stage = documentViewport(active?.descriptor.id);
32
+ const documentSelection = activeWorkspaceDocumentSelection();
33
+ const selected = stage?.selection
34
+ ? stage.selection.read()
35
+ : (documentSelection?.adapter?.selection?.get() ?? (stage ? [...store.selectedEntityIds] : []));
36
+ const viewport: EditorView['viewport'] = stage?.read() ?? undefined;
37
+ const utility = presentedUtility();
38
+ // The static panel holding the dock's focus, straight from the dock's own
39
+ // active-panel readout — the inverse of `revealStaticPanel`.
40
+ const panel = activeWorkspaceStaticPanel();
41
+ return {
42
+ version: 1,
43
+ workspace: activeEditorWorkspace(),
44
+ ...(activeWorkspaceStyleId() === null ? {} : { style: activeWorkspaceStyleId() as string }),
45
+ keymap: activeEditorKeymap(),
46
+ ...(document ? { document } : {}),
47
+ ...(selected.length > 0 ? { selection: { ids: [...selected] } } : {}),
48
+ ...(viewport ? { viewport } : {}),
49
+ ...(panel ? { panel } : {}),
50
+ ...(utility ? { utility } : {}),
51
+ };
52
+ }
53
+
54
+ export function currentEditorViewUrl(store: ShellStore): string {
55
+ return editorViewUrl(currentEditorView(store), window.location.href);
56
+ }