@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,55 @@
1
+ /**
2
+ * The 3D board's empty-viewport vocabulary, reused by every other design
3
+ * surface that would otherwise sit blank while it builds. Scene's root-aware
4
+ * loading/failure/empty states live in `SurfaceStateOverlay`; this compact
5
+ * label remains for object/board construction whose subject is already known.
6
+ *
7
+ * Idle / building / ready is viewport STATE, not a new overlay channel —
8
+ * the board already owns this shape (`ThreeBoardDocument`: idle "Open this
9
+ * tab…", building "Settling N stories…"). Scene's first design
10
+ * mount and `Object3DDocumentViewport`'s first construct are the same wait
11
+ * with different subjects. Copy names the subject being prepared; it does not
12
+ * claim a narrower phase (such as physics settling) while indexing, mounting,
13
+ * bounds/layout, or renderer setup is actually in flight.
14
+ */
15
+
16
+ import { themeVars } from '@volter/sdk/widgets';
17
+ import type { ReactNode } from 'react';
18
+
19
+ /** Fixed construct tail after the board scene exists — viewport-bind, not settle. */
20
+ export const OBJECT3D_SURFACE_BUILDING = 'Preparing the viewport…';
21
+
22
+ /** Whole 3D-board construction, from component index through mounted previews. */
23
+ export const THREE_BOARD_BUILDING = 'Preparing 3D component previews…';
24
+
25
+ /** Name the candidate count when we already know it. Never a progress fraction. */
26
+ export function threeBoardBuildingCopy(storyCount: number): string {
27
+ if (!Number.isFinite(storyCount) || storyCount < 1) return THREE_BOARD_BUILDING;
28
+ return storyCount === 1
29
+ ? 'Preparing 1 component preview…'
30
+ : `Preparing ${storyCount} component previews…`;
31
+ }
32
+
33
+ export function ViewportSurfaceStatus({
34
+ testId,
35
+ children,
36
+ }: {
37
+ readonly testId: string;
38
+ readonly children: ReactNode;
39
+ }) {
40
+ return (
41
+ <div
42
+ data-testid={testId}
43
+ style={{
44
+ position: 'absolute',
45
+ inset: 0,
46
+ padding: 16,
47
+ fontSize: 12,
48
+ color: themeVars.content.muted,
49
+ pointerEvents: 'none',
50
+ }}
51
+ >
52
+ {children}
53
+ </div>
54
+ );
55
+ }
@@ -0,0 +1,37 @@
1
+ /**
2
+ * POLL UNTIL A LIVE PREDICATE HOLDS — the one wait the editor's async doors
3
+ * share, and the one place its cadence is spelled.
4
+ *
5
+ * It lived private in `editor-view-presentation.ts` while the presenter was
6
+ * the only module that addressed a document. Now that each document family
7
+ * answers its own address (`document-open-registry.ts`), the families do the
8
+ * waiting their own addresses need — a table entry that arrives on a later
9
+ * adapter resolution, a contribution that registers after the first
10
+ * discovery pass — so the helper is shared rather than duplicated four times.
11
+ *
12
+ * NOT a general scheduling utility: it polls, which is what a registry with no
13
+ * per-entry subscription leaves you. Where a seam DOES publish changes
14
+ * (`subscribeToolContributions`, `subscribeProjectAdapter`), subscribe to it.
15
+ */
16
+
17
+ /**
18
+ * How long an EXPLICIT address waits for the thing it names. A view link, a
19
+ * restored layout and an agent's `present` are all durable intent, so a
20
+ * document that is merely late must still land; the window is bounded because
21
+ * "it is not coming" has to be sayable.
22
+ */
23
+ export const DOCUMENT_REGISTRATION_TIMEOUT_MS = 10_000;
24
+
25
+ /** `true` once `predicate()` holds, `false` if `timeoutMs` elapses first. */
26
+ export async function waitUntil(predicate: () => boolean, timeoutMs = 4000): Promise<boolean> {
27
+ if (predicate()) return true;
28
+ const started = performance.now();
29
+ return new Promise((resolve) => {
30
+ const tick = () => {
31
+ if (predicate()) resolve(true);
32
+ else if (performance.now() - started >= timeoutMs) resolve(false);
33
+ else setTimeout(tick, 25);
34
+ };
35
+ setTimeout(tick, 0);
36
+ });
37
+ }
@@ -0,0 +1,166 @@
1
+ /**
2
+ * A LANE'S WORKER STALLS, measured by the page and carried to the editor's `status` command.
3
+ *
4
+ * WHY (measured 2026-09-16): one Blender call held its worker for over 1,800s
5
+ * and wedged the tab; the only report anyone got was a replay harness timing
6
+ * out. Separately, a 0.86s-per-call cost in a 225-mesh scene stretched under
7
+ * load into heartbeat timeouts that read as "tab present, did not respond". The
8
+ * product had a number for NEITHER. Owner ruling: a tab that stops answering is
9
+ * the product's defect regardless of what the machine is doing, and the product
10
+ * must surface it.
11
+ *
12
+ * TWO MEASUREMENTS, BOTH TAKEN FROM THE PAGE, because neither blocked party can
13
+ * report on itself:
14
+ * - the WORKER's call times come from the lane's meter, which stamps each
15
+ * `postMessage` and its reply; a blocked worker cannot send, but the side
16
+ * that posted still has a clock.
17
+ * - the MAIN THREAD's stalls come from the `longtask` PerformanceObserver kept
18
+ * here.
19
+ *
20
+ * WHY A REGISTRY AND NOT A DIRECT IMPORT. The census sampler (`tab-census.ts`)
21
+ * must not pull a lane's stack into its import closure just to ask a question
22
+ * that is usually answered "no lane". A lane publishes its meter through
23
+ * `host.session.reportWorkerCallMeter` (`editor-host-door.ts`) when it
24
+ * constructs its runtime, the way a mounted game publishes its render-debug
25
+ * adapter to `authoring/active-systems`. The LONG TASKS are the host page's
26
+ * own, so publishing a meter is what starts the watch; no lane decides the page
27
+ * is watched.
28
+ *
29
+ * MEASUREMENT ONLY. Nothing here cancels, kills, or budgets a call, and no
30
+ * threshold is enforced anywhere: a budget is the owner's policy, and these are
31
+ * the numbers such a policy would have to be made from.
32
+ */
33
+
34
+ import type { EditorHostWorkerCallMetrics } from '@volter/sdk/host';
35
+ import type { TabStallMetrics, WorkerCallTabMetrics } from '@volter/sdk/tab-census';
36
+
37
+ /** What a lane publishes: a read of its live call meter. */
38
+ export type WorkerCallMeter = () => EditorHostWorkerCallMetrics;
39
+
40
+ const meters = new Map<string, WorkerCallMeter>();
41
+
42
+ /**
43
+ * Publish (or retract, with null) one lane's call meter, and start the page's
44
+ * own stall watch behind it.
45
+ *
46
+ * ONE OWNER per name: the lane's own runtime singleton, the same lifetime as
47
+ * the session itself. There is no per-document or per-play teardown that may
48
+ * retract it, because the session outlives both.
49
+ */
50
+ export function setWorkerCallMeter(lane: string, read: WorkerCallMeter | null): void {
51
+ if (read === null) {
52
+ meters.delete(lane);
53
+ return;
54
+ }
55
+ meters.set(lane, read);
56
+ // The observer's lifetime is the PAGE's (its history is what "during the
57
+ // last call" is answered from), so it is started, never stopped.
58
+ startStallObserver();
59
+ }
60
+
61
+ /** A long task, kept only as long as it can still be attributed to a call. */
62
+ interface StallEntry {
63
+ readonly start: number;
64
+ readonly duration: number;
65
+ }
66
+
67
+ /**
68
+ * How many recent long tasks to keep for the "during the last call" question.
69
+ *
70
+ * A long task is >50ms by spec, so this is minutes of a badly-stalled tab and
71
+ * nothing at all on a healthy one. Bounded because the observer runs for the
72
+ * life of the page.
73
+ */
74
+ const STALL_HISTORY = 128;
75
+
76
+ let recent: StallEntry[] = [];
77
+ let longestTaskMs: number | null = null;
78
+ let tasksOver100ms = 0;
79
+ let observing = false;
80
+
81
+ /**
82
+ * Start watching the main thread. Idempotent, and silent where the Long Tasks
83
+ * API does not exist (Safari/Firefox): `longestTaskMs` then stays null, which
84
+ * says "nobody measured" rather than the falsehood a 0 would tell.
85
+ *
86
+ * Internal: {@link setWorkerCallMeter} is the one caller, so the page's watch
87
+ * begins the moment a lane has calls to attribute stalls to, and no package has
88
+ * to know the page is watched at all.
89
+ */
90
+ function startStallObserver(): () => void {
91
+ if (observing) return () => {};
92
+ if (typeof PerformanceObserver === 'undefined') return () => {};
93
+ let observer: PerformanceObserver;
94
+ try {
95
+ observer = new PerformanceObserver((list) => {
96
+ for (const entry of list.getEntries()) {
97
+ const duration = entry.duration;
98
+ if (longestTaskMs === null || duration > longestTaskMs) longestTaskMs = duration;
99
+ if (duration >= 100) tasksOver100ms += 1;
100
+ recent.push({ start: entry.startTime, duration });
101
+ if (recent.length > STALL_HISTORY) recent = recent.slice(-STALL_HISTORY);
102
+ }
103
+ });
104
+ // `buffered` picks up the boot-time stalls that happened before this ran —
105
+ // a cold editor boot is one of the longest tasks a session ever has, and it
106
+ // is not measurable any other way.
107
+ observer.observe({ type: 'longtask', buffered: true });
108
+ } catch {
109
+ // An unsupported entry type throws here on some engines. Same answer as an
110
+ // absent API: no numbers, rather than invented ones.
111
+ return () => {};
112
+ }
113
+ observing = true;
114
+ return () => {
115
+ observer.disconnect();
116
+ observing = false;
117
+ };
118
+ }
119
+
120
+ /** The main thread's stalls, or null until a lane's meter started the watch. */
121
+ export function tabStallMetrics(): TabStallMetrics | null {
122
+ if (!observing) return null;
123
+ return {
124
+ longestTaskMs: longestTaskMs === null ? null : Math.round(longestTaskMs),
125
+ tasksOver100ms,
126
+ };
127
+ }
128
+
129
+ /**
130
+ * Every published lane's calls, keyed by lane, or null when no lane has
131
+ * published — the census then carries no `workerCalls` key at all, because
132
+ * "absent" and "idle" are different claims.
133
+ */
134
+ export function workerCallTabMetrics(
135
+ now: number = performance.now(),
136
+ ): Record<string, WorkerCallTabMetrics> | null {
137
+ if (meters.size === 0) return null;
138
+ const out: Record<string, WorkerCallTabMetrics> = {};
139
+ for (const [lane, read] of meters) {
140
+ const calls = read();
141
+ const window = calls.lastCallWindow;
142
+ let duringCall: number | null = null;
143
+ if (window !== null) {
144
+ const end = window.end ?? now;
145
+ for (const task of recent) {
146
+ // Overlap, not containment: the task that matters most is the one that
147
+ // was ALREADY running when the call was posted.
148
+ if (task.start + task.duration < window.start || task.start > end) continue;
149
+ if (duringCall === null || task.duration > duringCall) duringCall = task.duration;
150
+ }
151
+ }
152
+ out[lane] = {
153
+ inFlightMs: calls.inFlightMs,
154
+ lastCallMs: calls.lastCallMs,
155
+ maxCallMs: calls.maxCallMs,
156
+ maxCallLabel: calls.maxCallLabel ?? null,
157
+ currentPhase: calls.currentPhase ?? null,
158
+ ...(calls.completedCalls === undefined ? {} : {completedCalls: calls.completedCalls}),
159
+ callsOver5s: calls.callsOver5s,
160
+ callsOver30s: calls.callsOver30s,
161
+ lastCallLongestTaskMs: duringCall === null ? null : Math.round(duringCall),
162
+ wasmMemoryMB: calls.wasmMemoryMB,
163
+ };
164
+ }
165
+ return out;
166
+ }
@@ -0,0 +1,191 @@
1
+ /**
2
+ * THE ACTIVE WORKSPACE'S EDITOR AREAS — the live store the dock reads, and the
3
+ * one place an area document is opened and closed.
4
+ *
5
+ * **A Blender editor AREA is an editor group; the drawer holds utilities**
6
+ * (orchestrator ruling 2026-09-19; WORK.md §Inspection parity I5). Blender's UV
7
+ * Editing is a side-by-side split of the centre, Shading and Animation a
8
+ * top/bottom split, and both the dock and the Code-OSS frame have exactly that
9
+ * shape in editor groups. So a workspace's second editor is a
10
+ * `workspace.document` contribution opened into a second group — never a
11
+ * drawer utility — and this module is the seam: `workspace-presets.ts`
12
+ * publishes the active workspace's `areas` here on every switch, and this
13
+ * module opens what that list names and closes what it no longer does.
14
+ *
15
+ * WHY THE OPEN LIVES HERE AND NOT IN THE DOCK. The dock is a RECONCILER: it
16
+ * draws whatever the document registry holds, and `reconcileWorkspace` runs on
17
+ * every mutation, so opening a document from inside it is a write during a
18
+ * read. The registry is the truth; the frame places it (`volterDocuments.ts`'s
19
+ * `reconcileAreaDocumentPanels`), and under the frame the layout host places
20
+ * the same registry entry in a VS Code editor group instead. One list, two
21
+ * hosts — the shape every U8 seam takes.
22
+ *
23
+ * WHY IT IS A MODULE AND NOT A REACT EFFECT. A workspace switch arrives from
24
+ * four places (the menu, a registered action, `editor.workspace(id)`, the
25
+ * per-project restore at boot) and three of them have no component mounted to
26
+ * run an effect. `setWorkspaceAreas` is called by the same function that
27
+ * publishes the regions, so the two halves of "apply this workspace" cannot
28
+ * drift apart.
29
+ */
30
+
31
+ import type { WorkspaceAreaContribution } from '@volter/sdk/layout-arrangements';
32
+ import { openToolDocument, toolDocumentId } from './components/tool-documents';
33
+ import { subscribeToolContributions } from './tool-loader';
34
+ import { closeWorkspaceDocument, openWorkspaceDocuments } from '@volter/sdk/kit/workspace-document-registry';
35
+
36
+ let _declared: readonly WorkspaceAreaContribution[] = [];
37
+ let _areas: readonly WorkspaceAreaContribution[] = [];
38
+ /** Ratios an area's own document asked for ({@link setWorkspaceAreaRatio}), by area id. */
39
+ const _ratios = new Map<string, number>();
40
+ let _version = 0;
41
+ const _listeners = new Set<() => void>();
42
+
43
+ /** The active workspace's areas, in declaration order, each at the ratio its document asked
44
+ * for when it asked for one. */
45
+ export function activeWorkspaceAreas(): readonly WorkspaceAreaContribution[] {
46
+ return _areas;
47
+ }
48
+
49
+ /** Monotonic counter behind {@link subscribeWorkspaceAreas}. */
50
+ export function workspaceAreasVersion(): number {
51
+ return _version;
52
+ }
53
+
54
+ export function subscribeWorkspaceAreas(listener: () => void): () => void {
55
+ _listeners.add(listener);
56
+ return () => _listeners.delete(listener);
57
+ }
58
+
59
+ /** The area one open document fills, or `null` — the dock's lookup. */
60
+ export function workspaceAreaFor(documentId: string): WorkspaceAreaContribution | null {
61
+ return _areas.find((area) => toolDocumentId(area.document) === documentId) ?? null;
62
+ }
63
+
64
+ /**
65
+ * THE WHOLE OPEN PASS LEAVES THE MODULE EVALUATION, and this is the second and
66
+ * correct form of a fix the first attempt got half right.
67
+ *
68
+ * MEASURED TWICE, live, on a fresh `--template models` scaffold:
69
+ * 1. `subscribeToolContributions(...)` at this file's top level →
70
+ * "editor app failed to start: ReferenceError: Cannot access 'listeners'
71
+ * before initialization at subscribeToolContributions
72
+ * (tool-loader.ts:372) at workspace-areas.ts:41", x3. The WHOLE editor
73
+ * down, not a degraded panel.
74
+ * 2. The same subscription moved to the first `setWorkspaceAreas` call →
75
+ * the SAME error, one frame deeper: `... at ensureSubscribedToContributions
76
+ * ... at setWorkspaceAreas ... at publishWorkspaceRegions
77
+ * (workspace-presets.ts:119) at workspace-presets.ts:164`.
78
+ *
79
+ * The second reading is the one that names the real shape:
80
+ * `workspace-presets.ts` calls `publishWorkspaceRegions()` AT MODULE SCOPE
81
+ * (line 389 in source), so "the first publish" IS during module evaluation —
82
+ * deferring to it deferred nothing. And this module is in one import cycle
83
+ * with `tool-loader` (`workspace-areas` -> `components/tool-documents` ->
84
+ * `tool-loader`), so every binding over there is still in its temporal dead
85
+ * zone at that moment. `subscribeToolContributions` was merely the first of
86
+ * this module's reaches into it; `openToolDocument` is the other, and it
87
+ * would have thrown next.
88
+ *
89
+ * So the pass is queued as a MICROTASK. ES module evaluation is synchronous
90
+ * end to end, so a microtask queued during it runs after the last module has
91
+ * finished — every binding initialized, no ordering to reason about. The
92
+ * publish itself stays synchronous: `_areas`, the version and the listeners
93
+ * are this module's own state and nothing else's, and the dock must see the
94
+ * new list on the same tick the workspace changed.
95
+ */
96
+ let subscribed = false;
97
+ let pendingPass = false;
98
+
99
+ function runOpenPass(): void {
100
+ pendingPass = false;
101
+ if (!subscribed) {
102
+ subscribed = true;
103
+ // THE CONTRIBUTIONS ARRIVE AFTER THE WORKSPACE, EVERY TIME. A project's
104
+ // packages import asynchronously, so the workspace restored at boot
105
+ // publishes its `areas` while `blender-uv-editor.document` is still
106
+ // loading and `openToolDocument` truthfully opens nothing. Contributions
107
+ // changing is the other half of the same event — including a SAVE, which
108
+ // re-evaluates the module and must re-open the document against the fresh
109
+ // component.
110
+ subscribeToolContributions(scheduleOpenPass);
111
+ }
112
+ const areas = _areas;
113
+ const wanted = new Set(areas.map((area) => toolDocumentId(area.document)));
114
+ // CLOSING IS BY AREA, NOT BY ID SET DIFFERENCE. A document that is open and
115
+ // carries an `area` but is not in the new list is this module's to close,
116
+ // and nothing else in the editor opens one — so the sweep reads the registry
117
+ // rather than remembering what it opened, which is what survives a reload
118
+ // that rebuilt the registry underneath.
119
+ for (const open of openWorkspaceDocuments()) {
120
+ if (!open.descriptor.area) continue;
121
+ if (wanted.has(open.descriptor.id)) continue;
122
+ closeWorkspaceDocument(open.descriptor.id);
123
+ }
124
+ for (const area of areas) {
125
+ // `openToolDocument` is self-verifying: a contribution that has not loaded
126
+ // yet opens nothing and answers false, and the subscription above runs
127
+ // this pass again when it arrives. No queue, no retry timer.
128
+ openToolDocument(area.document, { activate: false }, area.id);
129
+ }
130
+ }
131
+
132
+ function scheduleOpenPass(): void {
133
+ if (pendingPass) return;
134
+ pendingPass = true;
135
+ queueMicrotask(runOpenPass);
136
+ }
137
+
138
+ function areasKey(areas: readonly WorkspaceAreaContribution[]): string {
139
+ return areas.map((area) => `${area.id}|${area.document}|${area.place}|${area.ratio}`).join(' ');
140
+ }
141
+
142
+ /**
143
+ * Publish the active workspace's areas (`workspace-presets.ts`), opening the
144
+ * documents it names and closing the ones the previous workspace had.
145
+ */
146
+ export function setWorkspaceAreas(areas: readonly WorkspaceAreaContribution[]): void {
147
+ _declared = areas;
148
+ scheduleOpenPass();
149
+ publishAreas();
150
+ }
151
+
152
+ /**
153
+ * AN AREA'S DOCUMENT CHANGED ITS JOB, and asks for the size that job needs — or, with `null`,
154
+ * for the workspace's declared ratio back. The model workspace's bottom area is the Timeline in
155
+ * Movie mode and the Game panel in Game mode (`@volter/editor-blender`): one document, two
156
+ * jobs, and Blender's measured Timeline strip (63 px of an 880-px column) shows the Game
157
+ * panel's play log as one clipped line.
158
+ *
159
+ * It is the same BOOTSTRAP the declared ratio is, applied the same way: under the frame a
160
+ * changed ratio stands the area up again (`volterDocuments.ts`), exactly as a workspace switch
161
+ * that puts a different document there does, and a person's drag on the sash is theirs until
162
+ * the next change of job. An id the active workspace does not declare is remembered and has no
163
+ * effect until one does.
164
+ */
165
+ export function setWorkspaceAreaRatio(areaId: string, ratio: number | null): void {
166
+ if (ratio !== null && !(ratio > 0 && ratio < 1))
167
+ throw new Error(`An area's ratio is its share of the split, between 0 and 1; got ${ratio}.`);
168
+ if ((_ratios.get(areaId) ?? null) === ratio) return;
169
+ if (ratio === null) _ratios.delete(areaId);
170
+ else _ratios.set(areaId, ratio);
171
+ publishAreas();
172
+ }
173
+
174
+ function publishAreas(): void {
175
+ const next = _declared.map((area) => {
176
+ const ratio = _ratios.get(area.id);
177
+ return ratio === undefined || ratio === area.ratio ? area : { ...area, ratio };
178
+ });
179
+ const changed = areasKey(next) !== areasKey(_areas);
180
+ _areas = next;
181
+ if (!changed) return;
182
+ _version += 1;
183
+ for (const listener of _listeners) listener();
184
+ }
185
+
186
+ /** Re-run the open pass without changing the list — the door for "the
187
+ * contributions finished loading", which is when a workspace applied at boot
188
+ * can finally find the document it named. */
189
+ export function reopenWorkspaceAreas(): void {
190
+ scheduleOpenPass();
191
+ }
@@ -0,0 +1,11 @@
1
+ import { showWorkspaceAuxiliary } from '@volter/sdk/kit/workspace-host-commands';
2
+
3
+ export function openUndoHistory(): void {
4
+ showWorkspaceAuxiliary('undo-history');
5
+ }
6
+
7
+ export function installAuxiliaryEvents(): () => void {
8
+ const onShowHistory = () => openUndoHistory();
9
+ window.addEventListener('editor:show-history-tab', onShowHistory);
10
+ return () => window.removeEventListener('editor:show-history-tab', onShowHistory);
11
+ }
@@ -0,0 +1,142 @@
1
+ /** Discoverable documents are independent of open tabs. Closing a tab keeps its
2
+ * project-owned descriptor available to Content and to session restoration. */
3
+
4
+ import {
5
+ closeWorkspaceDocument,
6
+ openWorkspaceDocument,
7
+ openWorkspaceDocuments,
8
+ WORKSPACE_DOCUMENT_KINDS,
9
+ type WorkspaceDocumentDescriptor,
10
+ } from '@volter/sdk/kit/workspace-document-registry';
11
+ import { liveDocumentHeld } from '@volter/sdk/kit/live-document';
12
+ import { registerWorkspaceDocumentRestorer } from '@volter/sdk/kit/workspace-document-restore';
13
+ import { projectAdapterFacet, subscribeProjectAdapter } from '@volter/sdk/kit/project-adapter';
14
+
15
+ export interface AvailableWorkspaceDocument {
16
+ readonly descriptor: WorkspaceDocumentDescriptor;
17
+ readonly category: string;
18
+ /** Set only when this is the root's own document, never an isolated scene. */
19
+ readonly rootId?: string | undefined;
20
+ readonly default: boolean;
21
+ }
22
+ let documents: readonly AvailableWorkspaceDocument[] = [];
23
+ const listeners = new Set<() => void>();
24
+ const pending = new Map<string, boolean>();
25
+ let sessionStarted = false;
26
+ let hasDocumentsRestoring = false;
27
+ let defaultOpened = false;
28
+ export function requestAvailableWorkspaceDocument(id: string, active = true): void {
29
+ pending.set(id, active);
30
+ restoreAvailableDocuments();
31
+ }
32
+ const notify = () => {
33
+ for (const listener of listeners) listener();
34
+ };
35
+ export const availableWorkspaceDocuments = () => documents;
36
+ export function subscribeAvailableWorkspaceDocuments(listener: () => void): () => void {
37
+ listeners.add(listener);
38
+ return () => {
39
+ listeners.delete(listener);
40
+ };
41
+ }
42
+
43
+ export function openAvailableWorkspaceDocument(id: string, activate = true): boolean {
44
+ const entry = documents.find((item) => item.descriptor.id === id);
45
+ if (!entry) return false;
46
+ openWorkspaceDocument(
47
+ { ...entry.descriptor, closeable: true, persist: () => ({ availableDocumentId: id }) },
48
+ { activate },
49
+ );
50
+ return true;
51
+ }
52
+
53
+ /** A document restored or opened by default while Play holds the game opens behind it. */
54
+ function restoreAvailableDocuments(): void {
55
+ for (const [id, active] of pending) {
56
+ if (openAvailableWorkspaceDocument(id, active && !liveDocumentHeld())) pending.delete(id);
57
+ }
58
+ if (sessionStarted && !hasDocumentsRestoring && !defaultOpened) {
59
+ // A root's fallback must wait for the project's declared document. Boards
60
+ // can register before the asynchronous document finders have settled.
61
+ const facet = projectAdapterFacet();
62
+ if (!facet || facet.documentsPending) return;
63
+ const declared = facet.scenes.entries.find((entry) => entry.id === facet.scenes.default);
64
+ if (
65
+ (declared && declared.kind !== 'scene' && declared.kind !== 'prefab') ||
66
+ openWorkspaceDocuments().some((document) => !document.descriptor.area)
67
+ ) return;
68
+ const entry = documents.find((item) => item.default);
69
+ if (entry) {
70
+ defaultOpened = true;
71
+ openAvailableWorkspaceDocument(entry.descriptor.id, !liveDocumentHeld());
72
+ }
73
+ }
74
+ }
75
+
76
+ subscribeProjectAdapter(restoreAvailableDocuments);
77
+
78
+ export function registerAvailableWorkspaceDocument(
79
+ descriptor: WorkspaceDocumentDescriptor,
80
+ options: { category: string; default?: boolean; rootId?: string | undefined },
81
+ ): string {
82
+ const previous = documents.find((item) => item.descriptor.id === descriptor.id);
83
+ if (
84
+ previous?.descriptor.Content === descriptor.Content &&
85
+ previous?.descriptor.title === descriptor.title &&
86
+ previous.descriptor.provenance?.sourcePath === descriptor.provenance?.sourcePath &&
87
+ previous.descriptor.provenance?.rootId === descriptor.provenance?.rootId &&
88
+ previous.descriptor.Toolbar === descriptor.Toolbar &&
89
+ previous.descriptor.Shelf === descriptor.Shelf &&
90
+ previous.descriptor.preview === descriptor.preview &&
91
+ previous.default === (options.default ?? false) &&
92
+ previous.category === options.category &&
93
+ previous.rootId === options.rootId
94
+ )
95
+ return descriptor.id;
96
+ const entry = {
97
+ descriptor,
98
+ category: options.category,
99
+ default: options.default ?? false,
100
+ rootId: options.rootId,
101
+ };
102
+ documents = previous
103
+ ? documents.map((item) => (item.descriptor.id === descriptor.id ? entry : item))
104
+ : [...documents, entry];
105
+ notify();
106
+ restoreAvailableDocuments();
107
+ return descriptor.id;
108
+ }
109
+
110
+ export function unregisterAvailableWorkspaceDocument(id: string): void {
111
+ if (!documents.some((item) => item.descriptor.id === id)) return;
112
+ documents = documents.filter((item) => item.descriptor.id !== id);
113
+ closeWorkspaceDocument(id, { discardDirty: true });
114
+ notify();
115
+ }
116
+
117
+ for (const kind of WORKSPACE_DOCUMENT_KINDS) {
118
+ registerWorkspaceDocumentRestorer({
119
+ kind,
120
+ owner: 'workspace-available-documents',
121
+ restore: ({ state, active }) => {
122
+ const id = (state as { availableDocumentId?: unknown } | null)?.availableDocumentId;
123
+ if (typeof id !== 'string') return false;
124
+ pending.set(id, active);
125
+ restoreAvailableDocuments();
126
+ return true;
127
+ },
128
+ beginRestore: ({ hasDocumentsToRestore }) => {
129
+ sessionStarted = true;
130
+ hasDocumentsRestoring = hasDocumentsToRestore;
131
+ restoreAvailableDocuments();
132
+ },
133
+ });
134
+ }
135
+ export function resetAvailableWorkspaceDocuments(): void {
136
+ documents = [];
137
+ pending.clear();
138
+ sessionStarted = false;
139
+ hasDocumentsRestoring = false;
140
+ defaultOpened = false;
141
+ notify();
142
+ }
@@ -0,0 +1,31 @@
1
+ /** The identity inventory of the HOST's own utility tabs — the ones
2
+ * `components/core-utilities.tsx` registers. */
3
+ export const CORE_WORKSPACE_UTILITIES = {
4
+ console: { id: 'console', title: 'Console' },
5
+ lightExplorer: { id: 'light-explorer', title: 'Light Explorer' },
6
+ } as const;
7
+
8
+ /**
9
+ * Utility tabs a PACKAGE registers, whose ids the host still declares.
10
+ *
11
+ * A tab id keys persisted dock state and is part of the shareable view address
12
+ * space (`EDITOR_VIEW_BUILT_IN_UTILITY_IDS` in `@volter/sdk`, which this
13
+ * list must equal), so the address is the host's even when the surface is not:
14
+ * the package imports its row from here rather than spelling the id twice.
15
+ * `@volter/editor-game` registers all four — the story trio through
16
+ * `story-documents.service.ts`, Generations through `generation.service.ts`.
17
+ * Build Output is NOT here: it is a `workspace.utility` CONTRIBUTION, so the
18
+ * loader namespaces its id as `tool:build-output.utility` and no host
19
+ * declaration exists.
20
+ */
21
+ export const CONTRIBUTED_WORKSPACE_UTILITIES = {
22
+ storyActions: { id: 'story-actions', title: 'Actions' },
23
+ storyInteractions: { id: 'story-interactions', title: 'Interactions' },
24
+ storyAccessibility: { id: 'story-accessibility', title: 'Accessibility' },
25
+ generations: { id: 'generations', title: 'Generations' },
26
+ } as const;
27
+
28
+ export const BUILT_IN_WORKSPACE_UTILITIES = [
29
+ ...Object.values(CORE_WORKSPACE_UTILITIES),
30
+ ...Object.values(CONTRIBUTED_WORKSPACE_UTILITIES),
31
+ ] as const;