@volter/sdk 0.0.0-stage → 0.5.203

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (523) hide show
  1. package/LICENSE +202 -0
  2. package/NOTICE +20 -0
  3. package/README.md +38 -3
  4. package/package.json +510 -4
  5. package/src/account.ts +210 -0
  6. package/src/chrome.ts +88 -0
  7. package/src/client.ts +1646 -0
  8. package/src/commands.ts +66 -0
  9. package/src/contributions.ts +619 -0
  10. package/src/css-numeric-style.ts +97 -0
  11. package/src/document-probe.ts +282 -0
  12. package/src/editor-view.ts +225 -0
  13. package/src/extension.ts +40 -0
  14. package/src/generations.ts +178 -0
  15. package/src/host.ts +1157 -0
  16. package/src/http-transport.browser.ts +14 -0
  17. package/src/http-transport.node.ts +19 -0
  18. package/src/index.ts +131 -0
  19. package/src/kit/CapabilityCoverageSection.tsx +185 -0
  20. package/src/kit/account-client.ts +333 -0
  21. package/src/kit/action-registry.ts +317 -0
  22. package/src/kit/active-product.ts +76 -0
  23. package/src/kit/active-project.ts +155 -0
  24. package/src/kit/adapter-editor-config.ts +25 -0
  25. package/src/kit/adapter-module.ts +7 -0
  26. package/src/kit/adapter-observation.ts +49 -0
  27. package/src/kit/animation/animation-clock.ts +479 -0
  28. package/src/kit/animation/stage-transport.ts +385 -0
  29. package/src/kit/api/assets.ts +365 -0
  30. package/src/kit/api/project-open.ts +355 -0
  31. package/src/kit/api/project-source.ts +180 -0
  32. package/src/kit/api/project-state.ts +110 -0
  33. package/src/kit/api/relay.ts +270 -0
  34. package/src/kit/api/themes.ts +45 -0
  35. package/src/kit/api-asset-library-wire.ts +45 -0
  36. package/src/kit/api-base.ts +10 -0
  37. package/src/kit/api-build.ts +99 -0
  38. package/src/kit/api-git-wire.ts +56 -0
  39. package/src/kit/api-logs.ts +92 -0
  40. package/src/kit/api-project-identity.ts +74 -0
  41. package/src/kit/api-settings.ts +36 -0
  42. package/src/kit/api-worktrees.ts +205 -0
  43. package/src/kit/asset-capabilities.ts +344 -0
  44. package/src/kit/asset-compare-core.ts +171 -0
  45. package/src/kit/asset-editor-context.tsx +101 -0
  46. package/src/kit/asset-events.ts +96 -0
  47. package/src/kit/asset-inspector-actions.ts +87 -0
  48. package/src/kit/asset-selection-viewer-registry.ts +113 -0
  49. package/src/kit/asset-selection.ts +146 -0
  50. package/src/kit/asset-thumbnails.ts +25 -0
  51. package/src/kit/asset-viewers.ts +115 -0
  52. package/src/kit/asset-workflow/asset-import-jobs.ts +106 -0
  53. package/src/kit/asset-workflow/asset-ledger-backend.ts +126 -0
  54. package/src/kit/asset-workflow/asset-ledger.ts +156 -0
  55. package/src/kit/asset-workflow/asset-materialization-report.ts +140 -0
  56. package/src/kit/asset-workflow/asset-pack-manifest.ts +320 -0
  57. package/src/kit/asset-workflow/asset-types.ts +142 -0
  58. package/src/kit/asset-workflow/audio-preview-player.ts +193 -0
  59. package/src/kit/asset-workflow/audio-waveform.ts +22 -0
  60. package/src/kit/asset-workflow/cloud-asset-client.ts +263 -0
  61. package/src/kit/asset-workflow/hosted-asset-materialization.ts +236 -0
  62. package/src/kit/asset-workflow/image-view-scale.ts +31 -0
  63. package/src/kit/asset-workflow/import-contract.ts +124 -0
  64. package/src/kit/asset-workflow/ledger-write-lock.ts +244 -0
  65. package/src/kit/asset-workflow/pixi-spritesheet.ts +197 -0
  66. package/src/kit/asset-workflow/preview-resource-lifetime.ts +44 -0
  67. package/src/kit/asset-workflow/project-asset-commands.ts +20 -0
  68. package/src/kit/asset-workflow/project-content.ts +288 -0
  69. package/src/kit/asset-workflow/project-source-index.ts +545 -0
  70. package/src/kit/asset-workflow/thumbnail-system.ts +256 -0
  71. package/src/kit/authoring/active-adapter.ts +200 -0
  72. package/src/kit/authoring/active-systems.ts +422 -0
  73. package/src/kit/authoring/adapter-key.ts +18 -0
  74. package/src/kit/authoring/authoring-asset-url.ts +27 -0
  75. package/src/kit/authoring/bootstrap-state.ts +49 -0
  76. package/src/kit/authoring/boundary-authoring-adapter.ts +189 -0
  77. package/src/kit/authoring/canvas-scene-guides.ts +84 -0
  78. package/src/kit/authoring/composite-authoring-adapter.ts +2109 -0
  79. package/src/kit/authoring/consumer-actions.ts +531 -0
  80. package/src/kit/authoring/design-time-layers.ts +852 -0
  81. package/src/kit/authoring/design-time-mount-registry.ts +244 -0
  82. package/src/kit/authoring/edit-mode-authoring.ts +637 -0
  83. package/src/kit/authoring/empty-project-authoring.ts +22 -0
  84. package/src/kit/authoring/instance-source-menu.ts +135 -0
  85. package/src/kit/authoring/layered-pick.ts +185 -0
  86. package/src/kit/authoring/mounted-root-subjects.ts +146 -0
  87. package/src/kit/authoring/no-authoring-adapter.ts +59 -0
  88. package/src/kit/authoring/object3d-document-persistence.ts +122 -0
  89. package/src/kit/authoring/panel-authoring.ts +121 -0
  90. package/src/kit/authoring/project-authoring-session.ts +105 -0
  91. package/src/kit/authoring/provenance.ts +99 -0
  92. package/src/kit/authoring/react-canvas-navigation.ts +259 -0
  93. package/src/kit/authoring/react-design-canvas-style.ts +20 -0
  94. package/src/kit/authoring/react-story-board.ts +917 -0
  95. package/src/kit/authoring/selection-scope.ts +195 -0
  96. package/src/kit/authoring/shell-document-ops.ts +169 -0
  97. package/src/kit/authoring/story-board-chrome-fit.ts +107 -0
  98. package/src/kit/authoring/story-board-presentation.ts +111 -0
  99. package/src/kit/authoring/three-root.ts +67 -0
  100. package/src/kit/authoring/viewport-tool-context.ts +73 -0
  101. package/src/kit/authoring/viewport-tool-owner.ts +38 -0
  102. package/src/kit/authoring/world-session-state.ts +101 -0
  103. package/src/kit/authoring-seam-evidence.ts +300 -0
  104. package/src/kit/availability-tick.ts +66 -0
  105. package/src/kit/bitmap-label.ts +120 -0
  106. package/src/kit/boot-routing.ts +392 -0
  107. package/src/kit/breakpoint-state.ts +43 -0
  108. package/src/kit/build-identity.ts +16 -0
  109. package/src/kit/bytes-codec.ts +62 -0
  110. package/src/kit/cancellation-reason.ts +58 -0
  111. package/src/kit/canvas-frames.ts +88 -0
  112. package/src/kit/capture-camera-pose.ts +77 -0
  113. package/src/kit/capture-size.ts +88 -0
  114. package/src/kit/chrome-registry.ts +159 -0
  115. package/src/kit/chrome-slot-registry.ts +91 -0
  116. package/src/kit/collaboration-client.ts +264 -0
  117. package/src/kit/collaboration-presence.ts +41 -0
  118. package/src/kit/command-dispatch.ts +19 -0
  119. package/src/kit/command-listener.ts +2182 -0
  120. package/src/kit/command-registry.ts +71 -0
  121. package/src/kit/component-board-registry.ts +205 -0
  122. package/src/kit/component-states-registry.ts +199 -0
  123. package/src/kit/components/AlignToolbar.tsx +204 -0
  124. package/src/kit/components/ApplicationMenus.tsx +372 -0
  125. package/src/kit/components/AssetEditorShell.tsx +216 -0
  126. package/src/kit/components/AssetInspectorToolSection.tsx +124 -0
  127. package/src/kit/components/BoardRulers.tsx +354 -0
  128. package/src/kit/components/CanvasAddNodeDialogs.tsx +529 -0
  129. package/src/kit/components/CanvasSceneViewport.tsx +1195 -0
  130. package/src/kit/components/ChromeSlot.tsx +20 -0
  131. package/src/kit/components/CodeView.tsx +470 -0
  132. package/src/kit/components/CompactInspectorShell.tsx +39 -0
  133. package/src/kit/components/ConsolePanel.tsx +273 -0
  134. package/src/kit/components/GameplaySessionTimeline.tsx +295 -0
  135. package/src/kit/components/InspectionProjection.tsx +932 -0
  136. package/src/kit/components/Inspector.tsx +270 -0
  137. package/src/kit/components/InspectorCanvasPreview.tsx +35 -0
  138. package/src/kit/components/InspectorFieldsSection.tsx +290 -0
  139. package/src/kit/components/InspectorStoriesSection.tsx +92 -0
  140. package/src/kit/components/InspectorToolSection.tsx +96 -0
  141. package/src/kit/components/InspectorTransformSection.tsx +245 -0
  142. package/src/kit/components/LightExplorerPanel.tsx +433 -0
  143. package/src/kit/components/MediaProperties.tsx +145 -0
  144. package/src/kit/components/ProjectHeader.tsx +328 -0
  145. package/src/kit/components/ReactCanvasControls.tsx +358 -0
  146. package/src/kit/components/RootSelectionOverlay.tsx +3688 -0
  147. package/src/kit/components/RootTextEditor.tsx +79 -0
  148. package/src/kit/components/SaveStatus.tsx +70 -0
  149. package/src/kit/components/SurfaceCrashBoundary.tsx +105 -0
  150. package/src/kit/components/SurfaceStateOverlay.tsx +24 -0
  151. package/src/kit/components/ToolContributionSurfaces.tsx +49 -0
  152. package/src/kit/components/ToolHost.tsx +380 -0
  153. package/src/kit/components/Toolbar.tsx +811 -0
  154. package/src/kit/components/TransientHint.tsx +44 -0
  155. package/src/kit/components/VersionControlSection.tsx +470 -0
  156. package/src/kit/components/ViewportOverlaysMenu.tsx +177 -0
  157. package/src/kit/components/VolterLogo.tsx +18 -0
  158. package/src/kit/components/WorktreeSwitcher.tsx +712 -0
  159. package/src/kit/components/account-documents.tsx +1162 -0
  160. package/src/kit/components/asset-documents.tsx +794 -0
  161. package/src/kit/components/asset-editor-persistence.ts +216 -0
  162. package/src/kit/components/asset-selection-section.tsx +545 -0
  163. package/src/kit/components/asset-thumbnails.tsx +307 -0
  164. package/src/kit/components/asset-viewers/AudioViewer.tsx +201 -0
  165. package/src/kit/components/asset-viewers/GenericJsonViewer.tsx +102 -0
  166. package/src/kit/components/asset-viewers/ImageViewer.tsx +300 -0
  167. package/src/kit/components/asset-viewers/JsonAssetDocument.tsx +98 -0
  168. package/src/kit/components/asset-viewers/OnlineAssetDetail.tsx +426 -0
  169. package/src/kit/components/asset-viewers/SourceAssetViewer.tsx +356 -0
  170. package/src/kit/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
  171. package/src/kit/components/asset-viewers/VideoViewer.tsx +101 -0
  172. package/src/kit/components/asset-viewers/shader-source.ts +144 -0
  173. package/src/kit/components/board-guides.ts +150 -0
  174. package/src/kit/components/canvas-scene-hotkeys.ts +37 -0
  175. package/src/kit/components/canvas-temporary-pivot.ts +34 -0
  176. package/src/kit/components/core-utilities.tsx +94 -0
  177. package/src/kit/components/inspector-preview-section.tsx +223 -0
  178. package/src/kit/components/inspector-revert-label.ts +20 -0
  179. package/src/kit/components/inspector-selection.ts +42 -0
  180. package/src/kit/components/inspector-stories-gating.ts +171 -0
  181. package/src/kit/components/inspector-transform-subject.ts +11 -0
  182. package/src/kit/components/inspector-transform.ts +88 -0
  183. package/src/kit/components/kind-documents.tsx +544 -0
  184. package/src/kit/components/primitives/DraftColorInput.tsx +74 -0
  185. package/src/kit/components/project-tool-documents.tsx +402 -0
  186. package/src/kit/components/scene-documents.tsx +221 -0
  187. package/src/kit/components/status-contributions.tsx +407 -0
  188. package/src/kit/components/tool-documents.tsx +302 -0
  189. package/src/kit/components/tool-schema-form.tsx +262 -0
  190. package/src/kit/components/use-after-paint.ts +41 -0
  191. package/src/kit/components/use-project-image-assets.ts +86 -0
  192. package/src/kit/components/workspace-history.ts +32 -0
  193. package/src/kit/components/world-documents.tsx +570 -0
  194. package/src/kit/components/world-overlay-gestures.ts +1939 -0
  195. package/src/kit/composite-screenshot.ts +2238 -0
  196. package/src/kit/content-entry-source-registry.ts +184 -0
  197. package/src/kit/contribution-surfaces.ts +48 -0
  198. package/src/kit/coverage/canvas-reveal.ts +192 -0
  199. package/src/kit/coverage/design-time-surfaces.ts +101 -0
  200. package/src/kit/coverage/ontology-invariants.ts +466 -0
  201. package/src/kit/coverage/session-vitals.ts +503 -0
  202. package/src/kit/crash-null-boundary.ts +36 -0
  203. package/src/kit/creation-site-edit.ts +1491 -0
  204. package/src/kit/creation-site-registry.ts +160 -0
  205. package/src/kit/delegate-harness-registry.ts +134 -0
  206. package/src/kit/document-areas.ts +70 -0
  207. package/src/kit/document-context-registry.ts +193 -0
  208. package/src/kit/document-open-registry.ts +200 -0
  209. package/src/kit/document-play-extension.ts +221 -0
  210. package/src/kit/document-preview-source.ts +20 -0
  211. package/src/kit/document-renderer-session.ts +138 -0
  212. package/src/kit/document-stage-sessions.ts +26 -0
  213. package/src/kit/document-viewports.ts +120 -0
  214. package/src/kit/editor-api.ts +46 -0
  215. package/src/kit/editor-chrome-capture.ts +136 -0
  216. package/src/kit/editor-commands.ts +176 -0
  217. package/src/kit/editor-console.ts +580 -0
  218. package/src/kit/editor-current-view.ts +56 -0
  219. package/src/kit/editor-document-probe.ts +1166 -0
  220. package/src/kit/editor-git-client.ts +115 -0
  221. package/src/kit/editor-hotkeys.ts +728 -0
  222. package/src/kit/editor-lease-view.ts +39 -0
  223. package/src/kit/editor-lease.ts +415 -0
  224. package/src/kit/editor-mode.ts +19 -0
  225. package/src/kit/editor-notifications.ts +140 -0
  226. package/src/kit/editor-presence.ts +563 -0
  227. package/src/kit/editor-presentation-activity.ts +58 -0
  228. package/src/kit/editor-presentation-notice.ts +42 -0
  229. package/src/kit/editor-runtime.tsx +147 -0
  230. package/src/kit/editor-server-response.ts +86 -0
  231. package/src/kit/editor-session-attribution.ts +85 -0
  232. package/src/kit/editor-session-mode.ts +54 -0
  233. package/src/kit/editor-state-facets.ts +74 -0
  234. package/src/kit/editor-view-presentation.ts +777 -0
  235. package/src/kit/environment-images.ts +58 -0
  236. package/src/kit/eyedropper-session.ts +60 -0
  237. package/src/kit/files/file-provider.ts +62 -0
  238. package/src/kit/files/project-files.ts +270 -0
  239. package/src/kit/finders/index.ts +137 -0
  240. package/src/kit/finders/scenes-from-entrypoint-selection.ts +387 -0
  241. package/src/kit/frame/frame-parts.ts +30 -0
  242. package/src/kit/framed-document-capture.ts +34 -0
  243. package/src/kit/game-globals-prelude.ts +143 -0
  244. package/src/kit/game-surface-defaults.ts +33 -0
  245. package/src/kit/gameplay-dom-recording.ts +318 -0
  246. package/src/kit/gameplay-export-state.ts +14 -0
  247. package/src/kit/gameplay-replay.ts +417 -0
  248. package/src/kit/gameplay-session-time.ts +9 -0
  249. package/src/kit/gameplay-sessions.ts +204 -0
  250. package/src/kit/hierarchy-component-marks.ts +298 -0
  251. package/src/kit/hierarchy-internals.ts +197 -0
  252. package/src/kit/hierarchy-kind-icon.ts +217 -0
  253. package/src/kit/hierarchy-menu-registry.ts +67 -0
  254. package/src/kit/hierarchy-node-rows.ts +307 -0
  255. package/src/kit/hierarchy-panel-view.ts +280 -0
  256. package/src/kit/hierarchy-projection.ts +76 -0
  257. package/src/kit/hierarchy-row-media.ts +45 -0
  258. package/src/kit/hierarchy-row-model.ts +308 -0
  259. package/src/kit/hierarchy-rows.ts +11 -0
  260. package/src/kit/hierarchy-walk.ts +86 -0
  261. package/src/kit/history/editor-session.ts +25 -0
  262. package/src/kit/history/history-commands.ts +147 -0
  263. package/src/kit/history/history-delegate.ts +187 -0
  264. package/src/kit/history/history-limit-notices.ts +43 -0
  265. package/src/kit/history/history-service.ts +1189 -0
  266. package/src/kit/history/persistence-coordinator.ts +35 -0
  267. package/src/kit/history/project-file-history.ts +386 -0
  268. package/src/kit/history/project-root-history-backends.ts +139 -0
  269. package/src/kit/history/resource-registry.ts +209 -0
  270. package/src/kit/history/snapshot-store.ts +103 -0
  271. package/src/kit/history/source-history-backend.ts +546 -0
  272. package/src/kit/history-types.ts +124 -0
  273. package/src/kit/hmr-registration-group.ts +67 -0
  274. package/src/kit/hmr-stable-react-context.ts +23 -0
  275. package/src/kit/hotkeys.ts +190 -0
  276. package/src/kit/inference-diagnostics.ts +69 -0
  277. package/src/kit/initial-project.ts +80 -0
  278. package/src/kit/inspection/active-subject.ts +571 -0
  279. package/src/kit/inspection/active-surface.ts +142 -0
  280. package/src/kit/inspection/compose-subject.ts +1055 -0
  281. package/src/kit/inspection/compose.ts +7 -0
  282. package/src/kit/inspection/display.ts +171 -0
  283. package/src/kit/inspection/document-subject.ts +109 -0
  284. package/src/kit/inspection/game-subject.ts +85 -0
  285. package/src/kit/inspection/null-subject.ts +119 -0
  286. package/src/kit/inspection/serialize.ts +357 -0
  287. package/src/kit/inspection/use-active-inspection.ts +180 -0
  288. package/src/kit/inspection-model.ts +542 -0
  289. package/src/kit/inspection-node-media.ts +58 -0
  290. package/src/kit/inspector-presentation.ts +203 -0
  291. package/src/kit/inspector-property-grouping.ts +64 -0
  292. package/src/kit/inspector-section-registry.ts +221 -0
  293. package/src/kit/instance-source-actions.ts +163 -0
  294. package/src/kit/js-heap.ts +71 -0
  295. package/src/kit/key-actions.ts +91 -0
  296. package/src/kit/keymap-presets.ts +428 -0
  297. package/src/kit/layout-policy.ts +31 -0
  298. package/src/kit/light-explorer-model.ts +134 -0
  299. package/src/kit/live-canvas-frame.ts +55 -0
  300. package/src/kit/live-document.ts +296 -0
  301. package/src/kit/live-gesture-lock.ts +50 -0
  302. package/src/kit/live-seam-evidence.ts +11 -0
  303. package/src/kit/live-session-registry.ts +220 -0
  304. package/src/kit/live-transition.ts +391 -0
  305. package/src/kit/manifest-project.ts +107 -0
  306. package/src/kit/module-fetch-diagnosis.ts +192 -0
  307. package/src/kit/mount-failure-report.ts +154 -0
  308. package/src/kit/native-selection-style.ts +497 -0
  309. package/src/kit/object3d-document-write-policy.ts +137 -0
  310. package/src/kit/packaged-runtime.ts +108 -0
  311. package/src/kit/palettes/maya.palette.json +57 -0
  312. package/src/kit/palettes/substance.palette.json +57 -0
  313. package/src/kit/performance-profiler.ts +367 -0
  314. package/src/kit/performance-sources.ts +69 -0
  315. package/src/kit/photograph-notice.ts +141 -0
  316. package/src/kit/play-boot-phase.ts +166 -0
  317. package/src/kit/play-camera-flight.ts +35 -0
  318. package/src/kit/png-encode.worker.ts +26 -0
  319. package/src/kit/presentation-surface.ts +248 -0
  320. package/src/kit/product-command.ts +90 -0
  321. package/src/kit/project-adapter.ts +1140 -0
  322. package/src/kit/project-asset-refresh.ts +23 -0
  323. package/src/kit/project-asset-roots.ts +68 -0
  324. package/src/kit/project-local-state.ts +151 -0
  325. package/src/kit/project-manager.ts +243 -0
  326. package/src/kit/project-module-changes.ts +201 -0
  327. package/src/kit/project-module-split.ts +270 -0
  328. package/src/kit/project-play-layers.ts +25 -0
  329. package/src/kit/project-provenance.ts +115 -0
  330. package/src/kit/project-ready.ts +42 -0
  331. package/src/kit/project-shape.ts +68 -0
  332. package/src/kit/project-tools.ts +107 -0
  333. package/src/kit/projection-types.ts +44 -0
  334. package/src/kit/readiness.ts +113 -0
  335. package/src/kit/renderer-resource-counts.ts +27 -0
  336. package/src/kit/reported-play-state.ts +90 -0
  337. package/src/kit/resolve-contributed-command.ts +14 -0
  338. package/src/kit/resolve-relative-specifier.ts +33 -0
  339. package/src/kit/retained-document-states.ts +91 -0
  340. package/src/kit/scene-document-plan.ts +320 -0
  341. package/src/kit/scene-live-open.ts +210 -0
  342. package/src/kit/scoped-game-css.ts +152 -0
  343. package/src/kit/served-url.ts +5 -0
  344. package/src/kit/session-close.ts +17 -0
  345. package/src/kit/session-tombstone.ts +127 -0
  346. package/src/kit/settings/settings-provider.ts +82 -0
  347. package/src/kit/settings-store.ts +348 -0
  348. package/src/kit/shell-document-state.ts +27 -0
  349. package/src/kit/shell-store-door.ts +45 -0
  350. package/src/kit/shell-store.ts +722 -0
  351. package/src/kit/source-conflict.ts +122 -0
  352. package/src/kit/stage-context.ts +377 -0
  353. package/src/kit/stage-invalidation.ts +25 -0
  354. package/src/kit/stage-store-registry.ts +69 -0
  355. package/src/kit/startup-failure.ts +80 -0
  356. package/src/kit/state-report-deferral.ts +73 -0
  357. package/src/kit/storage/host-files-storage.ts +97 -0
  358. package/src/kit/storage/http-storage.ts +174 -0
  359. package/src/kit/storage/index.ts +75 -0
  360. package/src/kit/storage/mem-storage.ts +158 -0
  361. package/src/kit/storage/path-lock.ts +44 -0
  362. package/src/kit/storage/paths.ts +26 -0
  363. package/src/kit/storage-types.ts +127 -0
  364. package/src/kit/stories/StoryPreviewMount.tsx +306 -0
  365. package/src/kit/stories/compose-project-stories.ts +255 -0
  366. package/src/kit/stories/prefabs-finder.ts +54 -0
  367. package/src/kit/stories/prefabs-from-stories.ts +182 -0
  368. package/src/kit/stories/project-story-regions.ts +24 -0
  369. package/src/kit/stories/story-capture.ts +579 -0
  370. package/src/kit/stories/story-declared-medium.ts +126 -0
  371. package/src/kit/stories/story-discovery.ts +176 -0
  372. package/src/kit/stories/story-dom-runtime.ts +78 -0
  373. package/src/kit/stories/story-grouping.ts +111 -0
  374. package/src/kit/stories/story-mount-turn.ts +27 -0
  375. package/src/kit/stories/story-presentation.ts +215 -0
  376. package/src/kit/stories/story-preview-component.ts +7 -0
  377. package/src/kit/stories/story-registry.ts +530 -0
  378. package/src/kit/stories-scope.ts +35 -0
  379. package/src/kit/story-document-openers.ts +36 -0
  380. package/src/kit/story-thumbnails.ts +47 -0
  381. package/src/kit/surface-keyboard.ts +101 -0
  382. package/src/kit/surface-state.ts +135 -0
  383. package/src/kit/system-seam-evidence.ts +72 -0
  384. package/src/kit/tab-census.ts +202 -0
  385. package/src/kit/tab-lifecycle-client.ts +227 -0
  386. package/src/kit/theme-library.ts +897 -0
  387. package/src/kit/theme-preference.ts +429 -0
  388. package/src/kit/three-viewport-presentation.ts +23 -0
  389. package/src/kit/tool-contribution-play.ts +74 -0
  390. package/src/kit/tool-loader.ts +1918 -0
  391. package/src/kit/transform-mode-request.ts +66 -0
  392. package/src/kit/transient-hint.ts +78 -0
  393. package/src/kit/transport-strip.tsx +174 -0
  394. package/src/kit/ui-source/adapter-region-includes.ts +238 -0
  395. package/src/kit/ui-source/file-region-resolver.ts +302 -0
  396. package/src/kit/ui-source/inspect.ts +775 -0
  397. package/src/kit/ui-source/source-write-backend.ts +605 -0
  398. package/src/kit/ui-source/tier-source-write-backend.ts +279 -0
  399. package/src/kit/user-local-state.ts +105 -0
  400. package/src/kit/viewport-activation-timings.ts +840 -0
  401. package/src/kit/viewport-editor-controls.ts +22 -0
  402. package/src/kit/viewport-presentation.ts +668 -0
  403. package/src/kit/viewport-surface-status.tsx +55 -0
  404. package/src/kit/wait-until.ts +37 -0
  405. package/src/kit/worker-call-metrics.ts +166 -0
  406. package/src/kit/workspace-areas.ts +191 -0
  407. package/src/kit/workspace-aux-commands.ts +11 -0
  408. package/src/kit/workspace-available-documents.ts +142 -0
  409. package/src/kit/workspace-core-utilities.ts +31 -0
  410. package/src/kit/workspace-document-ids.ts +59 -0
  411. package/src/kit/workspace-document-registry.ts +624 -0
  412. package/src/kit/workspace-document-restore.ts +146 -0
  413. package/src/kit/workspace-host-commands.ts +141 -0
  414. package/src/kit/workspace-persistence-gate.ts +40 -0
  415. package/src/kit/workspace-play-utilities.ts +44 -0
  416. package/src/kit/workspace-presets.ts +446 -0
  417. package/src/kit/workspace-regions.ts +276 -0
  418. package/src/kit/workspace-static-panels.ts +73 -0
  419. package/src/kit/workspace-status-registry.ts +121 -0
  420. package/src/kit/workspace-storage.ts +35 -0
  421. package/src/kit/workspace-style.ts +226 -0
  422. package/src/kit/workspace-utility-commands.ts +74 -0
  423. package/src/kit/workspace-utility-registry.ts +263 -0
  424. package/src/kit/world-adoption-event.ts +23 -0
  425. package/src/kit/world-adoption.ts +115 -0
  426. package/src/kit/world-canvas-viewport-state.ts +35 -0
  427. package/src/kit/world-document-routing.ts +104 -0
  428. package/src/kit/world-pan-state.ts +198 -0
  429. package/src/kit/write-pipe.ts +173 -0
  430. package/src/layout-arrangements.ts +5 -0
  431. package/src/layouts.tsx +108 -0
  432. package/src/looks.ts +16 -0
  433. package/src/project/output-roots.ts +73 -0
  434. package/src/project/tab-census.ts +155 -0
  435. package/src/project-tool-catalog.ts +104 -0
  436. package/src/selection.tsx +107 -0
  437. package/src/services.ts +18 -0
  438. package/src/session/build-report.ts +22 -0
  439. package/src/session/collaboration-types.ts +262 -0
  440. package/src/session/command-table.ts +327 -0
  441. package/src/session/discovery.ts +100 -0
  442. package/src/session/editor-brand.ts +48 -0
  443. package/src/session/editor-compatibility.ts +317 -0
  444. package/src/session/editor-control-lifecycle.ts +68 -0
  445. package/src/session/editor-control-protocol.ts +5 -0
  446. package/src/session/entrypoint-selection-readers.ts +66 -0
  447. package/src/session/entrypoint-selection-source.ts +120 -0
  448. package/src/session/game-css-scope.ts +30 -0
  449. package/src/session/hosted-attachment.ts +225 -0
  450. package/src/session/limited-view.ts +82 -0
  451. package/src/session/product-create.ts +24 -0
  452. package/src/session/product-locator.ts +478 -0
  453. package/src/session/project-module-url.ts +242 -0
  454. package/src/session/project-serving.ts +164 -0
  455. package/src/session/project-upgrade.ts +403 -0
  456. package/src/session/registry-format.ts +210 -0
  457. package/src/session/relative-path-guard.ts +56 -0
  458. package/src/session/scoped-game-css.ts +461 -0
  459. package/src/session/source-glob.ts +15 -0
  460. package/src/session/tool-contribution-convention.ts +123 -0
  461. package/src/session/workbench-locator.ts +712 -0
  462. package/src/session.ts +41 -0
  463. package/src/share.ts +160 -0
  464. package/src/source-analysis.ts +28 -0
  465. package/src/source-authoring.ts +439 -0
  466. package/src/tools/errors.ts +91 -0
  467. package/src/tools/provider-execution.ts +70 -0
  468. package/src/tools/registry.ts +341 -0
  469. package/src/tools/types.ts +159 -0
  470. package/src/transport.ts +100 -0
  471. package/src/types.ts +1693 -0
  472. package/src/views.ts +164 -0
  473. package/src/widgets/design-system.ts +93 -0
  474. package/src/widgets/editor-appearance.ts +151 -0
  475. package/src/widgets/editor-material.ts +83 -0
  476. package/src/widgets/icon-set-registry.ts +105 -0
  477. package/src/widgets/index.ts +71 -0
  478. package/src/widgets/inspector-widgets/AlignmentGrid.tsx +182 -0
  479. package/src/widgets/inspector-widgets/AssetSlotPicker.tsx +123 -0
  480. package/src/widgets/inspector-widgets/BorderEditor.tsx +309 -0
  481. package/src/widgets/inspector-widgets/ColorPicker.tsx +549 -0
  482. package/src/widgets/inspector-widgets/CurveEditor.tsx +359 -0
  483. package/src/widgets/inspector-widgets/FilterEditor.tsx +108 -0
  484. package/src/widgets/inspector-widgets/FontPicker.tsx +191 -0
  485. package/src/widgets/inspector-widgets/GradientEditor.tsx +623 -0
  486. package/src/widgets/inspector-widgets/ScrubbableInput.tsx +180 -0
  487. package/src/widgets/inspector-widgets/ShadowEditor.tsx +319 -0
  488. package/src/widgets/inspector-widgets/color-utils.ts +201 -0
  489. package/src/widgets/inspector-widgets/curve-utils.ts +212 -0
  490. package/src/widgets/inspector-widgets/index.ts +25 -0
  491. package/src/widgets/inspector-widgets/shared.tsx +140 -0
  492. package/src/widgets/interactive-edit-scope.ts +33 -0
  493. package/src/widgets/patterns/Dialog.tsx +140 -0
  494. package/src/widgets/patterns/Fields.tsx +44 -0
  495. package/src/widgets/patterns/List.tsx +25 -0
  496. package/src/widgets/patterns/StateSurface.tsx +40 -0
  497. package/src/widgets/patterns/Surfaces.tsx +122 -0
  498. package/src/widgets/patterns/Tabs.tsx +80 -0
  499. package/src/widgets/patterns/Toolbar.tsx +72 -0
  500. package/src/widgets/patterns/Tree.tsx +72 -0
  501. package/src/widgets/primitives/AnchoredMenu.tsx +260 -0
  502. package/src/widgets/primitives/Button.tsx +62 -0
  503. package/src/widgets/primitives/ColorInput.tsx +78 -0
  504. package/src/widgets/primitives/DraftTextInput.tsx +63 -0
  505. package/src/widgets/primitives/EditorIcon.tsx +157 -0
  506. package/src/widgets/primitives/FormControls.tsx +88 -0
  507. package/src/widgets/primitives/HoverPreview.tsx +96 -0
  508. package/src/widgets/primitives/JsonInput.tsx +113 -0
  509. package/src/widgets/primitives/Layout.tsx +100 -0
  510. package/src/widgets/primitives/Menu.tsx +161 -0
  511. package/src/widgets/primitives/NumberInput.tsx +169 -0
  512. package/src/widgets/primitives/Panel.tsx +80 -0
  513. package/src/widgets/primitives/SectionHeader.tsx +77 -0
  514. package/src/widgets/primitives/Text.tsx +54 -0
  515. package/src/widgets/primitives/ThemeRootPortal.tsx +52 -0
  516. package/src/widgets/primitives/Tooltip.tsx +204 -0
  517. package/src/widgets/primitives/Vec3Input.tsx +70 -0
  518. package/src/widgets/primitives/banner-tones.ts +32 -0
  519. package/src/widgets/primitives/clamp-to-viewport.ts +44 -0
  520. package/src/widgets/primitives/editor-icons.ts +254 -0
  521. package/src/widgets/primitives/panel-header-styles.ts +42 -0
  522. package/src/widgets/theme.ts +2841 -0
  523. package/src/widgets/z-index.ts +25 -0
