@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,668 @@
1
+ /**
2
+ * VIEWPORT PRESENTATION — what a 3D viewport DOES, as data: its draw mode, where the light on
3
+ * the model comes from, what is drawn behind the scene, which overlays show, how its tools
4
+ * behave and how its world is oriented. The ruling is
5
+ * `docs/VIEWPORT-STAGE.md` §The ruling (owner, 2026-09-25): the LOOK holds colours only (the
6
+ * palette's `color.viewport`), and light and environment are per-view settings a person toggles,
7
+ * as they are in every target — Blender's shading popover, Godot's Preview Sun and Environment,
8
+ * Unity's Scene-view lighting and skybox toggles.
9
+ *
10
+ * THIS MODULE IS MEDIUM-NEUTRAL (ARCHITECTURE.md rule 5). It names no Three type: a studio
11
+ * light is a colour, an intensity and a direction, and the viewport that draws in a medium
12
+ * applies it. It holds four things:
13
+ * - the TYPES of the four settings;
14
+ * - STUDIO PRESETS, the light rigs a `studio` lighting names by id (Blender's studio lights are
15
+ * data, `release/datafiles/studiolights/studio/*.sl`; so are ours);
16
+ * - STARTING VALUES, declared by whoever builds a kind of stage (an integration or a product),
17
+ * beneath the person's choices and outside the look (`workspace-style.ts` never sees them,
18
+ * so a style switch cannot wipe a toggle and a toggle cannot make a style read as custom);
19
+ * - the PER-VIEW choices a person made, which the document that owns the view persists in its
20
+ * own blob (`workspace-document-restore.ts`), through {@link viewPresentationSnapshot} and
21
+ * {@link restoreViewPresentation}.
22
+ *
23
+ * Resolution, lowest first: the kit's defaults, the stage kind's starting values, the
24
+ * document's override, the person's per-view choices. Lighting and backdrop are kept PER DRAW
25
+ * MODE (Blender keeps its lighting per shading type), so switching to wireframe and back finds
26
+ * the lighting where it was left.
27
+ */
28
+ import type { ShadingMode } from '../types';
29
+
30
+ /** The draw modes a viewport already has (`ShadingMode`), unchanged. */
31
+ export type ViewportDrawMode = ShadingMode;
32
+
33
+ /** An sRGB hex colour, `#rrggbb`. */
34
+ export type PresentationColor = string;
35
+
36
+ /** A light in a studio preset. `camera` lights move with the view (Blender's studio lights,
37
+ * Unity's headlight); `world` lights stay put. The direction points FROM the light. */
38
+ export interface StudioLight {
39
+ readonly color: PresentationColor;
40
+ readonly intensity: number;
41
+ readonly direction: readonly [number, number, number];
42
+ readonly space: 'camera' | 'world';
43
+ /** Blender's per-light specular colour and wrap (0..1), when the preset carries them. */
44
+ readonly specular?: PresentationColor;
45
+ readonly wrap?: number;
46
+ readonly castShadow?: boolean;
47
+ }
48
+
49
+ export interface StudioPreset {
50
+ readonly id: string;
51
+ readonly title: string;
52
+ readonly lights: readonly StudioLight[];
53
+ readonly ambient: { readonly color: PresentationColor; readonly intensity: number };
54
+ /** Image-based light strength under this preset (0 turns it off). */
55
+ readonly environmentIntensity: number;
56
+ }
57
+
58
+ /** What in the scene takes over from the view's own lighting, for `auto` (Godot: a directional
59
+ * light or a world environment, and an omni or spot light does not count; `light` is any light,
60
+ * the kit's own rule that a document's authored lighting wins). */
61
+ export type SceneTakeover = 'light' | 'directional-light' | 'environment';
62
+
63
+ export interface PreviewLighting {
64
+ /** Whether the scene's own lights also light the view (Godot's preview adds its sun to them;
65
+ * Blender's Material Preview draws without them: Scene Lights is off by default). */
66
+ readonly sceneLights: boolean;
67
+ readonly sun: {
68
+ readonly enabled: boolean;
69
+ readonly color: PresentationColor;
70
+ readonly energy: number;
71
+ /** Degrees above the horizon and clockwise from north (Godot: 60 and 150). */
72
+ readonly altitude: number;
73
+ readonly azimuth: number;
74
+ /** Shadow distance in scene units; 0 casts none. */
75
+ readonly shadowDistance: number;
76
+ };
77
+ readonly environment: {
78
+ readonly enabled: boolean;
79
+ /** A procedural sky (Godot's preview sky; Unity's default skybox). The horizon is the
80
+ * target's own derivation, so it is stated rather than computed here. */
81
+ readonly sky: {
82
+ readonly top: PresentationColor;
83
+ readonly horizon: PresentationColor;
84
+ readonly ground: PresentationColor;
85
+ /** How fast the horizon gives way to the top colour above it and to the ground below it
86
+ * (Godot's `sky_curve` 0.15 and `ground_curve` 0.02; Unity's horizon haze is a
87
+ * narrower band). */
88
+ readonly topCurve: number;
89
+ readonly groundCurve: number;
90
+ /** A cloud layer over the sky above the horizon (Unreal's `BP_Sky_Sphere`), or `null` for
91
+ * a clear sky (Godot, Unity). `cover` is the share of the sky clouded (0 to 1),
92
+ * `opacity` how much they hide the sky, `scale` how many cloud features span the sky. */
93
+ readonly clouds: { readonly cover: number; readonly opacity: number; readonly scale: number } | null;
94
+ };
95
+ /** A registered environment image (`kit/environment-images`) in place of the sky: the
96
+ * panorama drawn behind the scene and lit by (Blender's Material Preview HDRI; Unreal's
97
+ * preview-scene panorama). `null`: the procedural sky above. */
98
+ readonly image: string | null;
99
+ readonly energy: number;
100
+ /** Rotation about the vertical axis, degrees (Blender's Material Preview HDRI). */
101
+ readonly rotation: number;
102
+ };
103
+ }
104
+
105
+ export interface ViewportLighting {
106
+ /** `studio`: the named preset, ignoring the scene's lights (Blender's Solid).
107
+ * `preview`: the preview sun and environment (Godot; Blender's Material Preview).
108
+ * `scene`: the scene's own lights and environment only (Blender's Rendered; Unity with
109
+ * scene lighting on). */
110
+ readonly source: 'studio' | 'preview' | 'scene';
111
+ /** When set, the view's own lighting gives way to the scene's when the scene has any of
112
+ * `takeover`, and `overridable` says whether the person may turn it back on (Godot: false).
113
+ * `null`: the source never changes on its own (Blender, Unity). */
114
+ readonly auto: { readonly takeover: readonly SceneTakeover[]; readonly overridable: boolean } | null;
115
+ readonly studioPreset: string;
116
+ readonly preview: PreviewLighting;
117
+ readonly tone: { readonly mapper: 'none' | 'filmic' | 'aces' | 'agx'; readonly exposure: number };
118
+ }
119
+
120
+ export interface ViewportBackdrop {
121
+ /** `fill`: the look's fill (its colour and form, `color.viewport`).
122
+ * `color`: this view's own colour (Blender's "Viewport" background).
123
+ * `environment`: the lighting environment drawn behind the scene.
124
+ * `scene`: the scene's own background (Unity's skybox toggle; Blender's "World").
125
+ * `transparent`: nothing (a capture over a page). */
126
+ readonly source: 'fill' | 'color' | 'environment' | 'scene' | 'transparent';
127
+ readonly color: PresentationColor;
128
+ /** For `environment`: how much of it shows over the fill, and how blurred (Blender's World
129
+ * Opacity and Blur, both defaulting to 0 in Material Preview). */
130
+ readonly opacity: number;
131
+ readonly blur: number;
132
+ }
133
+
134
+ export interface ViewportOverlays {
135
+ readonly grid: {
136
+ readonly visible: boolean;
137
+ /** Minor cells per major line (Blender 10, Godot 8). */
138
+ readonly majorEvery: number;
139
+ readonly planes: { readonly xz: boolean; readonly xy: boolean; readonly yz: boolean };
140
+ };
141
+ /** Any set of selection marks (Unity can show outline and wire together; Godot a box), and
142
+ * a dot at each selected object's origin (Blender's Origins overlay). */
143
+ readonly selection: {
144
+ readonly outline: boolean;
145
+ readonly wire: boolean;
146
+ readonly box: boolean;
147
+ readonly origins: boolean;
148
+ };
149
+ /**
150
+ * Which of the world's axis lines are drawn, named by the WORLD's axes: `floor` is the two
151
+ * that lie on the floor (Blender's X and Y), an object states each (Blender's X/Y/Z overlay
152
+ * toggles; Godot draws all three, Y vertical; Unity and Unreal none).
153
+ */
154
+ readonly axes: 'floor' | { readonly x: boolean; readonly y: boolean; readonly z: boolean };
155
+ /** The navigation gizmo: `interactive` (a click turns the view to that axis — Blender's,
156
+ * Godot's, Unity's), `indicator` (drawn, not clicked — Unreal's axis triad) or `hidden`. */
157
+ readonly navigation: 'interactive' | 'indicator' | 'hidden';
158
+ /** The zoom and pan buttons under the navigation gizmo (Blender's navigation cluster; the
159
+ * game engines draw none), and the camera's position and target along the bottom (the
160
+ * editor's own readout; no reference draws one). Where they sit is the look's. */
161
+ readonly navigationControls: boolean;
162
+ readonly cameraReadout: boolean;
163
+ /** A floor under what the view shows, taking the preview sun's shadow (Unreal's preview
164
+ * floor, a Show toggle; the others show none). It lies at the content's lowest point, as
165
+ * Unreal's asset editors place theirs at the bottom of the mesh's bounds. */
166
+ readonly floor: { readonly visible: boolean; readonly color: PresentationColor };
167
+ /** A 2D view's drafting marks, each a switch in Godot's 2D View menu (Show Rulers, Show Guides,
168
+ * Show Origin, Show Viewport; all on by default there): the rulers along the view's edges, the
169
+ * guides dragged from them, the origin's axis lines, and the game's viewport rectangle (the
170
+ * manifest's `resolution` from the origin). `gridWhenSnapping` is the Grid submenu's Show When
171
+ * Snapping (the grid drawn only while the magnet is on); the Gizmos submenu's `position` (the
172
+ * selected node's origin handle), `lock` and `group` (marks on locked and grouped nodes) and
173
+ * `transformation` (the Move, Rotate and Scale tools' axis gizmo). */
174
+ readonly drafting: {
175
+ readonly rulers: boolean;
176
+ readonly guides: boolean;
177
+ readonly origin: boolean;
178
+ readonly viewport: boolean;
179
+ readonly gridWhenSnapping: boolean;
180
+ readonly position: boolean;
181
+ readonly lock: boolean;
182
+ readonly group: boolean;
183
+ readonly transformation: boolean;
184
+ };
185
+ }
186
+
187
+ /** How the stage's tools behave (function, ARCHITECTURE.md rule 7): the tool its shelf opens
188
+ * on, and what a box drag selects. Blender opens on Select Box and selects anything a box
189
+ * touches; the editor's own opens on the transform gizmo and selects what a box contains. */
190
+ export interface ViewportInteraction {
191
+ /** The tool the shelf opens on: Select (Blender's Select Box), the combined transform tool
192
+ * (the editor's own, Godot's Select gizmo), or one transform alone (Unity's and Unreal's
193
+ * Move). */
194
+ readonly bootTool: 'select' | 'transform' | 'move' | 'rotate' | 'scale';
195
+ readonly boxSelect: 'contain' | 'touch';
196
+ /**
197
+ * Which handles the combined transform tool offers beside its arrows and rings: scaling,
198
+ * rotating about the view axis (the outer ring), and moving freely (the centre). The
199
+ * editor's own offers all three; Godot's Select gizmo moves and rotates only.
200
+ */
201
+ readonly transformHandles: {
202
+ readonly scale: boolean;
203
+ readonly viewRotate: boolean;
204
+ readonly freeMove: boolean;
205
+ };
206
+ }
207
+
208
+ /** How the world the stage presents is oriented: which of its axes is up, which is what the
209
+ * gizmos name their axes by (Blender's world is Z-up, presented through three's Y-up). */
210
+ export interface ViewportWorld {
211
+ readonly upAxis: 'y' | 'z';
212
+ /** Unreal's world is LEFT-handed (Z up, Y to the right of X), so its Y points the other
213
+ * way from Blender's; the gizmos name and draw their axes by it. */
214
+ readonly handedness: 'right' | 'left';
215
+ }
216
+
217
+ /**
218
+ * THE STAGE'S CAMERA: its field of view and the direction it opens from — the view's function,
219
+ * never the look's. Each target holds its angle on its own side:
220
+ * - `vertical`: three's own and Godot's (`editors/3d/default_fov` 70, the camera keeping height);
221
+ * - `horizontal`: Unreal's (90 in its viewport settings);
222
+ * - `larger`: Blender's, whose lens angle is on the region's longer side (sensor fit AUTO);
223
+ * - `smaller`: Unity's (`kDefaultPerspectiveFov` 60, vertical when the view is wider than tall,
224
+ * `SceneView.GetVerticalFOV`).
225
+ * `opening` is the direction from the pivot to the eye when a document states none, in the
226
+ * stage's Y-up frame; a document stage opens along it (the world stage keeps its own framing).
227
+ */
228
+ export interface ViewportCamera {
229
+ readonly fov: { readonly degrees: number; readonly axis: 'vertical' | 'horizontal' | 'larger' | 'smaller' };
230
+ readonly opening: readonly [number, number, number];
231
+ }
232
+
233
+ /**
234
+ * X-RAY: surfaces drawn see-through at `alpha`, the edges behind them showing (Blender's shading
235
+ * X-Ray, kept per shading type: Solid off at 0.5, Wireframe on at 0 — no surface at all). The
236
+ * stage draws an enabled X-ray at alpha 0 by leaving the surfaces out of the draw; a partial
237
+ * alpha is drawn opaque.
238
+ */
239
+ export interface ViewportXray {
240
+ readonly enabled: boolean;
241
+ readonly alpha: number;
242
+ }
243
+
244
+ /** One draw mode's lighting, backdrop and X-ray. */
245
+ export interface ViewportModePresentation {
246
+ readonly lighting: ViewportLighting;
247
+ readonly backdrop: ViewportBackdrop;
248
+ readonly xray: ViewportXray;
249
+ }
250
+
251
+ /** A view's whole presentation, resolved. */
252
+ export interface ViewportPresentation extends ViewportModePresentation {
253
+ readonly drawMode: ViewportDrawMode;
254
+ readonly overlays: ViewportOverlays;
255
+ readonly interaction: ViewportInteraction;
256
+ readonly world: ViewportWorld;
257
+ readonly camera: ViewportCamera;
258
+ }
259
+
260
+ type DeepPartial<T> = { readonly [K in keyof T]?: T[K] extends readonly unknown[] ? T[K] : T[K] extends object ? DeepPartial<T[K]> : T[K] };
261
+
262
+ /** A partial presentation: starting values, a document override, a person's choices. Lighting
263
+ * and backdrop may be given for every mode (`all`) and per draw mode (`modes`). */
264
+ export interface PresentationLayer {
265
+ readonly drawMode?: ViewportDrawMode;
266
+ readonly overlays?: DeepPartial<ViewportOverlays>;
267
+ readonly interaction?: DeepPartial<ViewportInteraction>;
268
+ readonly world?: Partial<ViewportWorld>;
269
+ readonly camera?: DeepPartial<ViewportCamera>;
270
+ readonly all?: DeepPartial<ViewportModePresentation>;
271
+ readonly modes?: { readonly [M in ViewportDrawMode]?: DeepPartial<ViewportModePresentation> };
272
+ }
273
+
274
+ // ---- The kit's own defaults ------------------------------------------------------------------
275
+
276
+ /** The kit's studio rig: the lights a document stage wore before they were fitted to Blender —
277
+ * the dressing's key, warm (`#fff3dd`; engine `913444142` made it white), the viewport's own
278
+ * directional and ambient, and the image-based fill at three's default strength (engine
279
+ * `750b13fa9` set 0.3, later 0.85). */
280
+ export const KIT_STUDIO_PRESET: StudioPreset = Object.freeze<StudioPreset>({
281
+ id: 'kit',
282
+ title: 'Studio',
283
+ lights: [
284
+ { color: '#fff3dd', intensity: 1.9, direction: [-6, -10, 4], space: 'world', castShadow: true },
285
+ { color: '#ffffff', intensity: 1, direction: [-10, -20, -10], space: 'world' },
286
+ ],
287
+ ambient: { color: '#ffffff', intensity: 0.5 },
288
+ environmentIntensity: 1,
289
+ });
290
+
291
+ export const KIT_PRESENTATION: ViewportPresentation = Object.freeze<ViewportPresentation>({
292
+ drawMode: 'solid',
293
+ lighting: {
294
+ source: 'studio',
295
+ // The kit's own rule, kept: a document whose content carries lights wears them.
296
+ auto: { takeover: ['light'], overridable: true },
297
+ studioPreset: KIT_STUDIO_PRESET.id,
298
+ // Godot's preview defaults (`node_3d_editor_plugin.cpp` `_load_default_preview_settings`),
299
+ // the one target that ships a preview sun and sky, so `preview` means something out of the box.
300
+ preview: {
301
+ sceneLights: true,
302
+ sun: { enabled: true, color: '#ffffff', energy: 1, altitude: 60, azimuth: 150, shadowDistance: 100 },
303
+ environment: {
304
+ enabled: true,
305
+ // Top (0.385, 0.454, 0.55) and ground (0.2, 0.169, 0.133); the horizon is Godot's own
306
+ // derivation from them (their mix, pulled halfway to its luminance x 3.333).
307
+ sky: { top: '#62748c', horizon: '#a9abaf', ground: '#332b22', topCurve: 0.15, groundCurve: 0.02, clouds: null },
308
+ image: null,
309
+ energy: 1,
310
+ rotation: 0,
311
+ },
312
+ },
313
+ tone: { mapper: 'aces', exposure: 1 },
314
+ },
315
+ backdrop: { source: 'fill', color: '#3d3d3d', opacity: 0, blur: 0 },
316
+ xray: { enabled: false, alpha: 1 },
317
+ overlays: {
318
+ grid: { visible: true, majorEvery: 10, planes: { xz: true, xy: false, yz: false } },
319
+ selection: { outline: true, wire: false, box: false, origins: false },
320
+ axes: 'floor',
321
+ navigation: 'interactive',
322
+ navigationControls: true,
323
+ cameraReadout: true,
324
+ floor: { visible: false, color: '#2b3038' },
325
+ drafting: {
326
+ rulers: true,
327
+ guides: true,
328
+ origin: true,
329
+ viewport: true,
330
+ // Godot's 2D default (measured on 4.7.1: no grid until grid snap is on).
331
+ gridWhenSnapping: true,
332
+ position: true,
333
+ lock: true,
334
+ group: true,
335
+ transformation: true,
336
+ },
337
+ },
338
+ interaction: {
339
+ bootTool: 'transform',
340
+ boxSelect: 'contain',
341
+ transformHandles: { scale: true, viewRotate: true, freeMove: true },
342
+ },
343
+ world: { upAxis: 'y', handedness: 'right' },
344
+ // The editor's own camera: three's 50° vertical, opening from the editor's three-quarter view
345
+ // (the Isometric preset's direction, 1 : 0.72 : 1).
346
+ camera: { fov: { degrees: 50, axis: 'vertical' }, opening: [0.6301, 0.4537, 0.6301] },
347
+ });
348
+
349
+ // ---- Studio presets ----------------------------------------------------------------------------
350
+
351
+ /**
352
+ * THE DOCUMENT'S OWN STUDIO — the lights a document hands its stage to turn with the view
353
+ * (`ToolViewportDressing.viewLocked`): Blender's four Solid-mode lights, built by the Blender
354
+ * engine from Blender's own data. The stage draws them in place of a preset's lights; the preset
355
+ * itself carries none, and no image-based light (Blender's Solid mode has none).
356
+ */
357
+ export const DOCUMENT_STUDIO_PRESET: StudioPreset = Object.freeze<StudioPreset>({
358
+ id: 'document',
359
+ title: "Document's studio",
360
+ lights: [],
361
+ ambient: { color: '#ffffff', intensity: 0 },
362
+ environmentIntensity: 0,
363
+ });
364
+
365
+ const presets = new Map<string, StudioPreset>([
366
+ [KIT_STUDIO_PRESET.id, KIT_STUDIO_PRESET],
367
+ [DOCUMENT_STUDIO_PRESET.id, DOCUMENT_STUDIO_PRESET],
368
+ ]);
369
+
370
+ /** Register a studio preset (an integration's own studio lights). A duplicate id throws. */
371
+ export function registerStudioPreset(preset: StudioPreset): () => void {
372
+ if (presets.has(preset.id)) throw new Error(`registerStudioPreset: "${preset.id}" is already registered.`);
373
+ presets.set(preset.id, preset);
374
+ bump();
375
+ return () => {
376
+ if (presets.get(preset.id) !== preset) return;
377
+ presets.delete(preset.id);
378
+ bump();
379
+ };
380
+ }
381
+
382
+ /** The preset for an id, or the kit's when the id is not (or no longer) registered. */
383
+ export function studioPreset(id: string): StudioPreset {
384
+ return presets.get(id) ?? KIT_STUDIO_PRESET;
385
+ }
386
+
387
+ export function studioPresets(): readonly StudioPreset[] {
388
+ return [...presets.values()];
389
+ }
390
+
391
+ // ---- The grid switch ------------------------------------------------------------------------------
392
+
393
+ /**
394
+ * WHETHER A VIEW DRAWS ITS GRID — the person's grid toggle, which is the view's own choice
395
+ * (`overlays.grid.visible`): every door that toggles a grid (the viewport's button, the overlays
396
+ * menu, the Toggle Grid action, `set-grid`, a restored view) writes it here, per view, and the
397
+ * stage and the status read it back. One home; a view the person never touched shows its grid.
398
+ */
399
+ export function viewGridVisible(viewId: string): boolean {
400
+ return viewPresentation(viewId).overlays.grid.visible;
401
+ }
402
+
403
+ /** A 2D view's drafting marks (`overlays.drafting`), read and switched like its grid. */
404
+ export function viewDrafting(viewId: string): ViewportOverlays['drafting'] {
405
+ return viewPresentation(viewId).overlays.drafting;
406
+ }
407
+
408
+ export function setViewDrafting(viewId: string, choice: Partial<ViewportOverlays['drafting']>): void {
409
+ setViewPresentation(viewId, { overlays: { drafting: choice } });
410
+ }
411
+
412
+ export function setViewGridVisible(viewId: string, visible: boolean): void {
413
+ if (viewGridVisible(viewId) === visible) return;
414
+ setViewPresentation(viewId, { overlays: { grid: { visible } } });
415
+ }
416
+
417
+ // ---- View presets --------------------------------------------------------------------------------
418
+
419
+ /**
420
+ * A NAMED VIEW: a whole presentation a person can put on a view at once — a target engine's
421
+ * default viewport (Godot's preview sun and sky, all three axis lines, the box, its Select
422
+ * gizmo), contributed as data by the package that knows it (`*.view.ts`). It is the view's
423
+ * FUNCTION and light, never its look: the style stays whatever the person wears.
424
+ */
425
+ export interface ViewPreset {
426
+ readonly id: string;
427
+ readonly title: string;
428
+ readonly layer: PresentationLayer;
429
+ }
430
+
431
+ const viewPresetsById = new Map<string, ViewPreset>();
432
+
433
+ export function registerViewPreset(preset: ViewPreset): () => void {
434
+ if (viewPresetsById.has(preset.id)) throw new Error(`registerViewPreset: "${preset.id}" is already registered.`);
435
+ viewPresetsById.set(preset.id, preset);
436
+ bump();
437
+ return () => {
438
+ if (viewPresetsById.get(preset.id) !== preset) return;
439
+ viewPresetsById.delete(preset.id);
440
+ bump();
441
+ };
442
+ }
443
+
444
+ export function viewPresets(): readonly ViewPreset[] {
445
+ return [...viewPresetsById.values()];
446
+ }
447
+
448
+ /** Put a named view on a view: the person's choices become the preset's, whole. `false` for
449
+ * an id no package registered. */
450
+ export function applyViewPreset(viewId: string, presetId: string): boolean {
451
+ const preset = viewPresetsById.get(presetId);
452
+ if (!preset) return false;
453
+ // ONE write, so no listener sees the choices emptied in between; and a view that does not choose
454
+ // a draw mode keeps the one being drawn, rather than falling back to the kit's.
455
+ const current = views.get(viewId) ?? { stageKind: '', documentLayer: null, chosen: {} };
456
+ const drawMode = preset.layer.drawMode ?? current.chosen.drawMode;
457
+ views.set(viewId, { ...current, chosen: { ...preset.layer, ...(drawMode ? { drawMode } : {}) } });
458
+ bump();
459
+ return true;
460
+ }
461
+
462
+ // ---- Starting values, per kind of stage ---------------------------------------------------------
463
+
464
+ const starting = new Map<string, PresentationLayer>();
465
+
466
+ /**
467
+ * Declare the starting presentation of a kind of stage (`'model'`, `'scene'`, …): the builder's
468
+ * say, beneath every person's choice. One declaration per kind; a second throws, as two builders
469
+ * of one stage would be a composition defect.
470
+ */
471
+ export function registerStartingPresentation(stageKind: string, layer: PresentationLayer): () => void {
472
+ if (starting.has(stageKind)) {
473
+ throw new Error(`registerStartingPresentation: the "${stageKind}" stage already has starting values.`);
474
+ }
475
+ starting.set(stageKind, layer);
476
+ bump();
477
+ return () => {
478
+ if (starting.get(stageKind) !== layer) return;
479
+ starting.delete(stageKind);
480
+ bump();
481
+ };
482
+ }
483
+
484
+ // ---- Per-view choices ---------------------------------------------------------------------------
485
+
486
+ interface ViewRecord {
487
+ readonly stageKind: string;
488
+ readonly documentLayer: PresentationLayer | null;
489
+ readonly chosen: PresentationLayer;
490
+ }
491
+
492
+ const views = new Map<string, ViewRecord>();
493
+
494
+ /** What the builder of a kind of stage declared as its starting presentation, or null. */
495
+ export function startingPresentation(stageKind: string): PresentationLayer | null {
496
+ return starting.get(stageKind) ?? null;
497
+ }
498
+
499
+ /** Whether a kind of stage keeps its lighting per draw mode, as Blender's shading types each keep
500
+ * theirs: its builder stated lighting for a draw mode. Then a person's lighting choice is the
501
+ * current mode's, not every mode's. */
502
+ export function stageLightsPerMode(stageKind: string): boolean {
503
+ const modes = starting.get(stageKind)?.modes;
504
+ return modes !== undefined && Object.values(modes).some((mode) => mode?.lighting !== undefined);
505
+ }
506
+
507
+ /** Bind a view to its kind of stage and its document's override. Idempotent; a person's
508
+ * choices already recorded for the view are kept. */
509
+ export function bindViewPresentation(
510
+ viewId: string,
511
+ stageKind: string,
512
+ documentLayer: PresentationLayer | null = null,
513
+ ): void {
514
+ const current = views.get(viewId);
515
+ if (current && current.stageKind === stageKind && current.documentLayer === documentLayer) return;
516
+ views.set(viewId, { stageKind, documentLayer, chosen: current?.chosen ?? {} });
517
+ bump();
518
+ }
519
+
520
+ /** Record a person's choice for a view (a toggle, a menu pick), merged over earlier ones. */
521
+ export function setViewPresentation(viewId: string, choice: PresentationLayer): void {
522
+ const current = views.get(viewId) ?? { stageKind: '', documentLayer: null, chosen: {} };
523
+ views.set(viewId, { ...current, chosen: mergeLayers(current.chosen, choice) });
524
+ bump();
525
+ }
526
+
527
+ /** Forget a person's choices for a view: it falls back to its document and starting values. */
528
+ export function resetViewPresentation(viewId: string): void {
529
+ const current = views.get(viewId);
530
+ if (!current) return;
531
+ views.set(viewId, { ...current, chosen: {} });
532
+ bump();
533
+ }
534
+
535
+ /** The person's choices for a view, as the document persists them. */
536
+ export function viewPresentationSnapshot(viewId: string): PresentationLayer {
537
+ return views.get(viewId)?.chosen ?? {};
538
+ }
539
+
540
+ /** Put back the choices a document persisted (`restore` of its blob). */
541
+ export function restoreViewPresentation(viewId: string, chosen: PresentationLayer): void {
542
+ const current = views.get(viewId) ?? { stageKind: '', documentLayer: null, chosen: {} };
543
+ views.set(viewId, { ...current, chosen });
544
+ bump();
545
+ }
546
+
547
+ /** How a view is bound — its kind of stage and whether its document states a layer — or `null`
548
+ * when no stage has bound it (a view id no stage draws). */
549
+ export function viewPresentationBinding(
550
+ viewId: string,
551
+ ): { readonly stageKind: string; readonly documentLayer: PresentationLayer | null } | null {
552
+ const record = views.get(viewId);
553
+ return record && record.stageKind !== '' ? { stageKind: record.stageKind, documentLayer: record.documentLayer } : null;
554
+ }
555
+
556
+ /** What a view's LAST DRAW lit by, as its stage reports it: the source after `auto`, the
557
+ * preset, and which light sets were showing. The readout for an agent asking "is the view
558
+ * wearing what its presentation says". */
559
+ export interface ViewDrawReport {
560
+ readonly source: 'studio' | 'preview' | 'scene';
561
+ readonly presetId: string | null;
562
+ readonly presetLights: boolean;
563
+ readonly documentStudio: boolean | null;
564
+ readonly contentLights: number;
565
+ readonly contentLightsDarkened: number;
566
+ readonly environmentIntensity: number;
567
+ /** The environment image this draw showed (`null`: the procedural sky or none), and the one
568
+ * the view names while it is still loading or after it failed to load. */
569
+ readonly environmentImage: string | null;
570
+ readonly environmentImagePending: { readonly id: string; readonly state: 'unregistered' | 'loading' | 'failed' } | null;
571
+ readonly toneMapping: string;
572
+ }
573
+
574
+ const drawReports = new Map<string, ViewDrawReport>();
575
+
576
+ export function reportViewDraw(viewId: string, report: ViewDrawReport): void {
577
+ drawReports.set(viewId, report);
578
+ }
579
+
580
+ export function viewDrawReport(viewId: string): ViewDrawReport | null {
581
+ return drawReports.get(viewId) ?? null;
582
+ }
583
+
584
+ /** Every view a stage has bound, by id and kind of stage. */
585
+ export function boundViewPresentations(): readonly { readonly viewId: string; readonly stageKind: string }[] {
586
+ return [...views.entries()]
587
+ .filter(([, record]) => record.stageKind !== '')
588
+ .map(([viewId, record]) => ({ viewId, stageKind: record.stageKind }));
589
+ }
590
+
591
+ export function unbindViewPresentation(viewId: string): void {
592
+ if (views.delete(viewId)) bump();
593
+ }
594
+
595
+ /** A view's presentation, resolved: kit, starting values, document, person — lighting and
596
+ * backdrop for the view's current draw mode. */
597
+ export function viewPresentation(viewId: string): ViewportPresentation {
598
+ const record = views.get(viewId);
599
+ const layers = [starting.get(record?.stageKind ?? ''), record?.documentLayer ?? undefined, record?.chosen].filter(
600
+ (layer): layer is PresentationLayer => layer !== undefined,
601
+ );
602
+ return resolvePresentation(layers);
603
+ }
604
+
605
+ /** Resolve layers (lowest first) over the kit's defaults. Pure; exported for a stage that
606
+ * resolves without a bound view (a capture, a preview). */
607
+ export function resolvePresentation(layers: readonly PresentationLayer[]): ViewportPresentation {
608
+ const drawMode = layers.reduce<ViewportDrawMode>((mode, layer) => layer.drawMode ?? mode, KIT_PRESENTATION.drawMode);
609
+ let mode: ViewportModePresentation = {
610
+ lighting: KIT_PRESENTATION.lighting,
611
+ backdrop: KIT_PRESENTATION.backdrop,
612
+ xray: KIT_PRESENTATION.xray,
613
+ };
614
+ let overlays: ViewportOverlays = KIT_PRESENTATION.overlays;
615
+ let interaction: ViewportInteraction = KIT_PRESENTATION.interaction;
616
+ let world: ViewportWorld = KIT_PRESENTATION.world;
617
+ let camera: ViewportCamera = KIT_PRESENTATION.camera;
618
+ for (const layer of layers) {
619
+ if (layer.all) mode = deepMerge(mode, layer.all);
620
+ const forMode = layer.modes?.[drawMode];
621
+ if (forMode) mode = deepMerge(mode, forMode);
622
+ if (layer.overlays) overlays = deepMerge(overlays, layer.overlays);
623
+ if (layer.interaction) interaction = deepMerge(interaction, layer.interaction);
624
+ if (layer.world) world = deepMerge(world, layer.world);
625
+ if (layer.camera) camera = deepMerge(camera, layer.camera);
626
+ }
627
+ return { drawMode, lighting: mode.lighting, backdrop: mode.backdrop, xray: mode.xray, overlays, interaction, world, camera };
628
+ }
629
+
630
+ // ---- Change notification ------------------------------------------------------------------------
631
+
632
+ let version = 0;
633
+ const listeners = new Set<() => void>();
634
+
635
+ function bump(): void {
636
+ version += 1;
637
+ for (const listener of listeners) listener();
638
+ }
639
+
640
+ export function subscribeViewportPresentation(listener: () => void): () => void {
641
+ listeners.add(listener);
642
+ return () => listeners.delete(listener);
643
+ }
644
+
645
+ export function viewportPresentationVersion(): number {
646
+ return version;
647
+ }
648
+
649
+ // ---- Merging -----------------------------------------------------------------------------------
650
+
651
+ function isPlainObject(value: unknown): value is Record<string, unknown> {
652
+ return typeof value === 'object' && value !== null && !Array.isArray(value);
653
+ }
654
+
655
+ function deepMerge<T>(base: T, patch: unknown): T {
656
+ if (!isPlainObject(base) || !isPlainObject(patch)) return (patch === undefined ? base : patch) as T;
657
+ const out: Record<string, unknown> = { ...base };
658
+ for (const [key, value] of Object.entries(patch)) {
659
+ if (value === undefined) continue;
660
+ out[key] = isPlainObject(value) && isPlainObject(out[key]) ? deepMerge(out[key], value) : value;
661
+ }
662
+ return out as T;
663
+ }
664
+
665
+ /** Merge two layers: `later` wins, per field, including per draw mode. */
666
+ export function mergeLayers(earlier: PresentationLayer, later: PresentationLayer): PresentationLayer {
667
+ return deepMerge(earlier, later);
668
+ }