@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,195 @@
1
+ import type { AuthoringAdapter, EditorNode } from '@volter/project/adapter';
2
+ import { setAuthoringSelection } from './consumer-actions';
3
+
4
+ /** Session-only contents scope shared by hierarchy, viewport picking, and
5
+ * hotkeys. The adapter remains the source of hierarchy/ownership truth; this
6
+ * module only records which semantic boundary the user has opened. */
7
+ interface SelectionScopeState {
8
+ adapter: AuthoringAdapter;
9
+ stack: string[];
10
+ }
11
+
12
+ let state: SelectionScopeState | null = null;
13
+ const listeners = new Set<() => void>();
14
+ let version = 0;
15
+
16
+ function emit(): void {
17
+ version += 1;
18
+ for (const listener of listeners) listener();
19
+ }
20
+
21
+ function isScopeNode(node: EditorNode | null): boolean {
22
+ return (
23
+ !!node && (node.role === 'component' || node.role === 'instance' || node.role === 'boundary')
24
+ );
25
+ }
26
+
27
+ function isDescendant(adapter: AuthoringAdapter, id: string, ancestorId: string): boolean {
28
+ let current: string | null = id;
29
+ let guard = 0;
30
+ while (current && guard++ < 1000) {
31
+ if (current === ancestorId) return true;
32
+ current = adapter.hierarchy.node(current)?.parentId ?? null;
33
+ }
34
+ return false;
35
+ }
36
+
37
+ export function subscribeSelectionScope(listener: () => void): () => void {
38
+ listeners.add(listener);
39
+ return () => listeners.delete(listener);
40
+ }
41
+
42
+ export function selectionScopeVersion(): number {
43
+ return version;
44
+ }
45
+
46
+ /** Current boundary id for pick resolution. Deliberately adapter-agnostic:
47
+ * layered picking resolves through a composite's child adapter while the
48
+ * hierarchy owns the composite adapter that opened the scope. */
49
+ export function currentSelectionScopeId(): string | null {
50
+ return state?.stack.at(-1) ?? null;
51
+ }
52
+
53
+ export function selectionScopeStack(adapter: AuthoringAdapter): string[] {
54
+ if (state?.adapter !== adapter) return [];
55
+ const valid = state.stack.filter((id) => adapter.hierarchy.node(id) !== null);
56
+ if (valid.length !== state.stack.length) {
57
+ state = valid.length > 0 ? { adapter, stack: valid } : null;
58
+ }
59
+ return valid;
60
+ }
61
+
62
+ export function enterSelectionScope(adapter: AuthoringAdapter, id: string): boolean {
63
+ const node = adapter.hierarchy.node(id);
64
+ if (!isScopeNode(node) || node!.childIds.length === 0) return false;
65
+
66
+ const current = state?.adapter === adapter ? state.stack : [];
67
+ const parentScope = current.at(-1);
68
+ if (parentScope && !isDescendant(adapter, id, parentScope)) return false;
69
+ if (parentScope === id) return false;
70
+ state = { adapter, stack: [...current, id] };
71
+ setAuthoringSelection(adapter, [id]);
72
+ emit();
73
+ return true;
74
+ }
75
+
76
+ /** Navigate to an existing breadcrumb boundary, or null for the full Game. */
77
+ export function setSelectionScope(adapter: AuthoringAdapter, id: string | null): void {
78
+ if (id === null) {
79
+ if (state === null) return;
80
+ state = null;
81
+ emit();
82
+ return;
83
+ }
84
+ const current = selectionScopeStack(adapter);
85
+ const index = current.indexOf(id);
86
+ if (index < 0) return;
87
+ state = { adapter, stack: current.slice(0, index + 1) };
88
+ setAuthoringSelection(adapter, [id]);
89
+ emit();
90
+ }
91
+
92
+ export function exitSelectionScope(adapter: AuthoringAdapter): boolean {
93
+ if (state && state.adapter !== adapter) {
94
+ state = null;
95
+ emit();
96
+ return true;
97
+ }
98
+ const current = selectionScopeStack(adapter);
99
+ if (current.length === 0) return false;
100
+ const next = current.slice(0, -1);
101
+ state = next.length > 0 ? { adapter, stack: next } : null;
102
+ const selectionId = next.at(-1) ?? current[0]!;
103
+ setAuthoringSelection(adapter, [selectionId]);
104
+ emit();
105
+ return true;
106
+ }
107
+
108
+ export function enterSelectedScope(adapter: AuthoringAdapter): boolean {
109
+ const selected = adapter.selection?.get() ?? [];
110
+ return selected.length === 1 ? enterSelectionScope(adapter, selected[0]!) : false;
111
+ }
112
+
113
+ /**
114
+ * Drill in ONE level (the viewport's double-click, Figma's own gesture): open
115
+ * `boundaryId`'s scope, then select whatever the SAME pointer resolves to now
116
+ * that the scope is open.
117
+ *
118
+ * `repick` is the caller's own pick — `layered-pick.ts` already passes
119
+ * `currentSelectionScopeId()` into `SelectionProvider.resolve`, and the
120
+ * adapter's resolve already answers with the next member down its own owner
121
+ * chain. So there is no second chain-walking rule here, and this module still
122
+ * knows nothing about how a surface picks. Repeat the gesture to keep
123
+ * descending; {@link exitSelectionScope} (Escape) walks back out.
124
+ */
125
+ export function drillIntoSelectionScope(
126
+ adapter: AuthoringAdapter,
127
+ boundaryId: string,
128
+ repick: () => string | null,
129
+ ): boolean {
130
+ if (!enterSelectionScope(adapter, boundaryId)) return false;
131
+ // `enterSelectionScope` already selected the boundary; a deeper member under
132
+ // the same pointer is what the gesture actually asked for. When the chain
133
+ // ends here the boundary stays selected — entering was still correct.
134
+ const deeper = repick();
135
+ if (deeper && deeper !== boundaryId) setAuthoringSelection(adapter, [deeper]);
136
+ return true;
137
+ }
138
+
139
+ /**
140
+ * Figma's outside-click rule: a click that lands outside an open scope leaves
141
+ * it. Pops every entry whose boundary does not CONTAIN `id`, so the stack
142
+ * follows the click to the level that does; a `null` id (empty space) closes
143
+ * every scope.
144
+ *
145
+ * Selection stays the caller's to set — the pick that produced `id` was
146
+ * already resolved against the scope that was open (a chain without the scope
147
+ * in it resolves to its own outermost owner), so this only makes the stack
148
+ * agree with where the click landed.
149
+ */
150
+ export function popSelectionScopesToContain(adapter: AuthoringAdapter, id: string | null): boolean {
151
+ const current = selectionScopeStack(adapter);
152
+ if (current.length === 0) return false;
153
+ let depth = 0;
154
+ while (id !== null && depth < current.length && isDescendant(adapter, id, current[depth]!)) {
155
+ depth += 1;
156
+ }
157
+ if (depth === current.length) return false;
158
+ state = depth > 0 ? { adapter, stack: current.slice(0, depth) } : null;
159
+ emit();
160
+ return true;
161
+ }
162
+
163
+ /**
164
+ * ONE click's answer, across the scope exit the click itself causes — the
165
+ * whole of the viewport's single-click resolution.
166
+ *
167
+ * A pick resolves against whatever scope is OPEN (`layered-pick.ts` hands
168
+ * `currentSelectionScopeId()` to the adapter's own resolve), so a click that
169
+ * leaves the innermost scope was resolved by a scope that is about to be
170
+ * wrong. With a one-deep stack that is invisible — popping lands at "no
171
+ * scope", which is what the stale answer already assumed. With a stack THREE
172
+ * deep it is visible: the stale resolve answers with the chain's outermost
173
+ * owner, one level shallower than the same click gives once the stack has
174
+ * followed it, so the user has to click twice to land where one click should
175
+ * have (reviewer, #1235).
176
+ *
177
+ * So: resolve, let {@link popSelectionScopesToContain} follow the hit, and
178
+ * re-resolve ONCE — only when the stack actually moved, because a click that
179
+ * stays inside the open scope has nothing to re-resolve against. The second
180
+ * answer needs no second pop: it is a member of the scope the first pop
181
+ * settled on.
182
+ */
183
+ export function pickAcrossScopeExit(
184
+ adapter: AuthoringAdapter,
185
+ repick: () => string | null,
186
+ ): string | null {
187
+ const hit = repick();
188
+ return popSelectionScopesToContain(adapter, hit) ? repick() : hit;
189
+ }
190
+
191
+ /** Test-only reset; production scope is intentionally session-local. */
192
+ export function _resetSelectionScopeForTest(): void {
193
+ state = null;
194
+ emit();
195
+ }
@@ -0,0 +1,169 @@
1
+ /**
2
+ * Format-neutral shell document operations.
3
+ *
4
+ * Save destination, save state, hierarchy rows and select-all are questions
5
+ * about a DOCUMENT, and the shell owns none. Answering them from store fields
6
+ * would bind the shell chrome — status bar, application menus, command relay,
7
+ * hotkeys — to one format; these helpers ask the ACTIVE
8
+ * {@link AuthoringAdapter} instead, so the same chrome works for a TSX/R3F
9
+ * world, a React root, and an ingested game alike.
10
+ */
11
+
12
+ import type { AuthoringAdapter, NodeCreationSite, WriteAnchorKind } from '@volter/project/adapter';
13
+ import type { ShellDocumentState } from '@volter/sdk/kit/shell-document-state';
14
+ import { forEachHierarchyNode } from '@volter/sdk/kit/hierarchy-walk';
15
+ import { getActiveAuthoring } from './active-adapter';
16
+ import { saveAuthoringDocument, setAuthoringSelection } from '@volter/sdk/kit/authoring/consumer-actions';
17
+ import { resolvePanelAuthoring } from './panel-authoring';
18
+
19
+ /** The authoring adapter owned by the active center document. This is the same
20
+ * resolution used by Hierarchy and Inspector; shell commands must not keep
21
+ * driving the scene adapter after an asset/source document becomes active. */
22
+ export function activeDocumentAuthoring(store: ShellDocumentState): AuthoringAdapter {
23
+ return resolvePanelAuthoring(store).adapter;
24
+ }
25
+
26
+ /** One flattened hierarchy row — the wire shape `editor.hierarchy.inspect` reports. */
27
+ export interface ShellHierarchyRow {
28
+ id: string;
29
+ name: string;
30
+ childIds: string[];
31
+ }
32
+
33
+ /**
34
+ * The active adapter's hierarchy, flattened breadth-first to id/name/childIds
35
+ * rows. `[]` when the adapter owns no tree (the no-authoring floor).
36
+ */
37
+ export function activeHierarchyRows(store: ShellDocumentState): ShellHierarchyRow[] {
38
+ const rows: ShellHierarchyRow[] = [];
39
+ forEachHierarchyNode(activeDocumentAuthoring(store).hierarchy, (node) => {
40
+ rows.push({ id: node.id, name: node.label, childIds: [...node.childIds] });
41
+ });
42
+ return rows;
43
+ }
44
+
45
+ /**
46
+ * The source path represented by an adapter's document node.
47
+ *
48
+ * Source-authored adapters persist edits immediately and intentionally expose
49
+ * no PersistenceProvider. Their hierarchy still owns an honest document node
50
+ * whose secondary label is the project-relative source path (`src/world.tsx`,
51
+ * for example). Prefer that source identity for document chrome instead of
52
+ * leaking a composite persistence fallback such as "(no persistable child)".
53
+ */
54
+ export function authoringDocumentSourcePath(adapter: AuthoringAdapter): string | null {
55
+ let found: string | null = null;
56
+ forEachHierarchyNode(adapter.hierarchy, (node) => {
57
+ const sourcePath = node.secondaryLabel?.trim();
58
+ if (node.role !== 'document' || !sourcePath) return;
59
+ found = sourcePath;
60
+ return false; // the first document row answers; never walk the whole tree for it
61
+ });
62
+ return found;
63
+ }
64
+
65
+ /** The active source-authored document path, when its adapter exposes one. */
66
+ export function activeDocumentSourcePath(store: ShellDocumentState): string | null {
67
+ return authoringDocumentSourcePath(getActiveAuthoring(store));
68
+ }
69
+
70
+ /** The exact source filename represented by a project-relative path. */
71
+ export function sourceFileName(sourcePath: string | null | undefined): string | null {
72
+ const trimmed = sourcePath?.trim();
73
+ if (!trimmed) return null;
74
+ return trimmed.split(/[\\/]/).filter(Boolean).at(-1) ?? null;
75
+ }
76
+
77
+ /**
78
+ * Where a save would land, straight from the active adapter's
79
+ * `PersistenceProvider`, or `null` when this adapter persists nothing.
80
+ */
81
+ export function activeSaveDestination(store: ShellDocumentState): string | null {
82
+ const adapter = getActiveAuthoring(store);
83
+ return adapter.capabilities.persist ? (adapter.persistence?.destination ?? null) : null;
84
+ }
85
+
86
+ /**
87
+ * Whether the active adapter has unsaved edits.
88
+ *
89
+ * A source-backed adapter may be clean because it rolled a failed write back.
90
+ * Its provider still reports that failure until a later successful write
91
+ * clears the project-history error; clean and successful are not synonyms.
92
+ */
93
+ export function activeSaveState(store: ShellDocumentState): 'saved' | 'unsaved' | 'failed' {
94
+ const persistence = getActiveAuthoring(store).persistence;
95
+ if (persistence?.lastError?.()) return 'failed';
96
+ return persistence?.isDirty() ? 'unsaved' : 'saved';
97
+ }
98
+
99
+ /** The active adapter's human-readable persistence failure, when any. */
100
+ export function activeSaveFailure(store: ShellDocumentState): string | null {
101
+ return getActiveAuthoring(store).persistence?.lastError?.() ?? null;
102
+ }
103
+
104
+ /**
105
+ * The creation-site anchor for the CURRENT selection, as the control
106
+ * API reports it (the editor's `status` command / the editor's `eval` command's `editor.status()`).
107
+ *
108
+ * `null` has one meaning and one only: there is nothing to ask about — no
109
+ * selection, or an active adapter that indexes no creation sites. Whenever the
110
+ * adapter DOES index them the answer is a record, anchored or reasoned; a
111
+ * silent blank for "we couldn't find it" is exactly what the honest-floor rule
112
+ * forbids.
113
+ */
114
+ export function activeSelectionCreationSite(store: ShellDocumentState): NodeCreationSite | null {
115
+ const adapter = activeDocumentAuthoring(store);
116
+ const id = adapter.selection?.get()[0] ?? null;
117
+ if (!id) return null;
118
+ return adapter.truth?.resolve(id, 'position').site ?? null;
119
+ }
120
+
121
+ /**
122
+ * The WRITE-side sibling of {@link activeSelectionCreationSite}: which lane
123
+ * would carry an edit to the current selection (`WriteAnchorKind`).
124
+ *
125
+ * Reported beside the anchor because the anchor alone cannot answer it — two
126
+ * subjects at the same kind of `file:line` can belong to different lanes with
127
+ * different correctness contracts. A caller sweeping the hierarchy for one
128
+ * subject per lane reads this per row; a probe's edit-write walk is that
129
+ * caller, and it is what makes the walk exhaustive over the kinds a world has
130
+ * instead of stopping at whichever row answered first.
131
+ *
132
+ * `null` on the same terms as the anchor: nothing selected, or an adapter that
133
+ * plans no distinguishable lanes.
134
+ *
135
+ * READ THROUGH THE SAME BINDING THE WRITE TAKES ({@link activeDocumentAuthoring},
136
+ * which is what `setActiveInspectionField` resolves too). A classifier reached
137
+ * through a different resolver than the writer is how a subject came to be
138
+ * reported in one lane while its edit travelled another.
139
+ */
140
+ export function activeSelectionWriteAnchorKind(store: ShellDocumentState): WriteAnchorKind | null {
141
+ const adapter = activeDocumentAuthoring(store);
142
+ const id = adapter.selection?.get()[0] ?? null;
143
+ if (!id) return null;
144
+ return adapter.truth?.resolve(id, 'position').writeAnchorKind ?? null;
145
+ }
146
+
147
+ /** Current document-local selection, shared by UI actions and the control API. */
148
+ export function activeSelectionIds(store: ShellDocumentState): string[] {
149
+ return [...(activeDocumentAuthoring(store).selection?.get() ?? store.selectedEntityIds)];
150
+ }
151
+
152
+ /** Route selection through the active document's native adapter. */
153
+ export function selectAuthoringNodes(store: ShellDocumentState, ids: readonly string[]): void {
154
+ const adapter = activeDocumentAuthoring(store);
155
+ if (!setAuthoringSelection(adapter, ids)) store.selectMultiple([...ids]);
156
+ }
157
+
158
+ /** Select every node the active adapter's hierarchy exposes. */
159
+ export function selectAllAuthoringNodes(store: ShellDocumentState): void {
160
+ selectAuthoringNodes(
161
+ store,
162
+ activeHierarchyRows(store).map((row) => row.id),
163
+ );
164
+ }
165
+
166
+ /** Save through the active adapter's persistence provider (no-op when it has none). */
167
+ export async function saveActiveAuthoring(store: ShellDocumentState): Promise<void> {
168
+ await saveAuthoringDocument(getActiveAuthoring(store), 'the shell saved the active document');
169
+ }
@@ -0,0 +1,107 @@
1
+ /**
2
+ * Board chrome — frame names and group names — is CONSTANT-SIZE client-space
3
+ * furniture floating over a board that zooms underneath it (the deliberate
4
+ * Figma-style choice: names stay readable at any scale). The authored gaps
5
+ * that chrome lives in DO shrink with zoom, so below some zoom a constant
6
+ * 26px frame-name stack no longer fits a 64-authored-px row gap and paints
7
+ * over the frames of the row above.
8
+ *
9
+ * This module owns the one rule that prevents that: **chrome degrades, frames
10
+ * never move**. Given the client-space room above a row of frames, it returns
11
+ * the scale/opacity/offset the chrome must adopt so its painted box always
12
+ * ends at or below whatever sits above it. Layout stays zoom-independent.
13
+ *
14
+ * Priority: a group name is the navigation anchor at overview zoom, so it is
15
+ * served FIRST out of the available room and therefore degrades LAST; the
16
+ * frame name gets whatever is left over.
17
+ */
18
+
19
+ export const FRAME_LABEL_HEIGHT = 20;
20
+ export const FRAME_LABEL_GAP = 6;
21
+ export const GROUP_LABEL_HEIGHT = 22;
22
+ export const GROUP_LABEL_GAP = 10;
23
+
24
+ /** Client px a frame name claims above its frame's top edge at scale 1. */
25
+ export const FRAME_LABEL_STACK = FRAME_LABEL_HEIGHT + FRAME_LABEL_GAP;
26
+ /** Client px a group name claims above the frame-name stack at scale 1. */
27
+ export const GROUP_LABEL_STACK = GROUP_LABEL_HEIGHT + GROUP_LABEL_GAP;
28
+
29
+ /** Below this scale a name starts fading; below the hide scale it is dropped
30
+ * entirely, because an unreadable sliver of text is noise, not information. */
31
+ const FRAME_FADE_FROM = 0.6;
32
+ const FRAME_HIDE_BELOW = 0.4;
33
+ const GROUP_FADE_FROM = 0.7;
34
+ const GROUP_HIDE_BELOW = 0.45;
35
+
36
+ export interface ChromePlacement {
37
+ /** Uniform scale, applied with `transform-origin` at the element's bottom-left. */
38
+ readonly scale: number;
39
+ /** 0..1; 0 only when `visible` is false. */
40
+ readonly opacity: number;
41
+ /** false → do not paint (and do not accept pointer events) at all. */
42
+ readonly visible: boolean;
43
+ /** Client px to subtract from the row's top edge to get the element's `top`.
44
+ * Accounts for the element's own unscaled height, since the scale pivots on
45
+ * its bottom edge. */
46
+ readonly offset: number;
47
+ }
48
+
49
+ export interface StoryChromePlacement {
50
+ readonly frame: ChromePlacement;
51
+ /** null when the row carries no group name. */
52
+ readonly group: ChromePlacement | null;
53
+ }
54
+
55
+ function fade(scale: number, fadeFrom: number, hideBelow: number): [number, boolean] {
56
+ if (scale >= fadeFrom) return [1, true];
57
+ if (scale <= hideBelow) return [0, false];
58
+ return [(scale - hideBelow) / (fadeFrom - hideBelow), true];
59
+ }
60
+
61
+ /**
62
+ * Fit one frame row's chrome into the client-space `room` above it — the
63
+ * distance from the row's top edge to the bottom edge of the nearest frames
64
+ * above it (`Infinity` for the first row of the board, which has nothing
65
+ * above it to collide with).
66
+ *
67
+ * Invariant: the painted top of every returned placement is at or below
68
+ * `rowTop - room`, so chrome never paints over a frame that is not its own.
69
+ */
70
+ export function placeStoryChrome(room: number, withGroupLabel: boolean): StoryChromePlacement {
71
+ const usable = Math.max(0, room);
72
+ const groupScale = withGroupLabel ? Math.min(1, usable / GROUP_LABEL_STACK) : 0;
73
+ const [groupOpacity, groupVisible] = fade(groupScale, GROUP_FADE_FROM, GROUP_HIDE_BELOW);
74
+
75
+ const frameRoom = Math.max(0, usable - GROUP_LABEL_STACK * groupScale);
76
+ const frameScale = Math.min(1, frameRoom / FRAME_LABEL_STACK);
77
+ const [frameOpacity, frameVisible] = fade(frameScale, FRAME_FADE_FROM, FRAME_HIDE_BELOW);
78
+
79
+ // A dropped frame name reserves nothing, which lets the group name settle
80
+ // closer to the frames instead of floating over an empty band.
81
+ const frameConsumed = frameVisible ? FRAME_LABEL_STACK * frameScale : 0;
82
+
83
+ return {
84
+ frame: {
85
+ scale: frameScale,
86
+ opacity: frameOpacity,
87
+ visible: frameVisible,
88
+ offset: FRAME_LABEL_GAP * frameScale + FRAME_LABEL_HEIGHT,
89
+ },
90
+ group: withGroupLabel
91
+ ? {
92
+ scale: groupScale,
93
+ opacity: groupOpacity,
94
+ visible: groupVisible,
95
+ offset: frameConsumed + GROUP_LABEL_GAP * groupScale + GROUP_LABEL_HEIGHT,
96
+ }
97
+ : null,
98
+ };
99
+ }
100
+
101
+ /** Paint one chrome element at the placement this module computed. */
102
+ export function applyStoryChrome(element: HTMLElement, placement: ChromePlacement): void {
103
+ element.style.transformOrigin = '0 100%';
104
+ element.style.transform = placement.scale >= 1 ? '' : `scale(${placement.scale})`;
105
+ element.style.opacity = placement.visible ? String(placement.opacity) : '0';
106
+ element.style.display = placement.visible ? '' : 'none';
107
+ }
@@ -0,0 +1,111 @@
1
+ /**
2
+ * THE BOARD SUBSTRATE'S PRESENTATION CONTRACT — types only, no runtime import
3
+ * of any kind, and that is the whole point.
4
+ *
5
+ * `react-story-board.ts` is THE board substrate and stays in the host: two
6
+ * host chrome files draw OVER it (`components/ReactCanvasControls.tsx`, the
7
+ * viewport strip; `components/RootSelectionOverlay.tsx`, the frame hit-test),
8
+ * which is a different question from how a board MOUNTS. But it used to
9
+ * compute its own layout by calling `stories/story-presentation.ts`, which
10
+ * imports `storybook/viewport` and `storybook/internal/csf` — so the one file
11
+ * the host genuinely owns dragged Storybook in behind it.
12
+ *
13
+ * The decoupling is an injected RESOLVER, not a dropped default: the board
14
+ * resolves a presentation per story, per viewport override, INSIDE its own
15
+ * layout pass ({@link StoryBoardPresentation.resolve}), so a caller cannot
16
+ * pre-compute the answers and hand over a table. The callers — `@volter/editor-game`'s
17
+ * design-time mount and the canvas 2D board — each supply an
18
+ * implementation; `stories/story-presentation.ts` is the one that exists,
19
+ * and it implements these types rather than declaring its own, the way
20
+ * `design-time-layers.ts` exports `LayerMountResult` for the mounts that fill
21
+ * it.
22
+ *
23
+ * Storybook's slash title/path model is the organization source behind every
24
+ * implementation there is today, but nothing here says so: these are a board's
25
+ * own vocabulary — sections, nodes, a cell size, a viewport choice.
26
+ */
27
+
28
+ /** How a frame's content sits inside its cell. */
29
+ export type StoryLayout = 'padded' | 'centered' | 'fullscreen';
30
+
31
+ /** One selectable frame size, in authored px. */
32
+ export interface StoryViewportChoice {
33
+ readonly id: string;
34
+ readonly label: string;
35
+ readonly width: number;
36
+ readonly height: number;
37
+ }
38
+
39
+ /** What a presentation is resolved FROM — everything a board frame knows
40
+ * about its own story. */
41
+ export interface StoryPresentationInput {
42
+ readonly id: string;
43
+ readonly label: string;
44
+ readonly modulePath: string;
45
+ readonly title?: string | undefined;
46
+ readonly parameters?: Readonly<Record<string, unknown>> | undefined;
47
+ readonly globals?: Readonly<Record<string, unknown>> | undefined;
48
+ readonly viewportLocked?: boolean | undefined;
49
+ }
50
+
51
+ /** One component section: the frames that belong together on the board. */
52
+ export interface StoryPresentationSection {
53
+ readonly id: string;
54
+ readonly label: string;
55
+ readonly storyIds: readonly string[];
56
+ }
57
+
58
+ /** One row of the navigation tree the hierarchy and the board share. */
59
+ export interface StoryPresentationTreeNode {
60
+ readonly id: string;
61
+ readonly label: string;
62
+ readonly role: 'folder' | 'component';
63
+ readonly kind: 'group' | 'component';
64
+ readonly parentId: string | null;
65
+ readonly childIds: readonly string[];
66
+ readonly secondaryLabel?: string;
67
+ readonly typeLabel: 'Category' | 'Folder' | 'Component';
68
+ }
69
+
70
+ /** The whole navigation index: how a set of stories is organized. */
71
+ export interface StoryPresentationIndex {
72
+ readonly sections: readonly StoryPresentationSection[];
73
+ readonly nodes: readonly StoryPresentationTreeNode[];
74
+ readonly rootIds: readonly string[];
75
+ readonly storyParentIds: ReadonlyMap<string, string>;
76
+ }
77
+
78
+ /** One frame's resolved cell. */
79
+ export interface ResolvedStoryPresentation {
80
+ readonly layout: StoryLayout;
81
+ readonly choices: readonly StoryViewportChoice[];
82
+ readonly selectedViewportId: string | null;
83
+ readonly locked: boolean;
84
+ readonly rotated: boolean;
85
+ readonly width: number;
86
+ readonly height: number;
87
+ }
88
+
89
+ /**
90
+ * What a board is handed instead of an implementation: the index it lays out
91
+ * by, and the per-frame resolver it calls during that layout.
92
+ */
93
+ export interface StoryBoardPresentation {
94
+ /** How this board's stories are organized into sections and tree rows. */
95
+ readonly index: StoryPresentationIndex;
96
+ /**
97
+ * This story's cell, right now. Called per story and again on every
98
+ * viewport/rotation override, which is why it is a function the board holds
99
+ * rather than a table it was given.
100
+ *
101
+ * `fallback` is the board's own default cell for a story that authored
102
+ * none; `sessionViewportId` is `undefined` for "whatever the story
103
+ * authored" and `null` for "explicitly none".
104
+ */
105
+ readonly resolve: (
106
+ story: StoryPresentationInput,
107
+ fallback?: { readonly width: number; readonly height: number },
108
+ sessionViewportId?: string | null,
109
+ sessionRotated?: boolean,
110
+ ) => ResolvedStoryPresentation;
111
+ }
@@ -0,0 +1,67 @@
1
+ /**
2
+ * Which declared world is the Three root this viewport paints, read from the composite's
3
+ * manifest kinds and capabilities only (no scene, no renderer), so kit panels can ask without
4
+ * importing the viewport.
5
+ */
6
+ import { CompositeAuthoringAdapter } from '@volter/sdk/kit/authoring/composite-authoring-adapter';
7
+ import { isRootHidden } from '@volter/sdk/kit/authoring/world-session-state';
8
+ import type { ShellStore } from '@volter/sdk/kit/shell-store';
9
+ import { getActiveAuthoring } from './active-adapter';
10
+
11
+ /**
12
+ * The worldId of the ONE three world actually rendered in this viewport
13
+ * (`store.objectMap`'s contents), or `null` when the active adapter isn't a
14
+ * composite (single-world project — no world-group row/eye exists for it at
15
+ * all, so there is nothing to resolve) or declares no three world.
16
+ *
17
+ * Identifies the LIVE Three child by `capabilities.transform` — a transient
18
+ * Boundary adapter reports no transform capability until the R3F design
19
+ * session attaches. This reuses an existing, already-load-bearing signal
20
+ * instead of adding an `instanceof` check or parallel bookkeeping slot.
21
+ */
22
+ export function resolveThreeViewportRootId(store: ShellStore): string | null {
23
+ const active = getActiveAuthoring(store);
24
+ if (!(active instanceof CompositeAuthoringAdapter)) return null;
25
+ const focused = active
26
+ .childAdapters()
27
+ .find((c) => c.kind === 'three' && c.adapter.capabilities.transform);
28
+ return focused?.worldId ?? null;
29
+ }
30
+
31
+ /**
32
+ * Is a three surface currently SHOWING in the viewport? This is the single
33
+ * derived truth the 3D viewport chrome gates on (spec 28): the grid,
34
+ * orientation gizmo, transform toolstrip, camera readout, shading modes, and
35
+ * the transform gizmo itself are claims about what the user can do RIGHT NOW
36
+ * — showing them over a viewport with no visible 3D content is a false claim
37
+ * (same spirit as the adapter-reach rule: report what isn't there, never
38
+ * advertise it). The DOM half of the chrome (`RootSelectionOverlay`)
39
+ * already self-gates this way; this selector brings the pre-contract 3D
40
+ * chrome under the same rule.
41
+ *
42
+ * Truth table (deliberately conservative — every non-composite mode keeps
43
+ * today's behavior exactly):
44
+ * - active adapter is not a composite (single-world project, ingest):
45
+ * `true` — no world-group eyes exist there, so there is nothing to derive
46
+ * from.
47
+ * - composite with NO threejs-kind child at all (e.g. react-only
48
+ * multi-world manifest): `false` — no 3D content can EVER show.
49
+ * - composite whose three child is still a read-only Boundary
50
+ * (`resolveThreeViewportRootId` → null): `true` — this is reachable
51
+ * transiently while the R3F design session attaches; keep the chrome rather
52
+ * than flickering it around adapter-install timing.
53
+ * - composite with a live three world: `!isRootHidden(worldId)`
54
+ * — the eye is the "what we're showing" signal.
55
+ *
56
+ * Recompute-per-call like everything else in this module: callers read it on
57
+ * every store notify (`syncFromStore` / `the world root's stage` render), never cache
58
+ * it across notifies.
59
+ */
60
+ export function isThreejsSurfaceVisible(store: ShellStore): boolean {
61
+ const active = getActiveAuthoring(store);
62
+ if (!(active instanceof CompositeAuthoringAdapter)) return true;
63
+ const children = active.childAdapters();
64
+ if (!children.some((c) => c.kind === 'three')) return false;
65
+ const threeRootId = resolveThreeViewportRootId(store);
66
+ return threeRootId === null ? true : !isRootHidden(threeRootId);
67
+ }