@@ -0,0 +1,73 @@
1
+ import type { AuthoringAdapter } from '@volter/project/adapter';
2
+ import type { ShellStore } from '@volter/sdk/kit/shell-store';
3
+ import { adapterOnlyToolOwner, type ViewportToolOwner } from '@volter/sdk/kit/authoring/viewport-tool-owner';
4
+ import { CompositeAuthoringAdapter } from '@volter/sdk/kit/authoring/composite-authoring-adapter';
5
+ import { resolveThreeViewportRootId } from './three-root';
6
+ import { isRootHidden } from '@volter/sdk/kit/authoring/world-session-state';
7
+
8
+ /**
9
+ * The one native root whose viewport tools may claim the current selection.
10
+ *
11
+ * A composed game can contain several native surfaces at once, but editing
12
+ * chrome needs one unambiguous coordinate system and capability owner. Empty,
13
+ * organizational, and cross-root selections therefore resolve to `null`.
14
+ */
15
+ export interface ViewportToolContext extends ViewportToolOwner {
16
+ readonly adapter: AuthoringAdapter;
17
+ }
18
+
19
+ function compositeContext(
20
+ composite: CompositeAuthoringAdapter,
21
+ selectedIds: readonly string[],
22
+ ): ViewportToolContext | null {
23
+ const children = composite.childAdapters();
24
+ let owner: (typeof children)[number] | null = null;
25
+
26
+ for (const id of selectedIds) {
27
+ const child =
28
+ children.find((candidate) => composite.groupNodeId(candidate.worldId) === id) ??
29
+ children.find((candidate) => composite.ownerOf(id) === candidate.worldId);
30
+ // Kind/projection folders and stale ids do not claim native-world tools.
31
+ if (!child) return null;
32
+ // A heterogeneous selection has no single native editing context.
33
+ if (owner && owner.worldId !== child.worldId) return null;
34
+ owner = child;
35
+ }
36
+
37
+ return owner ? { worldId: owner.worldId, kind: owner.kind, adapter: owner.adapter } : null;
38
+ }
39
+
40
+ /**
41
+ * Resolve viewport-tool ownership from selection, never from which roots
42
+ * merely exist or happen to be visible.
43
+ */
44
+ export function resolveViewportToolContext(
45
+ adapter: AuthoringAdapter,
46
+ selectedIds: Iterable<string>,
47
+ ): ViewportToolContext | null {
48
+ const ids = [...selectedIds];
49
+ if (ids.length === 0) return null;
50
+ if (adapter instanceof CompositeAuthoringAdapter) return compositeContext(adapter, ids);
51
+
52
+ // Legacy/single-adapter sessions have no manifest kind metadata, and that
53
+ // fallback is `adapterOnlyToolOwner` — it speaks only the adapter contract,
54
+ // so it lives below the shell (`viewport-authoring-policy.ts`) as the gizmo
55
+ // viewport's own default. One copy, read from both sides.
56
+ const owner = adapterOnlyToolOwner(adapter, ids);
57
+ return owner ? { ...owner, adapter } : null;
58
+ }
59
+
60
+ /**
61
+ * Whether the selected owner is actually painted in this viewport. DOM
62
+ * layers follow their world eye; the manifest's sole Three root owns the 3D
63
+ * viewport chrome only while that root is visible.
64
+ */
65
+ export function isViewportToolContextVisible(
66
+ store: ShellStore,
67
+ context: ViewportToolOwner | null,
68
+ ): boolean {
69
+ if (!context) return false;
70
+ if (context.worldId !== null && isRootHidden(context.worldId)) return false;
71
+ if (context.kind !== 'three' || context.worldId === null) return true;
72
+ return resolveThreeViewportRootId(store) === context.worldId;
73
+ }
@@ -0,0 +1,38 @@
1
+ import type { AuthoringAdapter } from '@volter/project/adapter';
2
+
3
+ /**
4
+ * The native root whose viewport tools may claim the current selection, as far
5
+ * as the viewport cares: its KIND (only `three` lets the 3D chrome claim the
6
+ * surface) and its manifest root id (`null` for a single-adapter session).
7
+ *
8
+ * `authoring/viewport-tool-context.ts`'s `ViewportToolContext` is this plus the
9
+ * adapter, and is structurally assignable to it.
10
+ */
11
+ export interface ViewportToolOwner {
12
+ readonly worldId: string | null;
13
+ readonly kind: string;
14
+ }
15
+
16
+ /**
17
+ * Viewport-tool ownership for a SINGLE adapter — no composite, no manifest kind
18
+ * metadata to read.
19
+ *
20
+ * Structural and conservative, unchanged from where it was written
21
+ * (`authoring/viewport-tool-context.ts`, which now imports it): a rect-capable
22
+ * selection is DOM; a selection whose every node resolves to an `Object3D` is
23
+ * three; anything else advertises no kind-specific chrome rather than guessing.
24
+ * It speaks only the adapter contract, which is why it can be the default here.
25
+ */
26
+ export function adapterOnlyToolOwner(
27
+ adapter: AuthoringAdapter,
28
+ selectedIds: Iterable<string>,
29
+ ): ViewportToolOwner | null {
30
+ const ids = [...selectedIds];
31
+ if (ids.length === 0) return null;
32
+ if (ids.some((id) => adapter.hierarchy.node(id) === null)) return null;
33
+ if (adapter.rects) return { worldId: null, kind: 'dom' };
34
+ if (ids.every((id) => adapter.hierarchy.object3D?.(id) != null)) {
35
+ return { worldId: null, kind: 'three' };
36
+ }
37
+ return null;
38
+ }
@@ -0,0 +1,101 @@
1
+ /**
2
+ * World session state (B1) — a module-level subscribable singleton (same shape as
3
+ * `./mount-failure-report.ts`: a bare get/set slot, no subscribe of its own — every
4
+ * caller that mutates it follows up with `store.notifyIngestEdit()`, which every
5
+ * panel already re-renders off via `useSyncExternalStore(store.subscribe, …)`)
6
+ * holding THREE session-local, per-worldId toggles that are NEVER
7
+ * serialized/persisted (D9: "eye = session-local viewport visibility, never
8
+ * serialized" — generalized here to all three, none of which is an authored
9
+ * property):
10
+ *
11
+ * - `hidden` — the eye (A2/D9). LIFTED out of `GameHierarchy.tsx`'s former
12
+ * local `useState<Set<string>> hiddenRootIds` (module-private React state
13
+ * the design-time layer stack could never see) so `design-time-layers.ts`
14
+ * can hide/show a world's actual DOM layer, not just dim its hierarchy row.
15
+ * - `interactive` — forwards real pointer events to the layer (for testing
16
+ * hover/press states at design time); off by default (`pointer-events:none`
17
+ * is the layer's resting state — see `design-time-layers.ts`).
18
+ * - `pickLock` — stored here for B4 to consume (layered viewport picking,
19
+ * D12): a pick-locked layer is skipped by the topmost-first pick walk.
20
+ * B1 only stores/exposes the toggle; nothing reads it yet.
21
+ *
22
+ * Keyed by the RAW manifest world id (`CompositeChild.worldId` /
23
+ * `ResolvedAdapterRoot.id`) — the SAME id `design-time-layers.ts` gets from
24
+ * `composite.childAdapters()`, NOT the composite's synthetic `world:<id>`
25
+ * group-node id. `GameHierarchy.tsx` (whose rows ARE keyed by the group-node
26
+ * id) resolves the raw worldId via `compositeGroupBadge`'s `worldId` field
27
+ * before calling into this module — see that file's row component.
28
+ *
29
+ * A process-lifetime singleton (not project-scoped): switching projects
30
+ * within the same tab does not reset these toggles. That's a deliberate
31
+ * relaxation of the former per-mount-React-state behavior (which reset on
32
+ * every `GameHierarchy` remount) — "session-local" here means "this browser
33
+ * tab's session", matching D9's own framing; nothing depends on a
34
+ * project-switch reset.
35
+ */
36
+
37
+ export interface RootSessionState {
38
+ readonly hidden: boolean;
39
+ readonly interactive: boolean;
40
+ readonly pickLock: boolean;
41
+ }
42
+
43
+ const DEFAULT_STATE: RootSessionState = { hidden: false, interactive: false, pickLock: false };
44
+
45
+ const _states = new Map<string, RootSessionState>();
46
+
47
+ function get(worldId: string): RootSessionState {
48
+ return _states.get(worldId) ?? DEFAULT_STATE;
49
+ }
50
+
51
+ function patch(worldId: string, partial: Partial<RootSessionState>): void {
52
+ _states.set(worldId, { ...get(worldId), ...partial });
53
+ }
54
+
55
+ /** The eye (A2/D9): true while `worldId`'s design-time layer is hidden. */
56
+ export function isRootHidden(worldId: string): boolean {
57
+ return get(worldId).hidden;
58
+ }
59
+
60
+ export function setRootHidden(worldId: string, hidden: boolean): void {
61
+ patch(worldId, { hidden });
62
+ }
63
+
64
+ export function toggleRootHidden(worldId: string): void {
65
+ setRootHidden(worldId, !isRootHidden(worldId));
66
+ }
67
+
68
+ /** True while `worldId`'s layer forwards real pointer events (design-time
69
+ * hover/press testing) instead of its resting `pointer-events:none`. */
70
+ export function isRootInteractive(worldId: string): boolean {
71
+ return get(worldId).interactive;
72
+ }
73
+
74
+ export function setRootInteractive(worldId: string, interactive: boolean): void {
75
+ patch(worldId, { interactive });
76
+ }
77
+
78
+ export function toggleRootInteractive(worldId: string): void {
79
+ setRootInteractive(worldId, !isRootInteractive(worldId));
80
+ }
81
+
82
+ /** B4 will read this to skip a layer in the topmost-first pick walk; B1 only
83
+ * stores/exposes the toggle. */
84
+ export function isRootPickLocked(worldId: string): boolean {
85
+ return get(worldId).pickLock;
86
+ }
87
+
88
+ export function setRootPickLock(worldId: string, pickLock: boolean): void {
89
+ patch(worldId, { pickLock });
90
+ }
91
+
92
+ export function toggleRootPickLock(worldId: string): void {
93
+ setRootPickLock(worldId, !isRootPickLocked(worldId));
94
+ }
95
+
96
+ /** Test-only: drop every world's session state back to defaults so unit
97
+ * tests don't leak toggles across cases (this module is a process-lifetime
98
+ * singleton — see the header comment). */
99
+ export function _resetRootSessionStateForTest(): void {
100
+ _states.clear();
101
+ }
@@ -0,0 +1,300 @@
1
+ /**
2
+ * One structural and operational answer for an AuthoringAdapter.
3
+ *
4
+ * This module does not call providers. It inventories their compiler-pinned
5
+ * shapes and combines those receipts with receipts produced by real consumers
6
+ * and conformance probes. Shape can reject a malformed carrier immediately;
7
+ * it can never manufacture an operational pass.
8
+ */
9
+
10
+ import {
11
+ AUTHORING_ADAPTER_SHAPE,
12
+ AUTHORING_PROVIDER_KEYS,
13
+ AUTHORING_PROVIDER_SHAPES,
14
+ type AuthoringAdapter,
15
+ type AuthoringProviderKey,
16
+ gradeSeamCarrier,
17
+ gradeSeamEvidence,
18
+ HIERARCHY_PROVIDER_SHAPE,
19
+ type HierarchyProvider,
20
+ inspectSeamShape,
21
+ type SeamEvidenceReceipt,
22
+ type SeamEvidenceVerdict,
23
+ type SeamProofStage,
24
+ type SeamShape,
25
+ type StructuralWriteOutcome,
26
+ type WriteAck,
27
+ } from '@volter/project/adapter';
28
+ import { liveSeamEvidence, recordLiveSeamEvidence } from '@volter/sdk/kit/live-seam-evidence';
29
+
30
+ const EPOCHS = new WeakMap<object, string>();
31
+ let nextEpoch = 1;
32
+
33
+ /** Stable only for the lifetime of this adapter object. A cold remount creates
34
+ * a new adapter and therefore cannot inherit receipts from the old one. */
35
+ export function authoringAdapterEpoch(adapter: AuthoringAdapter): string {
36
+ const object = adapter as object;
37
+ const existing = EPOCHS.get(object);
38
+ if (existing) return existing;
39
+ const epoch = `authoring-${nextEpoch++}`;
40
+ EPOCHS.set(object, epoch);
41
+ return epoch;
42
+ }
43
+
44
+ function recordAuthoringReceipt(options: {
45
+ readonly adapter: AuthoringAdapter;
46
+ readonly seam: string;
47
+ readonly stage: SeamProofStage;
48
+ readonly outcome: 'pass' | 'fail';
49
+ readonly detail: string;
50
+ }): void {
51
+ const epoch = authoringAdapterEpoch(options.adapter);
52
+ const record = (seam: string, detail: string): void =>
53
+ recordLiveSeamEvidence({
54
+ seam,
55
+ subject: 'authoring-adapter',
56
+ epoch,
57
+ stage: options.stage,
58
+ outcome: options.outcome,
59
+ source: 'consumer',
60
+ detail,
61
+ });
62
+ record(options.seam, options.detail);
63
+ const segments = options.seam.split('.');
64
+ if (segments.length < 3) return;
65
+ const parent = segments.slice(0, -1).join('.');
66
+ record(
67
+ parent,
68
+ options.outcome === 'pass'
69
+ ? `${parent} served a real consumer ${options.stage}`
70
+ : `${parent} failed through its consumer: ${options.detail}`,
71
+ );
72
+ }
73
+
74
+ function writeAck(value: unknown): WriteAck | null {
75
+ if (!value || typeof value !== 'object') return null;
76
+ const candidate = value as { destination?: unknown; persisted?: unknown };
77
+ return typeof candidate.destination === 'string' && typeof candidate.persisted === 'boolean'
78
+ ? (candidate as WriteAck)
79
+ : null;
80
+ }
81
+
82
+ /** Record one real consumer call against the exact adapter object it used.
83
+ *
84
+ * The epoch, not a display label, is the identity boundary: one root can be
85
+ * reported under its manifest id in status and under `root` in the ingest
86
+ * mount report, while both names refer to this same adapter instance. The
87
+ * receipt is therefore stored under the neutral subject and rebound to the
88
+ * report's subject in {@link inspectAuthoringAdapterSeams} below.
89
+ *
90
+ * Promise-returning provider methods keep their original timing and rejection;
91
+ * success is recorded only after they settle. A thrown/rejected call records a
92
+ * failing receipt and is rethrown unchanged.
93
+ */
94
+ export function recordAuthoringConsumerUse<T>(options: {
95
+ readonly adapter: AuthoringAdapter;
96
+ readonly seam: string;
97
+ readonly stage: SeamProofStage;
98
+ readonly detail: string;
99
+ readonly run: () => T;
100
+ }): T {
101
+ const receipt = (outcome: 'pass' | 'fail', detail: string): void => {
102
+ recordAuthoringReceipt({ ...options, outcome, detail });
103
+ };
104
+ try {
105
+ const value = options.run();
106
+ if (value && typeof (value as { then?: unknown }).then === 'function') {
107
+ return Promise.resolve(value).then(
108
+ (settled) => {
109
+ receipt('pass', options.detail);
110
+ return settled;
111
+ },
112
+ (error) => {
113
+ receipt(
114
+ 'fail',
115
+ `${options.detail} failed: ${error instanceof Error ? error.message : String(error)}`,
116
+ );
117
+ throw error;
118
+ },
119
+ ) as unknown as T;
120
+ }
121
+ receipt('pass', options.detail);
122
+ return value;
123
+ } catch (error) {
124
+ receipt(
125
+ 'fail',
126
+ `${options.detail} failed: ${error instanceof Error ? error.message : String(error)}`,
127
+ );
128
+ throw error;
129
+ }
130
+ }
131
+
132
+ /** Record a write at the strength its own return value proves. A concrete
133
+ * WriteAck is a round trip even when it honestly says live-only; `void` proves
134
+ * only that the effect call returned. This keeps void-returning legacy lanes
135
+ * from manufacturing the stronger receipt their contract still owes. */
136
+ export function recordAuthoringWriteConsumerUse(options: {
137
+ readonly adapter: AuthoringAdapter;
138
+ readonly seam: string;
139
+ readonly detail: string;
140
+ readonly run: () => StructuralWriteOutcome;
141
+ }): StructuralWriteOutcome {
142
+ const success = (value: void | WriteAck): void | WriteAck => {
143
+ const ack = writeAck(value);
144
+ recordAuthoringReceipt({
145
+ adapter: options.adapter,
146
+ seam: options.seam,
147
+ stage: ack ? 'round-trip' : 'effect',
148
+ outcome: 'pass',
149
+ detail: ack
150
+ ? `${options.detail}: ${ack.destination} (${ack.persisted ? 'persisted' : 'live-only'})`
151
+ : `${options.detail}; the provider returned no write acknowledgement`,
152
+ });
153
+ return value;
154
+ };
155
+ const failure = (error: unknown): never => {
156
+ recordAuthoringReceipt({
157
+ adapter: options.adapter,
158
+ seam: options.seam,
159
+ stage: 'round-trip',
160
+ outcome: 'fail',
161
+ detail: `${options.detail} failed: ${error instanceof Error ? error.message : String(error)}`,
162
+ });
163
+ throw error;
164
+ };
165
+ try {
166
+ const value = options.run();
167
+ return value && typeof (value as { then?: unknown }).then === 'function'
168
+ ? Promise.resolve(value).then(success, failure)
169
+ : success(value as void | WriteAck);
170
+ } catch (error) {
171
+ return failure(error);
172
+ }
173
+ }
174
+
175
+ export interface AuthoringSeamEvidence {
176
+ readonly subject: string;
177
+ readonly epoch: string;
178
+ readonly receipts: readonly SeamEvidenceReceipt[];
179
+ readonly providers: Readonly<Record<AuthoringProviderKey, SeamEvidenceVerdict>>;
180
+ /**
181
+ * The hierarchy CARRIER: well-formed, and every member it advertises proven
182
+ * at that member's own required stage. This is the door
183
+ * `authoring/active-adapter.ts` refuses a malformed adapter with — a missing
184
+ * or mis-kinded `roots`/`node` only ever shows up as a member verdict, so
185
+ * the refusal needs the carrier grade and not the seam's own.
186
+ */
187
+ readonly hierarchy: SeamEvidenceVerdict;
188
+ /**
189
+ * The hierarchy WALK — the `editor.hierarchy` seam's own verdict, which is a
190
+ * different and weaker question than {@link hierarchy}: did a current-epoch
191
+ * operation walk this root's tree and find it finite, non-empty and
192
+ * reciprocal (`coverage/authoring-read-probe.ts`)?
193
+ *
194
+ * It exists because the CARRIER asks a strictly stronger question: every
195
+ * member the carrier advertises, proven at that member's own stage. It used
196
+ * to be an UNANSWERABLE one — `object3D` (required `operation`) and
197
+ * `idForObject3D` (then required `effect`) are optional-but-PRESENT on every
198
+ * three adapter, no production consumer records a receipt for either, and
199
+ * the read probe did not call them, so `gradeSeamCarrier` returned
200
+ * `unverified` on a perfectly reciprocal tree, forever. Both are pure
201
+ * lookups and are `operation` now, called and checked against the walk by
202
+ * `coverage/authoring-read-probe.ts`'s `objectLookupReceipts`, so the
203
+ * carrier answers its own question on a healthy adapter.
204
+ * The two grades stay separate regardless: this one is what
205
+ * `adapter-reach.ts`'s `captureEvidence` reads, and reading the CARRIER
206
+ * there once left the capture row's `ok` branch DEAD — a healthy
207
+ * root printed "no current-epoch hierarchy operation proves it projects
208
+ * this root's runtime" as `info` while the operation had in fact run and
209
+ * passed. MEASURED 2026-09-19 on a `--template game` scaffold: `info` with
210
+ * the reciprocity fix in, `gap` with the pre-fix adapter planted — the
211
+ * failure branch worked, the success branch could not be reached.
212
+ *
213
+ * Graded here, beside the carrier and off the SAME receipt set, so the two
214
+ * answers cannot drift apart in two modules.
215
+ */
216
+ readonly hierarchyWalk: SeamEvidenceVerdict;
217
+ }
218
+
219
+ export function inspectAuthoringAdapterSeams(options: {
220
+ readonly adapter: AuthoringAdapter;
221
+ readonly subject: string;
222
+ readonly epoch?: string | undefined;
223
+ readonly receipts?: readonly SeamEvidenceReceipt[] | undefined;
224
+ }): AuthoringSeamEvidence {
225
+ const { adapter, subject } = options;
226
+ const epoch = options.epoch ?? authoringAdapterEpoch(adapter);
227
+ const receipts: SeamEvidenceReceipt[] = [
228
+ ...inspectSeamShape<AuthoringAdapter>({
229
+ prefix: 'editor',
230
+ value: adapter,
231
+ shape: AUTHORING_ADAPTER_SHAPE,
232
+ subject,
233
+ epoch,
234
+ }),
235
+ ...inspectSeamShape<HierarchyProvider>({
236
+ prefix: 'editor.hierarchy',
237
+ value: adapter.hierarchy,
238
+ shape: HIERARCHY_PROVIDER_SHAPE,
239
+ subject,
240
+ epoch,
241
+ }),
242
+ ];
243
+
244
+ for (const [provider, shape] of Object.entries(AUTHORING_PROVIDER_SHAPES)) {
245
+ receipts.push(
246
+ ...inspectSeamShape({
247
+ prefix: `editor.${provider}`,
248
+ value: (adapter as unknown as Record<string, unknown>)[provider],
249
+ shape: shape as SeamShape<object>,
250
+ subject,
251
+ epoch,
252
+ }),
253
+ );
254
+ }
255
+ // An adapter epoch already identifies one concrete carrier. Rebind its live
256
+ // consumer receipts to this report's display subject so the same operation
257
+ // closes both the per-root status row (`worldId`) and the ingest report
258
+ // (`root`) without duplicating or guessing names at the call site.
259
+ receipts.push(
260
+ ...liveSeamEvidence.receipts({ epoch }).map((receipt) => ({ ...receipt, subject })),
261
+ );
262
+ if (options.receipts) receipts.push(...options.receipts);
263
+
264
+ const providers = {} as Record<AuthoringProviderKey, SeamEvidenceVerdict>;
265
+ for (const provider of AUTHORING_PROVIDER_KEYS) {
266
+ const nested = (AUTHORING_PROVIDER_SHAPES as Partial<Record<string, SeamShape<object>>>)[
267
+ provider
268
+ ];
269
+ providers[provider] = gradeSeamCarrier({
270
+ seam: `editor.${provider}`,
271
+ required: AUTHORING_ADAPTER_SHAPE[provider].required,
272
+ shape: nested,
273
+ subject,
274
+ epoch,
275
+ receipts,
276
+ });
277
+ }
278
+
279
+ return {
280
+ subject,
281
+ epoch,
282
+ receipts,
283
+ providers,
284
+ hierarchy: gradeSeamCarrier({
285
+ seam: 'editor.hierarchy',
286
+ required: AUTHORING_ADAPTER_SHAPE.hierarchy.required,
287
+ shape: HIERARCHY_PROVIDER_SHAPE as SeamShape<object>,
288
+ subject,
289
+ epoch,
290
+ receipts,
291
+ }),
292
+ hierarchyWalk: gradeSeamEvidence({
293
+ seam: 'editor.hierarchy',
294
+ required: AUTHORING_ADAPTER_SHAPE.hierarchy.required,
295
+ subject,
296
+ epoch,
297
+ receipts,
298
+ }),
299
+ };
300
+ }
@@ -0,0 +1,66 @@
1
+ /**
2
+ * ONE shared 250ms availability tick replacing the three independent
3
+ * `setInterval(…, 250)` pollers that W4 left behind (utility availability,
4
+ * the Dev utility's live-plane gate, and ConnectionStatus's networking-adapter
5
+ * poll).
6
+ *
7
+ * These gates all watch the SAME kind of out-of-band signal — a live play
8
+ * session's adapters appearing/disappearing without any store/registry
9
+ * notification — so they don't need three timers, three wakeups, and three
10
+ * interleaved re-render schedules; they need one heartbeat. The interval is
11
+ * refcounted: it starts with the first subscriber and stops with the last,
12
+ * so an idle editor (none of the three consumers mounted) runs no timer at
13
+ * all — strictly better than the three always-on intervals it replaces.
14
+ *
15
+ * `useSyncExternalStore`-shaped on purpose: consumers subscribe and SELECT
16
+ * the derived value they actually read (`getActiveDebug()` presence, a
17
+ * connection state, an availability fingerprint) — they re-render only when
18
+ * that value changes, never on the tick itself. The former version-counter
19
+ * hook (`useAvailabilityTick`) re-rendered every subscriber 4×/s
20
+ * unconditionally; with the workspace and every panel subscribed
21
+ * that measured ~27ms of React work per tick (~110ms/s) in an idle editor —
22
+ * found 2026-07-31 by the Profiler's long-animation-frame attribution.
23
+ */
24
+
25
+ import { useSyncExternalStore } from 'react';
26
+
27
+ const TICK_MS = 250;
28
+
29
+ let _version = 0;
30
+ let _intervalId: ReturnType<typeof setInterval> | null = null;
31
+ const _listeners = new Set<() => void>();
32
+
33
+ function onTick(): void {
34
+ _version++;
35
+ for (const fn of _listeners) fn();
36
+ }
37
+
38
+ /** Subscribe to the shared 250ms tick. Starts the timer on first subscriber,
39
+ * stops it with the last. Returns unsubscribe. */
40
+ export function subscribeAvailabilityTick(fn: () => void): () => void {
41
+ _listeners.add(fn);
42
+ if (_intervalId === null) _intervalId = setInterval(onTick, TICK_MS);
43
+ return () => {
44
+ _listeners.delete(fn);
45
+ if (_listeners.size === 0 && _intervalId !== null) {
46
+ clearInterval(_intervalId);
47
+ _intervalId = null;
48
+ }
49
+ };
50
+ }
51
+
52
+ /** Monotonic tick counter — exposed for tests that assert the timer runs. */
53
+ export function availabilityTickVersion(): number {
54
+ return _version;
55
+ }
56
+
57
+ /**
58
+ * Re-evaluate `select` on every shared availability tick, re-rendering the
59
+ * caller ONLY when its result changes (`Object.is`). `select` must return a
60
+ * primitive or a stable reference (an adapter identity, a joined-id string,
61
+ * a bitmask) — a fresh object every call would defeat the point and re-render
62
+ * per tick. It runs 4×/s plus once per render, so keep it a cheap read.
63
+ */
64
+ export function useAvailabilitySelector<T>(select: () => T): T {
65
+ return useSyncExternalStore(subscribeAvailabilityTick, select, select);
66
+ }