@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,184 @@
1
+ /**
2
+ * A CONTENT ENTRY IS SOURCED, NOT DERIVED — the fourth registry in the family
3
+ * of `workspace-document-restore.ts` (a kind owns its persisted state),
4
+ * `document-open-registry.ts` (a kind owns how it opens) and
5
+ * `chrome-slot-registry.ts` (the host owns the place, a package owns what sits
6
+ * there). Here: the host owns the Content SCOPE — the grid, the chips, the
7
+ * sort, the search, the selection and the drag — and a package owns WHY a
8
+ * project component is content at all, what it looks like, and what opening it
9
+ * means.
10
+ *
11
+ * WHY IT EXISTS. The Content scope of `components/AssetBrowser.tsx` already
12
+ * concatenates two sources it does not own: the active adapter facet's
13
+ * document entries and `liveAuthoringAssets(adapter)`. A THIRD was hard-wired
14
+ * — `pickComponentPreviewStory` decided which components were content and
15
+ * `StoryComponentThumbnail` painted them — which made the host's Content
16
+ * browser know what portable CSF is, and dragged the story registry (and
17
+ * therefore Storybook) into every editor boot, a `models` build that authors
18
+ * no stories included (WORK.md §Stories leave the host, edge 1 — the ONE new
19
+ * door that design mints). The shape is transcribed from
20
+ * `chrome-slot-registry.ts`: register / list / subscribe / version, with the
21
+ * same owner-replaces-owner rule for an HMR re-evaluation.
22
+ *
23
+ * NOTHING REGISTERED IS A REAL ANSWER. A build whose package list carries no
24
+ * content source lists documents and assets and no component tiles — the same
25
+ * honest emptiness a document kind with no registered opener gives.
26
+ *
27
+ * WHAT THE HOST STILL OWNS, and why it is not a leak: the COMPONENT INDEX
28
+ * (`services.listProjectComponents()`, the server's own scan) is the host's,
29
+ * and it is handed to every source as context. A source answers "which of
30
+ * these, and why" — it never rescans the project.
31
+ */
32
+
33
+ import type { AdapterSurface } from '@volter/project/adapter';
34
+ import type { ComponentType } from 'react';
35
+ import type { ProjectComponentEntry } from '@volter/sdk/kit/asset-workflow/project-content';
36
+ import type { WorkspaceStateStore } from './workspace-document-restore';
37
+
38
+ /**
39
+ * A component as a SOURCE sees it: what it is called, where its module is,
40
+ * which surface it mounts on. Deliberately narrower than the host's own index
41
+ * row (`ProjectComponentEntry`, which is assignable to it), because the other
42
+ * caller of this registry has exactly these three facts and no index: the
43
+ * Inspector, asking for the picture of ONE component.
44
+ */
45
+ export interface ContentComponentRef {
46
+ readonly name: string;
47
+ readonly path: string;
48
+ readonly surface: ProjectComponentEntry['surface'];
49
+ }
50
+
51
+ /** What a source is asked ABOUT: components, and the surface the question is
52
+ * focused on (`null` = no active authoring surface, so nothing is filtered
53
+ * out by surface). The Content scope passes its whole index; the Inspector
54
+ * passes one. */
55
+ export interface ContentEntrySourceContext {
56
+ readonly components: readonly ContentComponentRef[];
57
+ readonly surface: AdapterSurface | null;
58
+ }
59
+
60
+ /** One admitted component. `detail` is the source's own reason — opaque to the
61
+ * host, handed back to the source's `Thumbnail` and `open`. */
62
+ export interface ContentEntry {
63
+ /** Unique within the source; the host keys its row on `<source>:<id>`. */
64
+ readonly id: string;
65
+ /** The component this entry depicts — the very ref the source was given. */
66
+ readonly component: ContentComponentRef;
67
+ /** The source's own reason, opaque by construction: only the source that
68
+ * minted the entry ever reads it, and it casts. */
69
+ readonly detail: unknown;
70
+ }
71
+
72
+ export interface ContentEntryThumbnailProps {
73
+ readonly entry: ContentEntry;
74
+ /** Bumped by the panel when a preview must be re-taken. */
75
+ readonly previewRevision: number;
76
+ readonly width?: number;
77
+ readonly height?: number;
78
+ }
79
+
80
+ export interface ContentEntrySource {
81
+ /** The source's id, in its own vocabulary. Part of every row key. */
82
+ readonly id: string;
83
+ /** Which module registered it. Re-registering the same owner+id REPLACES,
84
+ * so an HMR re-evaluation leaves one source, not two. */
85
+ readonly owner: string;
86
+ /** Ascending; ties keep registration order. */
87
+ readonly order?: number;
88
+ readonly entries: (context: ContentEntrySourceContext) => readonly ContentEntry[];
89
+ /** The source's OWN change signal — its ledger settling, a discovery pass
90
+ * finishing. The panel re-reads on it without knowing what moved. */
91
+ readonly subscribe: (listener: () => void) => () => void;
92
+ /** Paints the tile. A stable component type (not a closure per entry), so
93
+ * the grid re-renders rather than remounting every preview. */
94
+ readonly Thumbnail: ComponentType<ContentEntryThumbnailProps>;
95
+ /** Double-click: open whatever this entry's subject opens as. */
96
+ readonly open: (store: WorkspaceStateStore, entry: ContentEntry, title: string) => void;
97
+ }
98
+
99
+ const _sources: ContentEntrySource[] = [];
100
+ const listeners = new Set<() => void>();
101
+ /** Live teardowns for the per-source subscriptions the registry re-fans. */
102
+ const sourceSubscriptions = new Map<ContentEntrySource, () => void>();
103
+ let version = 0;
104
+
105
+ function publish(): void {
106
+ version++;
107
+ for (const listener of listeners) listener();
108
+ }
109
+
110
+ /** Install a source. Returns the teardown. */
111
+ export function registerContentEntrySource(source: ContentEntrySource): () => void {
112
+ const stale = _sources.findIndex((item) => item.owner === source.owner && item.id === source.id);
113
+ if (stale >= 0) {
114
+ const [removed] = _sources.splice(stale, 1);
115
+ if (removed) {
116
+ sourceSubscriptions.get(removed)?.();
117
+ sourceSubscriptions.delete(removed);
118
+ }
119
+ }
120
+ _sources.push(source);
121
+ _sources.sort((a, b) => (a.order ?? 0) - (b.order ?? 0));
122
+ sourceSubscriptions.set(source, source.subscribe(publish));
123
+ publish();
124
+ return () => {
125
+ const at = _sources.indexOf(source);
126
+ if (at < 0) return;
127
+ _sources.splice(at, 1);
128
+ sourceSubscriptions.get(source)?.();
129
+ sourceSubscriptions.delete(source);
130
+ publish();
131
+ };
132
+ }
133
+
134
+ const EMPTY: readonly ContentEntrySource[] = [];
135
+
136
+ /** Everything registered, in order. A stable array per version, so it is a
137
+ * safe `useSyncExternalStore` snapshot. */
138
+ export function contentEntrySources(): readonly ContentEntrySource[] {
139
+ return _sources.length === 0 ? EMPTY : _sources;
140
+ }
141
+
142
+ /** ONE subscription for the panel: the registry's own changes AND every
143
+ * registered source's. What changed is never the panel's question. */
144
+ export function subscribeContentEntrySources(listener: () => void): () => void {
145
+ listeners.add(listener);
146
+ return () => {
147
+ listeners.delete(listener);
148
+ };
149
+ }
150
+
151
+ export function contentEntrySourceRegistryVersion(): number {
152
+ return version;
153
+ }
154
+
155
+ /**
156
+ * THE SAME QUESTION, ABOUT ONE COMPONENT: the first registered source that
157
+ * admits it, and the entry it minted — what the INSPECTOR asks when it wants a
158
+ * picture of a component it cannot photograph natively (a canvas entity with
159
+ * no Object3D, a selected component-backed asset).
160
+ *
161
+ * It is deliberately not a second door. "Is this component content, and what
162
+ * does it look like?" is one question; the Content grid asks it of the whole
163
+ * index and the Inspector of a single ref, and both take back the same
164
+ * `{ source, entry }` pair to paint with `source.Thumbnail`.
165
+ */
166
+ export function contentEntryForComponent(
167
+ component: ContentComponentRef,
168
+ ): { readonly source: ContentEntrySource; readonly entry: ContentEntry } | null {
169
+ for (const source of _sources) {
170
+ // Surface `null`: the Inspector is asking about THIS component, not about
171
+ // what belongs on the surface currently in focus.
172
+ const entry = source.entries({ components: [component], surface: null })[0];
173
+ if (entry) return { source, entry };
174
+ }
175
+ return null;
176
+ }
177
+
178
+ /** Test-only reset (mirrors the restore, open and chrome-slot registries'). */
179
+ export function __resetContentEntrySourcesForTest(): void {
180
+ for (const stop of sourceSubscriptions.values()) stop();
181
+ sourceSubscriptions.clear();
182
+ _sources.length = 0;
183
+ publish();
184
+ }
@@ -0,0 +1,48 @@
1
+ /**
2
+ * The native surfaces a contribution is handed beyond the kit's own (`surfaces.Object3DAuthoring`
3
+ * and the rest a medium's integration adds to `ToolContributionSurfaces` from its public API), as
4
+ * that integration registers them. The kit forwards whatever is registered under a surface's name
5
+ * and imports no medium: a composition without the integration registers none, and a
6
+ * contribution that asks for one shows the kit's placeholder until one is.
7
+ *
8
+ * The surfaces reach contributions through their props, not an import, because a project's
9
+ * contributions are modules of the project's own graph and cannot import the editor's components.
10
+ */
11
+ import type { ComponentType } from 'react';
12
+ import type { ToolContributionSurfaces } from '../contributions';
13
+
14
+ export type ContributionSurfaceRegistration = {
15
+ readonly [Name in keyof ToolContributionSurfaces]?: ToolContributionSurfaces[Name];
16
+ };
17
+
18
+ const registered = new Map<string, ComponentType<never>>();
19
+ const listeners = new Set<() => void>();
20
+
21
+ function notify(): void {
22
+ for (const listener of listeners) listener();
23
+ }
24
+
25
+ /** Install an integration's surfaces by name. Returns the teardown. */
26
+ export function registerContributionSurfaces(surfaces: ContributionSurfaceRegistration): () => void {
27
+ const entries = Object.entries(surfaces) as [string, ComponentType<never>][];
28
+ for (const [name, surface] of entries) registered.set(name, surface);
29
+ notify();
30
+ return () => {
31
+ for (const [name, surface] of entries) {
32
+ if (registered.get(name) === surface) registered.delete(name);
33
+ }
34
+ notify();
35
+ };
36
+ }
37
+
38
+ /** The surface registered under `name`, or null when no integration has registered one. */
39
+ export function contributionSurface(name: string): ComponentType<never> | null {
40
+ return registered.get(name) ?? null;
41
+ }
42
+
43
+ export function subscribeContributionSurfaces(listener: () => void): () => void {
44
+ listeners.add(listener);
45
+ return () => {
46
+ listeners.delete(listener);
47
+ };
48
+ }
@@ -0,0 +1,192 @@
1
+ /**
2
+ * WHICH CANVAS IS PRESENTING, and the bounded failsafe for when NONE is.
3
+ *
4
+ * The `canvas-revealed` ontology invariant (`ontology-invariants.ts`) asks one
5
+ * question: is this session drawing onto a surface nobody can see? Its own
6
+ * `fix` text has always named "the reveal failsafe" — and there wasn't one.
7
+ * This module is both halves, kept pure (facts in, decision out) so every
8
+ * transition is testable with no browser, the same contract the invariants
9
+ * themselves follow.
10
+ *
11
+ * ## Half one: the measurement was picking the wrong canvas
12
+ *
13
+ * The facts used to come from `findPrimaryCanvas`, which ranks by painted
14
+ * AREA and is blind to visibility — a canvas hidden by `visibility: hidden`
15
+ * keeps its full bounding box. Measured live on a racing-game ingest session
16
+ * (2026-08-15): during Play the Scene document's render overlay is hidden
17
+ * with an inline `visibility: hidden` while the game's own canvas
18
+ * fills the pane. The editor's Scene canvas — full-size, correctly hidden,
19
+ * shallower in the tree — won the ranking, so the invariant reported
20
+ * "4 frame(s) produced in 3389ms while the viewport canvas is hidden
21
+ * (visibility: hidden)" for a session whose screenshot showed the game
22
+ * rendering perfectly. A standing warning on a healthy session is the failure
23
+ * mode the invariant module's own comments warn about, so it is fixed at the
24
+ * source: **a session is revealed when ANY of its canvases is revealed**, and
25
+ * only when every one of them is hidden does the row name the largest one's
26
+ * reason.
27
+ *
28
+ * ## Half two: firing, not just reporting
29
+ *
30
+ * When every canvas IS hidden while frames are being produced, reporting is
31
+ * not enough — the user is looking at a blank viewport and the fix is one
32
+ * style write away. The failsafe fires it, and is deliberately narrow:
33
+ *
34
+ * - **Only inline hiding on the canvas ITSELF.** A canvas hidden by an
35
+ * ancestor (a render overlay) or by a stylesheet rule is somebody
36
+ * else's decision, expressed somewhere this must not reach into.
37
+ * - **Only a canvas with no declared owner.** The editor's own viewport
38
+ * canvas is inline `opacity: 0` whenever `isThreejsSurfaceVisible` says so
39
+ * — a computed decision with a name — and React would re-apply it anyway.
40
+ * Fighting it would put a permanent false alarm on every DOM-only project.
41
+ * - **Once per canvas, after a bounded wait.** A mount is legitimately hidden
42
+ * for a moment; a failsafe that fires on the transient is a failsafe that
43
+ * cries wolf. And a failsafe is an emergency, never a policy: it clears the
44
+ * style once and then stops, so it can never become the mechanism a broken
45
+ * reveal path quietly relies on.
46
+ *
47
+ * Firing is LOUD by design. The ledger entry says the failsafe fired, what it
48
+ * had to undo, and that this is a defect worth reporting upstream — because a
49
+ * silently-repaired reveal is a reveal nobody ever fixes.
50
+ */
51
+
52
+ /** One canvas as the DOM layer measured it. */
53
+ export interface CanvasVisibilityFact {
54
+ /** How the message names it — a `data-testid`, a class, or its index. */
55
+ readonly label: string;
56
+ /** Painted area in CSS px², used only to pick the one the row speaks for. */
57
+ readonly area: number;
58
+ /** Why it is not visible, in the measurement's own words, or `null` when it
59
+ * IS visible. */
60
+ readonly hiddenBy: string | null;
61
+ /** Which of the canvas' OWN inline style properties is what hides it, or
62
+ * `null` when the hiding comes from anywhere else (an ancestor, a
63
+ * stylesheet, a zero-size box). Only this is ever cleared. */
64
+ readonly inlineHiding: 'opacity' | 'visibility' | 'display' | null;
65
+ /** True when this canvas' visibility is nobody's declared decision. The
66
+ * editor's own viewport canvas is `false` — see the module header. */
67
+ readonly failsafeEligible: boolean;
68
+ }
69
+
70
+ /**
71
+ * Why the session has no visible presentation surface, in the measurement's
72
+ * own words — `undefined` when there is no canvas to measure at all, `null`
73
+ * when at least one canvas is revealed.
74
+ *
75
+ * This is the whole of half one: the presence of ONE revealed canvas is what
76
+ * makes the session presentable, whatever the others are doing.
77
+ */
78
+ export function presentingCanvasHiddenBy(
79
+ canvases: readonly CanvasVisibilityFact[],
80
+ ): string | null | undefined {
81
+ if (canvases.length === 0) return undefined;
82
+ if (canvases.some((canvas) => canvas.hiddenBy === null)) return null;
83
+ const largest = [...canvases].sort((a, b) => b.area - a.area)[0];
84
+ return largest?.hiddenBy ?? null;
85
+ }
86
+
87
+ /**
88
+ * One line per hidden canvas: which one, why, and whose doing it is.
89
+ *
90
+ * The row used to say only "the viewport canvas is hidden (visibility:
91
+ * hidden)" — a sentence you cannot act on, because a session has several
92
+ * canvases and the reason does not say which of them is the subject or who
93
+ * hid it. Verifying this work against a live session was blocked on exactly
94
+ * that gap, which is the argument for it being in the report rather than in a
95
+ * debug affordance.
96
+ */
97
+ export function hiddenCanvasBreakdown(
98
+ canvases: readonly CanvasVisibilityFact[],
99
+ ): readonly string[] {
100
+ return canvases
101
+ .filter((canvas) => canvas.hiddenBy !== null)
102
+ .sort((a, b) => b.area - a.area)
103
+ .map(
104
+ (canvas) =>
105
+ `${canvas.label} (${canvas.hiddenBy}, ${
106
+ canvas.inlineHiding === null
107
+ ? 'from an ancestor or a stylesheet'
108
+ : canvas.failsafeEligible
109
+ ? 'its own inline style, unowned'
110
+ : 'its own inline style, by a declared owner'
111
+ }, ${Math.round(canvas.area)}px²)`,
112
+ );
113
+ }
114
+
115
+ /**
116
+ * THE ONE SUBJECT DEFINITION — a canvas hiding ITSELF with nobody owning that
117
+ * decision. Both the invariant row and the failsafe below turn on this, which
118
+ * is why it is a function rather than two filters that could drift apart.
119
+ *
120
+ * Two facts have to line up, and each was measured as a false positive on the
121
+ * same live racing-ingest session (2026-08-15) when it did not:
122
+ *
123
+ * - hidden by its OWN box or inline style. On the UI Components document,
124
+ * every canvas is hidden by an ANCESTOR — the editor
125
+ * showing a different document, which is what the user opened.
126
+ * - and NOT a canvas whose visibility is somebody's declared decision. The
127
+ * editor's own viewport canvas carries inline `opacity: 0` from
128
+ * `isThreejsSurfaceVisible`, so during Play over an ingest root it read as
129
+ * "a canvas hiding itself" and kept the row violating on a healthy session.
130
+ */
131
+ export function selfHiddenSubjects(
132
+ canvases: readonly CanvasVisibilityFact[],
133
+ ): readonly CanvasVisibilityFact[] {
134
+ return canvases.filter((canvas) => canvas.failsafeEligible && canvas.inlineHiding !== null);
135
+ }
136
+
137
+ /**
138
+ * Of the hidden canvases, is any of them {@link selfHiddenSubjects | hiding
139
+ * itself}? `null` when nothing is hidden at all — there is no question to
140
+ * answer.
141
+ */
142
+ export function anyCanvasHidesItself(canvases: readonly CanvasVisibilityFact[]): boolean | null {
143
+ if (!canvases.some((canvas) => canvas.hiddenBy !== null)) return null;
144
+ return selfHiddenSubjects(canvases).length > 0;
145
+ }
146
+
147
+ /**
148
+ * How long the all-hidden-while-drawing condition must hold before the
149
+ * failsafe fires. Longer than one vitals sample, so the condition has to
150
+ * SURVIVE a sample rather than merely be observed once during a mount.
151
+ */
152
+ export const REVEAL_FAILSAFE_DEADLINE_MS = 4_000;
153
+
154
+ export type RevealFailsafeDecision =
155
+ | { readonly fire: false }
156
+ | { readonly fire: true; readonly target: CanvasVisibilityFact; readonly ledger: string };
157
+
158
+ export interface RevealFailsafeInput {
159
+ readonly canvases: readonly CanvasVisibilityFact[];
160
+ /** Frames the page produced in the sample window. */
161
+ readonly framesProduced: number;
162
+ /** How long the condition has held, or `null` when this is the first sample
163
+ * that has seen it (nothing has held yet). */
164
+ readonly hiddenForMs: number | null;
165
+ readonly deadlineMs?: number;
166
+ }
167
+
168
+ /**
169
+ * Whether to force the reveal, and the ledger line that must accompany it.
170
+ *
171
+ * Every gate is a fact the caller measured; nothing here reads a clock or the
172
+ * DOM.
173
+ */
174
+ export function decideRevealFailsafe(input: RevealFailsafeInput): RevealFailsafeDecision {
175
+ const deadline = input.deadlineMs ?? REVEAL_FAILSAFE_DEADLINE_MS;
176
+ if (input.framesProduced <= 0) return { fire: false };
177
+ if (input.hiddenForMs === null || input.hiddenForMs < deadline) return { fire: false };
178
+ if (presentingCanvasHiddenBy(input.canvases) === null) return { fire: false };
179
+ const target = [...selfHiddenSubjects(input.canvases)].sort((a, b) => b.area - a.area)[0];
180
+ if (!target) return { fire: false };
181
+ return {
182
+ fire: true,
183
+ target,
184
+ ledger:
185
+ `canvas reveal FAILSAFE FIRED — the "${target.label}" canvas was still hidden by its own ` +
186
+ `inline ${target.inlineHiding} (${target.hiddenBy}) ${Math.round(input.hiddenForMs / 1000)}s ` +
187
+ 'after frames started arriving, so the editor cleared that style to put the picture on ' +
188
+ 'screen. THIS IS A DEFECT, not a feature: the mount path that hid this canvas never ran ' +
189
+ 'its own reveal, and the failsafe fires ONCE — a second mount in this state stays blank. ' +
190
+ 'Report it upstream with the mount that owns this canvas.',
191
+ };
192
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * THE DESIGN-TIME SURFACE REGISTRY — every place the editor mounts a game's own
3
+ * content while it is NOT playing, and the content clock each one publishes.
4
+ *
5
+ * ## CONTENT time vs PRESENTATION time (the one policy, stated once)
6
+ *
7
+ * A design-time surface renders continuously, and that is fine: the camera
8
+ * orbit, a turntable, the standard viewport dressing and the editor's own
9
+ * helpers are PRESENTATION and are editor-owned, so they may move while the
10
+ * editor is in Edit. What may NOT move is CONTENT — the mounted world's
11
+ * `update(dt)`, an animation mixer, a `useFrame` clock, a simulation step —
12
+ * because Edit is static (ARCHITECTURE-CORE §Rules). An interactive document
13
+ * may advance content only through its explicit animation/simulation transport;
14
+ * opening the document itself never advances it. Off-screen capture operations
15
+ * may request their own bounded settle before producing a still.
16
+ *
17
+ * ## WHY A REGISTRY, rather than a field on one surface's session class
18
+ *
19
+ * Edit-static was enforced at the Scene view's design session only, so the
20
+ * SAME content mounted on any other surface kept running: a GLB train animated
21
+ * in the Asset Lab while every instrument reported a still editor (owner find,
22
+ * 2026-08-15). The check therefore enumerates SURFACES, and a surface that
23
+ * publishes no clock is reported UNMEASURED BY NAME rather than assumed still —
24
+ * silence is the one case that would let a surface animate in Edit with the
25
+ * vitals green, which is the defect this registry exists to make impossible.
26
+ *
27
+ * A surface's clock is monotonic seconds of ITS OWN content time. Its absolute
28
+ * value means nothing; `coverage/session-vitals.ts` only ever asks whether two
29
+ * readings differ, which is what makes camera orbit (which never touches it)
30
+ * irrelevant to the answer.
31
+ *
32
+ * ## THE TRANSPORT IS THE SANCTION
33
+ *
34
+ * "Edit is static" has always meant *nothing plays on its own* — the origin
35
+ * note behind the row says it out loud: a game running "with nothing having
36
+ * pressed ▶". A document's own animation/simulation transport IS that press,
37
+ * so content time advancing WHILE a transport is engaged is the sanctioned
38
+ * case, not the violation. A surface therefore publishes a second reading
39
+ * beside its clock: how many times an ENGAGED transport advanced it
40
+ * ({@link DesignTimeSurface.transportAdvances}). The row fires only when the
41
+ * clock moved and that counter did not.
42
+ */
43
+
44
+ export interface DesignTimeSurface {
45
+ /**
46
+ * Stable per MOUNT — the document id only for the one mount that IS the
47
+ * document. Two mounts of one document (its viewport and a chromeless
48
+ * preview of it) are two surfaces: registration is last-wins and the vitals
49
+ * consumer keys its per-window sample history by this id, so a shared id
50
+ * makes the survivor answer for both — a held preview clock once spoke for a
51
+ * viewport that was visibly animating (measured 2026-08-30). Suffix, or
52
+ * sequence, anything that is not the document itself.
53
+ */
54
+ readonly id: string;
55
+ /** What the vitals row calls it out loud. */
56
+ readonly label: string;
57
+ /**
58
+ * Monotonic seconds of THIS surface's content time, or `null` when the host
59
+ * cannot currently make an honest comparison. Interactive document boot is
60
+ * never such a window: it publishes zero immediately because it performs no
61
+ * hidden simulation.
62
+ */
63
+ readonly contentClock: () => number | null;
64
+ /**
65
+ * Monotonic count of the times an ENGAGED transport (this document's
66
+ * animation transport, its simulation transport's play or step) advanced
67
+ * this surface's content time.
68
+ *
69
+ * Compared the same way the clock is: two readings, and only whether they
70
+ * DIFFER. A counter — not a "is a transport playing right now" boolean —
71
+ * because the question is about the window BETWEEN two samples, and a
72
+ * boolean answers about the instant of the sample: a single-frame step, or
73
+ * a transport paused between two reads, would both report "nothing engaged"
74
+ * over a window in which a transport was the only thing that ran.
75
+ *
76
+ * A surface that omits this publishes no transport at all, so ANY advance of
77
+ * its clock is unsanctioned — which is the honest reading for a surface (a
78
+ * preview card, a turntable) that has no ▶ to press.
79
+ */
80
+ readonly transportAdvances?: () => number;
81
+ }
82
+
83
+ const surfaces = new Map<string, DesignTimeSurface>();
84
+
85
+ /**
86
+ * Publish one live design-time surface. Returns its withdrawal — the ONE
87
+ * teardown path, and it is safe to call after the id has been re-registered by
88
+ * a later mount (it withdraws only its own entry).
89
+ */
90
+ export function registerDesignTimeSurface(surface: DesignTimeSurface): () => void {
91
+ surfaces.set(surface.id, surface);
92
+ return () => {
93
+ if (surfaces.get(surface.id) !== surface) return;
94
+ surfaces.delete(surface.id);
95
+ };
96
+ }
97
+
98
+ /** Every live design-time surface, for the vitals collector. */
99
+ export function allDesignTimeSurfaces(): readonly DesignTimeSurface[] {
100
+ return [...surfaces.values()];
101
+ }