@volter/sdk 0.0.0-stage → 0.5.203

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 +1166 -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 +317 -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 +403 -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,226 @@
1
+ /**
2
+ * Workspace STYLE BUNDLES (Glass-UI spike, Unit 3, "New named style using
3
+ * existing axes" row).
4
+ *
5
+ * Named one-shot presets over PALETTE + MATERIAL + ICONS: how things are DRAWN, and nothing
6
+ * else (ARCHITECTURE.md rule 7). The axes stay independently selectable; choosing a named style
7
+ * intentionally restores its canonical complete appearance. In particular, Classic must restore
8
+ * the original Graphite contract rather than inheriting a Glass palette. Which chrome regions
9
+ * exist is function — a workspace's (`workspace-regions.ts`), never a style's.
10
+ *
11
+ * Bundles are ONE-SHOT PRESETS, not a fifth stored axis: applying a bundle
12
+ * just calls the four existing axis setters, and this module keeps no store
13
+ * or persistence of its own. "Which bundle is active" is always DERIVED
14
+ * from their current values (`activeWorkspaceStyleId`) and can never
15
+ * disagree with them — e.g. after a user independently changes just the
16
+ * material, the derived id correctly falls back to `null` (a "custom" mix)
17
+ * rather than going stale.
18
+ */
19
+
20
+ import type { StyleContribution } from '@volter/sdk/looks';
21
+ import type { EditorMaterialId, EditorPalette } from '@volter/sdk/widgets';
22
+ import {
23
+ DEFAULT_ICON_SET_ID,
24
+ registerContributedIconSet,
25
+ registerContributedMaterial,
26
+ } from '@volter/sdk/widgets';
27
+ import { activeProduct, subscribeActiveProduct } from './active-product';
28
+ import { registerContributedPalette } from './theme-library';
29
+ import {
30
+ editorIconSetSnapshot,
31
+ editorMaterialSnapshot,
32
+ editorPaletteSnapshot,
33
+ setDefaultEditorAppearance,
34
+ setEditorIconSetPreference,
35
+ setEditorMaterialPreference,
36
+ setEditorPalettePreference,
37
+ } from './theme-preference';
38
+
39
+ export interface WorkspaceStyleBundle {
40
+ readonly id: string;
41
+ readonly title: string;
42
+ readonly paletteId: EditorPalette['id'];
43
+ readonly materialId: EditorMaterialId;
44
+ /** `icon-set-registry.ts`; `default` is the editor's own glyphs. */
45
+ readonly iconSetId: string;
46
+ }
47
+
48
+ /** Frozen built-in list — the switch surface (command palette / View menu)
49
+ * enumerates this directly. */
50
+ const BUILT_IN_STYLES: readonly WorkspaceStyleBundle[] = Object.freeze([
51
+ {
52
+ id: 'classic',
53
+ title: 'Classic',
54
+ paletteId: 'graphite-dark',
55
+ materialId: 'classic',
56
+ iconSetId: DEFAULT_ICON_SET_ID,
57
+ },
58
+ {
59
+ id: 'glass',
60
+ title: 'Glass',
61
+ paletteId: 'graphite-neutral',
62
+ materialId: 'glass',
63
+ iconSetId: DEFAULT_ICON_SET_ID,
64
+ },
65
+ {
66
+ id: 'maya',
67
+ title: 'Maya',
68
+ paletteId: 'maya',
69
+ materialId: 'classic',
70
+ iconSetId: DEFAULT_ICON_SET_ID,
71
+ },
72
+ {
73
+ id: 'substance',
74
+ title: 'Substance',
75
+ paletteId: 'substance',
76
+ materialId: 'classic',
77
+ iconSetId: DEFAULT_ICON_SET_ID,
78
+ },
79
+ ]);
80
+
81
+ interface ContributedStyle {
82
+ readonly bundle: WorkspaceStyleBundle;
83
+ readonly unregisterPalette: (() => void) | null;
84
+ readonly unregisterMaterial: (() => void) | null;
85
+ readonly unregisterIconSet: (() => void) | null;
86
+ }
87
+ const contributedStyles = new Map<string, ContributedStyle>();
88
+ let registryVersion = 0;
89
+ const registryListeners = new Set<() => void>();
90
+
91
+ /** Built-ins first, then contributions in registration order — the switch
92
+ * surfaces (View menu, palette) enumerate this. */
93
+ export function workspaceStyles(): readonly WorkspaceStyleBundle[] {
94
+ return [...BUILT_IN_STYLES, ...[...contributedStyles.values()].map((entry) => entry.bundle)];
95
+ }
96
+
97
+ export function workspaceStylesVersion(): number {
98
+ return registryVersion;
99
+ }
100
+
101
+ export function subscribeWorkspaceStyles(listener: () => void): () => void {
102
+ registryListeners.add(listener);
103
+ return () => registryListeners.delete(listener);
104
+ }
105
+
106
+ /**
107
+ * Register a package's style bundle (`workspace.style` contribution), with
108
+ * the palette document and the material it carries registered first — the
109
+ * bundle names their ids, and an id must exist before the bundle can be
110
+ * applied. Returns the unregister. A duplicate id throws.
111
+ */
112
+ export function registerContributedStyle(contribution: StyleContribution): () => void {
113
+ if (
114
+ BUILT_IN_STYLES.some((entry) => entry.id === contribution.id) ||
115
+ contributedStyles.has(contribution.id)
116
+ )
117
+ throw new Error(`registerContributedStyle: style "${contribution.id}" is already registered.`);
118
+ const unregisterPalette =
119
+ contribution.palette === undefined ? null : registerContributedPalette(contribution.palette);
120
+ const unregisterMaterial =
121
+ contribution.material === undefined ? null : registerContributedMaterial(contribution.material);
122
+ const unregisterIconSet =
123
+ contribution.icons === undefined ? null : registerContributedIconSet(contribution.icons);
124
+ const entry: ContributedStyle = {
125
+ bundle: {
126
+ id: contribution.id,
127
+ title: contribution.title,
128
+ paletteId: contribution.paletteId,
129
+ materialId: contribution.materialId,
130
+ iconSetId: contribution.iconSetId ?? contribution.icons?.id ?? DEFAULT_ICON_SET_ID,
131
+ },
132
+ unregisterPalette,
133
+ unregisterMaterial,
134
+ unregisterIconSet,
135
+ };
136
+ contributedStyles.set(contribution.id, entry);
137
+ registryVersion++;
138
+ for (const listener of registryListeners) listener();
139
+ // The product's look is usually one of these (the Blender look ships inside
140
+ // `@volter/editor-blender`), so the id it named only becomes resolvable here.
141
+ publishProductLook();
142
+ return () => {
143
+ if (contributedStyles.get(contribution.id) !== entry) return;
144
+ contributedStyles.delete(contribution.id);
145
+ entry.unregisterPalette?.();
146
+ entry.unregisterMaterial?.();
147
+ entry.unregisterIconSet?.();
148
+ registryVersion++;
149
+ for (const listener of registryListeners) listener();
150
+ publishProductLook();
151
+ };
152
+ }
153
+
154
+ /**
155
+ * THE PRODUCT'S LOOK, RESOLVED TO ITS AXES — the one thing this module does for
156
+ * a composition rather than for a gesture.
157
+ *
158
+ * A product names a style bundle id (`frame/product.ts`'s `look`); this is the
159
+ * module that knows what a bundle IS, so it resolves the id and pushes the
160
+ * palette/material/icons behind `theme-preference.ts`'s defaults. It runs on
161
+ * every registry change because a product's own look usually arrives as one of
162
+ * its packages' `workspace.style` contributions, which register a moment into
163
+ * the session — the Blender look is the worked case.
164
+ *
165
+ * It applies nothing and persists nothing: a bundle a person CHOOSES goes
166
+ * through {@link applyWorkspaceStyle}, which writes the preference. This is the
167
+ * floor under that.
168
+ */
169
+ function publishProductLook(): void {
170
+ const declared = activeProduct()?.look;
171
+ if (declared === undefined) {
172
+ setDefaultEditorAppearance(null);
173
+ return;
174
+ }
175
+ const bundle = workspaceStyles().find((entry) => entry.id === declared);
176
+ if (!bundle) return;
177
+ setDefaultEditorAppearance({
178
+ palette: bundle.paletteId,
179
+ material: bundle.materialId,
180
+ icons: bundle.iconSetId,
181
+ });
182
+ }
183
+
184
+ subscribeActiveProduct(publishProductLook);
185
+ publishProductLook();
186
+
187
+ /** Apply the three axes of the named bundle. Unknown ids are a silent no-op —
188
+ * callers (menu/command palette) only ever offer ids from {@link workspaceStyles}. */
189
+ export function applyWorkspaceStyle(id: string): void {
190
+ const bundle = workspaceStyles().find((entry) => entry.id === id);
191
+ if (!bundle) return;
192
+ setEditorPalettePreference(bundle.paletteId);
193
+ setEditorMaterialPreference(bundle.materialId);
194
+ setEditorIconSetPreference(bundle.iconSetId);
195
+ }
196
+
197
+ /** Each axis on which the chrome's current value differs from the bundle `id`'s, as
198
+ * `axis: wearing <value>, bundle <value>` — what a caller told "custom mix" needs to act on. */
199
+ export function workspaceStyleDifferences(id: string): string[] {
200
+ const bundle = workspaceStyles().find((entry) => entry.id === id);
201
+ if (!bundle) return [`no style bundle "${id}"`];
202
+ const rows: Array<[string, string, string]> = [
203
+ ['palette', editorPaletteSnapshot(), bundle.paletteId],
204
+ ['material', editorMaterialSnapshot(), bundle.materialId],
205
+ ['icons', editorIconSetSnapshot(), bundle.iconSetId],
206
+ ];
207
+ return rows
208
+ .filter(([, wearing, wanted]) => wearing !== wanted)
209
+ .map(([axis, wearing, wanted]) => `${axis}: wearing ${wearing}, bundle ${wanted}`);
210
+ }
211
+
212
+ /** The bundle id whose palette, material and icon set all match the
213
+ * current axis values, or `null` if the current combination isn't any
214
+ * registered bundle (a "custom" mix — always derived, never a separate
215
+ * stored state). */
216
+ export function activeWorkspaceStyleId(): string | null {
217
+ const paletteId = editorPaletteSnapshot();
218
+ const materialId = editorMaterialSnapshot();
219
+ const bundle = workspaceStyles().find(
220
+ (entry) =>
221
+ entry.paletteId === paletteId &&
222
+ entry.materialId === materialId &&
223
+ entry.iconSetId === editorIconSetSnapshot()
224
+ );
225
+ return bundle?.id ?? null;
226
+ }
@@ -0,0 +1,74 @@
1
+ /** Semantic commands and failure auto-open policy for workspace utilities. */
2
+
3
+ import { getMountFailureReports, subscribeToMountFailures } from '@volter/sdk/kit/mount-failure-report';
4
+ import { editorConsole } from '@volter/sdk/kit/editor-console';
5
+ import type { HistoryService } from '@volter/sdk/kit/history/history-service';
6
+ import { showWorkspaceUtility, toggleWorkspaceUtility } from '@volter/sdk/kit/workspace-host-commands';
7
+ import { activeChromeRegions } from '@volter/sdk/kit/workspace-regions';
8
+
9
+ export const CONSOLE_UTILITY_ID = 'console';
10
+
11
+ /**
12
+ * Only actionable failures open a utility automatically.
13
+ *
14
+ * A world that did not mount is the most actionable failure the editor has —
15
+ * the project is showing something that is not the game — and revealing the
16
+ * Console (where every mount route already wrote its full line) is what keeps
17
+ * it LOUD without a second error surface. This replaced a top-of-shell red
18
+ * banner: the reveal, not the banner, is the answer to "the Console is not
19
+ * the default bottom tab". Fires on the empty→failing EDGE only, so a second
20
+ * failing world in the same attempt does not yank the region back.
21
+ *
22
+ * Source persistence failures arrive through the project history that guarded
23
+ * and rolled back the write. Watch its failure EDGE directly: this keeps the
24
+ * Console reveal format-neutral and avoids a second adapter-specific event.
25
+ *
26
+ * A workspace whose regions HIDE the drawer (Blender's modeling workspace has
27
+ * no strip below the viewport) is never yanked open by this policy: the
28
+ * status bar's error count stays the loud surface there, and a person's own
29
+ * gesture (a failure item, View → Console) still reveals it.
30
+ */
31
+ export function installUtilityAutoOpen(history: HistoryService): () => void {
32
+ let hadMountFailure = getMountFailureReports().length > 0;
33
+ const stopMountFailures = subscribeToMountFailures(() => {
34
+ const failing = getMountFailureReports().length > 0;
35
+ if (failing && !hadMountFailure && activeChromeRegions().drawer !== 'hidden')
36
+ showWorkspaceUtility(CONSOLE_UTILITY_ID);
37
+ hadMountFailure = failing;
38
+ });
39
+
40
+ let hadSourceFailure = history.getSnapshot().lastError !== null;
41
+ const stopHistory = history.subscribe(() => {
42
+ const error = history.getSnapshot().lastError;
43
+ const failing = error !== null;
44
+ if (failing && !hadSourceFailure) {
45
+ // The one place every rolled-back write is named for the DOOR: the
46
+ // screen narrates it (a toast, the document's own message), and
47
+ // the editor's `console` command must say the same — measured silent before this line.
48
+ editorConsole.error(`Source write rolled back: ${error.message} (${error.code})`, 'history');
49
+ if (activeChromeRegions().drawer !== 'hidden') showWorkspaceUtility(CONSOLE_UTILITY_ID);
50
+ }
51
+ hadSourceFailure = failing;
52
+ });
53
+
54
+ return () => {
55
+ stopMountFailures();
56
+ stopHistory();
57
+ };
58
+ }
59
+
60
+ /** Toggle the Console utility — the semantic command every menu/hotkey/
61
+ * control-API caller invokes directly. It used to be reached through a
62
+ * `window` CustomEvent (`editor:toggle-console`) installed by
63
+ * `installUtilityEvents`; that indirection was a shell-era relay with no
64
+ * remaining second implementation, so it was deleted. */
65
+ export function toggleConsoleUtility(): void {
66
+ toggleWorkspaceUtility(CONSOLE_UTILITY_ID);
67
+ }
68
+
69
+ /** REVEAL the Console — what a failure item clicks through to. Distinct from
70
+ * {@link toggleConsoleUtility} on purpose: a user acting on a reported error
71
+ * must never have that click HIDE the panel holding the error's trace. */
72
+ export function showConsoleUtility(): void {
73
+ showWorkspaceUtility(CONSOLE_UTILITY_ID);
74
+ }
@@ -0,0 +1,263 @@
1
+ /**
2
+ * Workspace UTILITY registry (W0 — the shell-contract slice of §9 W0).
3
+ * Utilities are the TRANSIENT output/debug surfaces of §1.4/§5: Console,
4
+ * Problems, Build Output, Dev, and story-scoped addon results. They live in
5
+ * the on-demand bottom utility region — never substantial editors, which are
6
+ * documents (`workspace-document-registry.ts`).
7
+ *
8
+ * On-demand is about the TAB: a registration with no materialized tab has no
9
+ * presence at all. Once a tab EXISTS — pre-registered here, contributed by
10
+ * the open project, or introduced by background activity through
11
+ * `ensureWorkspaceUtility` — the region stays on screen COLLAPSED to its own
12
+ * tab strip, so the tab and its badge are discoverable while the body stays
13
+ * closed until the tab is clicked (the layout host owns that presentation).
14
+ *
15
+ * The layout host pre-registers default-visible tabs in a
16
+ * zero-footprint hidden host. Semantic commands and actionable failures reveal
17
+ * that host directly. Other registrations
18
+ * are created on demand (built-ins register via
19
+ * `components/core-utilities.tsx`; migration map).
20
+ *
21
+ * Registrations declare a `section` (`core` | `project`, default `core`) —
22
+ * the editor's own instruments versus the open game's plane. It is the OUTER
23
+ * sort key, so the drawer's tab strip renders the two as visually separated
24
+ * clusters (`utilitySectionBoundaryId` names the divider's position). It is
25
+ * presentation within the one bottom group; it is not a second dock.
26
+ *
27
+ * Idioms mirror `inspector-section-registry.ts`: module-scope state,
28
+ * `useSyncExternalStore`-shaped subscribe + monotonic version,
29
+ * `__resetForTest`, pure-logic headless tests (`Content` is never rendered
30
+ * here). Unlike that registry, utility ids KEY tabs (test ids, persisted
31
+ * drawer state), so duplicate registration is a programming error and
32
+ * throws.
33
+ */
34
+
35
+ import type { ComponentType } from 'react';
36
+
37
+ /** Attention badge a utility surfaces when its host is open; persistent
38
+ * signals such as Console errors are also projected into the status bar. */
39
+ export interface WorkspaceUtilityBadge {
40
+ readonly count: number;
41
+ readonly severity: 'info' | 'warn' | 'error';
42
+ }
43
+
44
+ /**
45
+ * Which audience a utility belongs to, and therefore which cluster of the
46
+ * drawer's tab strip it sits in.
47
+ *
48
+ * - `core` — the EDITOR's own instruments (Console, Animation, Profiler,
49
+ * Network, Audio…). Present in every project.
50
+ * - `project` — the GAME's own plane: one tab per `workspace.utility` tool
51
+ * contribution the open project ships (`tool-loader.ts` registers them
52
+ * under `tool:<contributionId>`). Which tabs exist depends entirely on the
53
+ * open game, so this cluster is empty for a project that contributes none.
54
+ */
55
+ export type WorkspaceUtilitySection = 'core' | 'project';
56
+
57
+ const SECTION_RANK: Record<WorkspaceUtilitySection, number> = { core: 0, project: 1 };
58
+
59
+ /** The §7 utility contribution contract. */
60
+ export interface WorkspaceUtilityRegistration {
61
+ /** Stable id — keys the drawer tab (`data-testid`, persisted layout). */
62
+ readonly id: string;
63
+ /** Tab label (§8 naming: `Build Output`, not `Build`). */
64
+ readonly title: string;
65
+ /** Tab-strip cluster. Default `'core'` — a contribution that says nothing
66
+ * is one of the editor's own instruments. */
67
+ readonly section?: WorkspaceUtilitySection;
68
+ /** React content host. Never rendered by the registry itself. */
69
+ readonly Content: ComponentType;
70
+ /** Tab order among registered utilities (ascending; ties keep
71
+ * registration order). Default `0`. */
72
+ readonly order?: number;
73
+ /** Session-scoped availability — e.g. Network exists only while a live
74
+ * session exposes the owning adapter (§5 "play-only bottom utility").
75
+ * Default: always available. */
76
+ readonly available?: () => boolean;
77
+ /** Optional attention badge for the tab (may return `null` for none). */
78
+ readonly badge?: () => WorkspaceUtilityBadge | null;
79
+ /** Subscribe to the source read by `badge()`. Dynamic badges must provide
80
+ * this together with `badgeSnapshot` so a dock tab updates while its panel
81
+ * is collapsed. */
82
+ readonly subscribeBadge?: (listener: () => void) => () => void;
83
+ /** Stable `useSyncExternalStore` snapshot for `subscribeBadge`. */
84
+ readonly badgeSnapshot?: () => number;
85
+ /** Whether the tab is pre-registered in the clean layout's hidden utility
86
+ * host. Defaults to `true`; this does not make the host itself visible.
87
+ * Event/output surfaces can remain discoverable while creating their tab
88
+ * only after an explicit command or relevant activity. */
89
+ readonly visibleByDefault?: boolean;
90
+ /** Whether a revealed utility tab may be closed. Defaults to `false`. */
91
+ readonly closeable?: boolean;
92
+ }
93
+
94
+ // --- Module-scope state (mirrors inspector-section-registry.ts) -----------
95
+
96
+ interface StoredUtility {
97
+ readonly registration: WorkspaceUtilityRegistration;
98
+ readonly seq: number;
99
+ }
100
+
101
+ let _utilities: StoredUtility[] = [];
102
+ let _seq = 0;
103
+ let _version = 0;
104
+ const _listeners = new Set<() => void>();
105
+
106
+ function notifyChanged(): void {
107
+ _version++;
108
+ for (const fn of _listeners) fn();
109
+ }
110
+
111
+ /** Subscribe to (un)registrations. Returns an unsubscribe function. */
112
+ export function subscribeWorkspaceUtilities(fn: () => void): () => void {
113
+ _listeners.add(fn);
114
+ return () => {
115
+ _listeners.delete(fn);
116
+ };
117
+ }
118
+
119
+ /** Monotonic change counter — the `getSnapshot` for `useSyncExternalStore`. */
120
+ export function workspaceUtilityRegistryVersion(): number {
121
+ return _version;
122
+ }
123
+
124
+ /**
125
+ * Register a utility contribution. Returns an unregister function.
126
+ * Throws on a duplicate id — utility ids key tabs and persisted layout, so
127
+ * two live registrations sharing one id is always a bug (re-registration
128
+ * flows, e.g. project-tool HMR, unregister first — tool-loader's own
129
+ * discipline).
130
+ */
131
+ export function registerWorkspaceUtility(registration: WorkspaceUtilityRegistration): () => void {
132
+ if (_utilities.some((u) => u.registration.id === registration.id)) {
133
+ throw new Error(
134
+ `registerWorkspaceUtility: id "${registration.id}" is already registered — ` +
135
+ 'utility ids key drawer tabs and persisted layout, so they must be unique; ' +
136
+ 'unregister the previous contribution first.',
137
+ );
138
+ }
139
+ const stored: StoredUtility = { registration, seq: _seq++ };
140
+ _utilities = [..._utilities, stored];
141
+ notifyChanged();
142
+ return () => {
143
+ if (!_utilities.includes(stored)) return;
144
+ _utilities = _utilities.filter((u) => u !== stored);
145
+ notifyChanged();
146
+ };
147
+ }
148
+
149
+ /** A registration's cluster, defaulting to the editor's own instruments. */
150
+ export function workspaceUtilitySection(
151
+ registration: WorkspaceUtilityRegistration,
152
+ ): WorkspaceUtilitySection {
153
+ return registration.section ?? 'core';
154
+ }
155
+
156
+ function sorted(): WorkspaceUtilityRegistration[] {
157
+ return [..._utilities]
158
+ .sort(
159
+ (a, b) =>
160
+ // Section is the OUTER key: the two clusters never interleave, so the
161
+ // tab strip's divider is a single boundary rather than a repeated one.
162
+ SECTION_RANK[workspaceUtilitySection(a.registration)] -
163
+ SECTION_RANK[workspaceUtilitySection(b.registration)] ||
164
+ (a.registration.order ?? 0) - (b.registration.order ?? 0) ||
165
+ a.seq - b.seq,
166
+ )
167
+ .map((u) => u.registration);
168
+ }
169
+
170
+ /**
171
+ * The id of the tab the `project` cluster STARTS at, for a given rendered tab
172
+ * order — i.e. the first project-section utility that some core-section
173
+ * utility precedes. `null` when the order has no such boundary (one cluster
174
+ * only, or the project cluster leads). Pure: the caller passes the list it is
175
+ * actually rendering, which after a user tab-drag need not be registry order.
176
+ */
177
+ export function utilitySectionBoundaryId(
178
+ utilities: readonly WorkspaceUtilityRegistration[],
179
+ ): string | null {
180
+ let sawCore = false;
181
+ for (const utility of utilities) {
182
+ if (workspaceUtilitySection(utility) === 'core') {
183
+ sawCore = true;
184
+ continue;
185
+ }
186
+ if (sawCore) return utility.id;
187
+ }
188
+ return null;
189
+ }
190
+
191
+ /**
192
+ * Where a NEWLY ADDED utility tab belongs among the tabs already in the
193
+ * drawer, per registry order — the count of existing tabs that sort at or
194
+ * before it. Registrations arrive at different times (core utilities at
195
+ * module init, project-tool contributions after the async tool load), so
196
+ * appending would interleave the clusters by arrival order; inserting at
197
+ * this index makes any arrival order converge to registry order. Ids the
198
+ * registry no longer knows (a stale persisted tab) sort AFTER every known
199
+ * one, and an unknown `id` appends. Pure: the caller passes the tab ids it
200
+ * is actually hosting, which after a user drag need not be registry order —
201
+ * rank-counting still yields a stable, in-bounds index there.
202
+ */
203
+ export function utilityInsertionIndex(
204
+ existingIds: readonly string[],
205
+ id: string,
206
+ ): number | undefined {
207
+ const rank = new Map(availableWorkspaceUtilities().map((utility, index) => [utility.id, index]));
208
+ const target = rank.get(id);
209
+ if (target === undefined) return undefined;
210
+ let index = 0;
211
+ for (const existing of existingIds) {
212
+ const existingRank = rank.get(existing);
213
+ if (existingRank !== undefined && existingRank <= target) index += 1;
214
+ }
215
+ return index;
216
+ }
217
+
218
+ /** Every registered utility, in (order, registration-sequence) order. */
219
+ export function registeredWorkspaceUtilities(): WorkspaceUtilityRegistration[] {
220
+ return sorted();
221
+ }
222
+
223
+ /** The registered utilities whose `available()` currently returns true
224
+ * (guarded: a THROWING `available` counts as unavailable — a broken
225
+ * contribution must not take the drawer down; same failure physics as
226
+ * tool-loader's match guard). */
227
+ export function availableWorkspaceUtilities(): WorkspaceUtilityRegistration[] {
228
+ return sorted().filter((u) => {
229
+ if (!u.available) return true;
230
+ try {
231
+ return u.available();
232
+ } catch {
233
+ return false;
234
+ }
235
+ });
236
+ }
237
+
238
+ /** Order-preserving fingerprint of the available utility ids — a stable
239
+ * STRING, so `useAvailabilitySelector` consumers (the dock's reconciler)
240
+ * re-render only when the available SET changes, not on every 250ms tick. */
241
+ export function availableUtilityFingerprint(): string {
242
+ return availableWorkspaceUtilities()
243
+ .map((u) => u.id)
244
+ .join('\n');
245
+ }
246
+
247
+ /** A utility's current badge (guarded: a throwing `badge` yields `null`). */
248
+ export function workspaceUtilityBadge(id: string): WorkspaceUtilityBadge | null {
249
+ const found = _utilities.find((u) => u.registration.id === id);
250
+ if (!found?.registration.badge) return null;
251
+ try {
252
+ return found.registration.badge();
253
+ } catch {
254
+ return null;
255
+ }
256
+ }
257
+
258
+ /** Test-only reset (mirrors `__resetInspectorSectionRegistryForTest`). */
259
+ export function __resetWorkspaceUtilityRegistryForTest(): void {
260
+ _utilities = [];
261
+ _seq = 0;
262
+ notifyChanged();
263
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * One world-adoption fact. `adopted` fires exactly once, when the trap commits
3
+ * to a (scene, camera, renderer) triple; `alternate` fires for each DISTINCT
4
+ * triple seen afterwards, up to the capture trap's `MAX_RECORDED_ALTERNATES`.
5
+ */
6
+ export type WorldAdoptionEvent =
7
+ | {
8
+ readonly phase: 'adopted';
9
+ /** `declared` = the contract named this scene; `measured` = first render won. */
10
+ readonly source: 'declared' | 'measured';
11
+ readonly sceneId: string;
12
+ readonly cameraId: string;
13
+ }
14
+ | {
15
+ readonly phase: 'alternate';
16
+ readonly sceneId: string;
17
+ readonly cameraId: string;
18
+ /** `false` ⇒ a SECOND renderer is drawing, which is the stronger signal. */
19
+ readonly sameRenderer: boolean;
20
+ /** Draws observed when this alternate first appeared — how far past the
21
+ * adoption it is, without a wall clock. */
22
+ readonly drawCount: number;
23
+ };