@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,197 @@
1
+ /**
2
+ * Pixi's native spritesheet sidecar — TexturePacker hash/array JSON, the
3
+ * same document AssetPack writes as `image.png.json`. The game loads THAT
4
+ * file (`Assets.load('images/game-screen.png.json')`); the PNG is the atlas
5
+ * page, not the authored unit.
6
+ */
7
+
8
+ export interface PixiSpritesheetFrame {
9
+ readonly name: string;
10
+ readonly x: number;
11
+ readonly y: number;
12
+ readonly width: number;
13
+ readonly height: number;
14
+ readonly rotated: boolean;
15
+ /** Untrimmed sprite canvas — Unity/Aseprite's document size. */
16
+ readonly sourceWidth: number;
17
+ readonly sourceHeight: number;
18
+ /** Where the packed pixels sit inside that canvas. */
19
+ readonly trimX: number;
20
+ readonly trimY: number;
21
+ }
22
+
23
+ export interface PixiSpritesheet {
24
+ readonly image: string;
25
+ readonly frames: readonly PixiSpritesheetFrame[];
26
+ }
27
+
28
+ export function spritesheetResolutionRank(name: string): number {
29
+ if (/@[0-9.]+x\./i.test(name)) return 1;
30
+ if (/\.webp\.json$/i.test(name)) return 2;
31
+ if (/\.png\.json$/i.test(name)) return 3;
32
+ return 0;
33
+ }
34
+
35
+ export function spritesheetFamilyKey(path: string): string {
36
+ const slash = path.lastIndexOf('/');
37
+ const dir = slash < 0 ? '' : path.slice(0, slash);
38
+ const file = slash < 0 ? path : path.slice(slash + 1);
39
+ const stem = file
40
+ .replace(/@[0-9.]+x/i, '')
41
+ .replace(/\.(png|webp|jpe?g)\.json$/i, '')
42
+ .replace(/\.json$/i, '');
43
+ return dir ? `${dir}/${stem}` : stem;
44
+ }
45
+
46
+ export function parsePixiSpritesheet(source: string): PixiSpritesheet | null {
47
+ let parsed: unknown;
48
+ try {
49
+ parsed = JSON.parse(source);
50
+ } catch {
51
+ return null;
52
+ }
53
+ if (!parsed || typeof parsed !== 'object') return null;
54
+ const record = parsed as {
55
+ frames?: unknown;
56
+ meta?: { image?: unknown };
57
+ };
58
+ const image = typeof record.meta?.image === 'string' ? fileName(record.meta.image) : '';
59
+ const frames = readFrames(record.frames);
60
+ if (!image || frames.length === 0) return null;
61
+ return { image, frames };
62
+ }
63
+
64
+ /** Content/open path: `assets/images/game-screen.png#satellite`. */
65
+ export function splitSpritesheetAssetPath(path: string): {
66
+ readonly sheetPath: string;
67
+ readonly frameName: string | null;
68
+ } {
69
+ const trimmed = path.replace(/^\//, '');
70
+ const hash = trimmed.lastIndexOf('#');
71
+ if (hash < 0) return { sheetPath: trimmed, frameName: null };
72
+ return { sheetPath: trimmed.slice(0, hash), frameName: trimmed.slice(hash + 1) || null };
73
+ }
74
+
75
+ /** Tab title: the frame name, never `game-screen.png#satellite`. */
76
+ export function spritesheetFrameTitle(path: string): string {
77
+ const { sheetPath, frameName } = splitSpritesheetAssetPath(path);
78
+ return frameName ?? sheetPath.split('/').pop() ?? path;
79
+ }
80
+
81
+ export function sidecarPathForSheet(sheetPath: string): string {
82
+ return `${sheetPath.replace(/^\//, '')}.json`;
83
+ }
84
+
85
+ export function sheetVariantsFor(image: string): readonly string[] {
86
+ const ext = image.match(/\.[a-z0-9]+$/i)?.[0] ?? '';
87
+ const stem = image.slice(0, image.length - ext.length);
88
+ return [
89
+ image,
90
+ `${stem}.png`,
91
+ `${stem}.webp`,
92
+ `${stem}.jpg`,
93
+ `${stem}@0.5x${ext}`,
94
+ `${stem}@0.5x.png`,
95
+ `${stem}@0.5x.webp`,
96
+ `${stem}@2x${ext}`,
97
+ `${stem}@2x.png`,
98
+ `${stem}@2x.webp`,
99
+ ];
100
+ }
101
+
102
+ function readFrames(frames: unknown): PixiSpritesheetFrame[] {
103
+ if (!frames || typeof frames !== 'object') return [];
104
+ if (Array.isArray(frames)) {
105
+ return frames.flatMap((entry) => {
106
+ if (!entry || typeof entry !== 'object') return [];
107
+ const row = entry as FrameRecord;
108
+ const name = typeof row.filename === 'string' ? row.filename : '';
109
+ const parsed = readFrame(row);
110
+ if (!name || !parsed) return [];
111
+ return [{ name: stripFrameExt(name), ...parsed }];
112
+ });
113
+ }
114
+ return Object.entries(frames as Record<string, unknown>).flatMap(([name, entry]) => {
115
+ if (!entry || typeof entry !== 'object') return [];
116
+ const parsed = readFrame(entry as FrameRecord);
117
+ if (!parsed) return [];
118
+ return [{ name: stripFrameExt(name), ...parsed }];
119
+ });
120
+ }
121
+
122
+ interface FrameRecord {
123
+ filename?: unknown;
124
+ frame?: unknown;
125
+ rotated?: unknown;
126
+ sourceSize?: unknown;
127
+ spriteSourceSize?: unknown;
128
+ }
129
+
130
+ function readFrame(row: FrameRecord): Omit<PixiSpritesheetFrame, 'name'> | null {
131
+ const box = readBox(row.frame);
132
+ if (!box) return null;
133
+ const source = readSize(row.sourceSize) ?? { width: box.width, height: box.height };
134
+ const trim = readPoint(row.spriteSourceSize);
135
+ return {
136
+ ...box,
137
+ rotated: row.rotated === true,
138
+ sourceWidth: source.width,
139
+ sourceHeight: source.height,
140
+ trimX: trim?.x ?? 0,
141
+ trimY: trim?.y ?? 0,
142
+ };
143
+ }
144
+
145
+ function readBox(frame: unknown): { x: number; y: number; width: number; height: number } | null {
146
+ if (!frame || typeof frame !== 'object') return null;
147
+ const box = frame as { x?: unknown; y?: unknown; w?: unknown; h?: unknown };
148
+ if (
149
+ typeof box.x !== 'number' ||
150
+ typeof box.y !== 'number' ||
151
+ typeof box.w !== 'number' ||
152
+ typeof box.h !== 'number'
153
+ ) {
154
+ return null;
155
+ }
156
+ return { x: box.x, y: box.y, width: box.w, height: box.h };
157
+ }
158
+
159
+ function readSize(value: unknown): { width: number; height: number } | null {
160
+ if (!value || typeof value !== 'object') return null;
161
+ const size = value as { w?: unknown; h?: unknown };
162
+ if (typeof size.w !== 'number' || typeof size.h !== 'number') return null;
163
+ return { width: size.w, height: size.h };
164
+ }
165
+
166
+ function readPoint(value: unknown): { x: number; y: number } | null {
167
+ if (!value || typeof value !== 'object') return null;
168
+ const point = value as { x?: unknown; y?: unknown };
169
+ if (typeof point.x !== 'number' || typeof point.y !== 'number') return null;
170
+ return { x: point.x, y: point.y };
171
+ }
172
+
173
+ /**
174
+ * Packed rect Pixi samples. A rotated TexturePacker frame stores the
175
+ * unrotated size in `frame` and occupies the swapped rect on the page.
176
+ */
177
+ export function packedFrameRect(
178
+ frame: Pick<PixiSpritesheetFrame, 'x' | 'y' | 'width' | 'height' | 'rotated'>,
179
+ ): {
180
+ x: number;
181
+ y: number;
182
+ width: number;
183
+ height: number;
184
+ } {
185
+ return frame.rotated
186
+ ? { x: frame.x, y: frame.y, width: frame.height, height: frame.width }
187
+ : { x: frame.x, y: frame.y, width: frame.width, height: frame.height };
188
+ }
189
+
190
+ function fileName(path: string): string {
191
+ const slash = path.lastIndexOf('/');
192
+ return slash < 0 ? path : path.slice(slash + 1);
193
+ }
194
+
195
+ function stripFrameExt(name: string): string {
196
+ return name.replace(/\.(png|webp|jpe?g)$/i, '');
197
+ }
@@ -0,0 +1,44 @@
1
+ export type PreviewResourceKind =
2
+ | 'webglContext'
3
+ | 'animationFrame'
4
+ | 'resizeObserver'
5
+ | 'objectUrl';
6
+
7
+ export interface PreviewResourceSnapshot {
8
+ webglContext: number;
9
+ animationFrame: number;
10
+ resizeObserver: number;
11
+ objectUrl: number;
12
+ peaks: Record<PreviewResourceKind, number>;
13
+ }
14
+
15
+ const current: Record<PreviewResourceKind, number> = {
16
+ webglContext: 0,
17
+ animationFrame: 0,
18
+ resizeObserver: 0,
19
+ objectUrl: 0,
20
+ };
21
+ const peaks = { ...current };
22
+
23
+ /** Local diagnostic counter used by stress tests and the Debugger; never uploads identifiers. */
24
+ export function registerPreviewResource(kind: PreviewResourceKind): () => void {
25
+ current[kind]++;
26
+ peaks[kind] = Math.max(peaks[kind], current[kind]);
27
+ let released = false;
28
+ return () => {
29
+ if (released) return;
30
+ released = true;
31
+ current[kind] = Math.max(0, current[kind] - 1);
32
+ };
33
+ }
34
+
35
+ export function previewResourceSnapshot(): PreviewResourceSnapshot {
36
+ return { ...current, peaks: { ...peaks } };
37
+ }
38
+
39
+ export function resetPreviewResourceCounters(): void {
40
+ for (const key of Object.keys(current) as PreviewResourceKind[]) {
41
+ current[key] = 0;
42
+ peaks[key] = 0;
43
+ }
44
+ }
@@ -0,0 +1,20 @@
1
+ export const PROJECT_ASSET_COMMANDS = {
2
+ open: { id: 'project-asset.open', shortcut: 'Enter' },
3
+ rename: { id: 'project-asset.rename', shortcut: 'F2' },
4
+ move: { id: 'project-asset.move', shortcut: null },
5
+ duplicate: { id: 'project-asset.duplicate', shortcut: 'Mod+D' },
6
+ delete: { id: 'project-asset.delete', shortcut: 'Delete' },
7
+ copyPath: { id: 'project-asset.copy-path', shortcut: 'Mod+Shift+C' },
8
+ reveal: { id: 'project-asset.reveal', shortcut: null },
9
+ refresh: { id: 'project-asset.refresh', shortcut: 'Mod+R' },
10
+ import: { id: 'project-asset.import', shortcut: null },
11
+ createFolder: { id: 'project-asset.create-folder', shortcut: 'Mod+Shift+N' },
12
+ } as const;
13
+
14
+ export type ProjectAssetCommandId =
15
+ (typeof PROJECT_ASSET_COMMANDS)[keyof typeof PROJECT_ASSET_COMMANDS]['id'];
16
+
17
+ export function projectAssetCommandIds(): readonly ProjectAssetCommandId[] {
18
+ return Object.values(PROJECT_ASSET_COMMANDS).map((command) => command.id);
19
+ }
20
+
@@ -0,0 +1,288 @@
1
+ /**
2
+ * WHAT THE CONTENT BROWSER SHOWS: the project's asset rows, their media
3
+ * facets, spritesheet expansion, and the orderings the gallery sorts by — plus
4
+ * the shapes the panel and its siblings type against.
5
+ *
6
+ * ITS OTHER HALF IS `project-source-index.ts`, and the split is load-bearing:
7
+ * this module is in the shell's EAGER closure (the Content panel is a static
8
+ * workspace panel), while indexing a project's own TSX for components and
9
+ * regions is TypeScript-AST work nothing at boot asks for. Keeping the two
10
+ * apart is what stops one panel's five presentation helpers from carrying
11
+ * the source-authoring integration's JSX transform and the five R3F prop-contract bindings into
12
+ * every editor boot — measured at EIGHT files, 2026-09-18. Add a discovery
13
+ * function to the index file; add a row-shaping one here.
14
+ *
15
+ * The one edge back is `import type { ProjectComponentEntry }`, which is
16
+ * erased at build and costs no closure. Never make it a value import.
17
+ */
18
+
19
+ import type { R3fComponentContract } from '@volter/sdk/source-authoring';
20
+ import { assetCapabilities } from '@volter/sdk/kit/asset-capabilities';
21
+ import {
22
+ parsePixiSpritesheet,
23
+ sheetVariantsFor,
24
+ spritesheetFamilyKey,
25
+ spritesheetResolutionRank,
26
+ } from './pixi-spritesheet';
27
+ import { ASSET_ROOTS, type AssetRootId } from '@volter/sdk/kit/project-asset-roots';
28
+
29
+ export interface ProjectComponentEntry {
30
+ name: string;
31
+ /** Project-root-relative source file. */
32
+ path: string;
33
+ line: number;
34
+ exported: boolean;
35
+ defaultExport: boolean;
36
+ /** Declared in a manifest root's own source module. This is an intent
37
+ * signal for file-local scene-building components without relying on a
38
+ * conventional filename or directory layout. */
39
+ declaredInRootEntry: boolean;
40
+ /** Static JSX uses of this definition in its own module. Root-entry locals
41
+ * need repeated/collection use as evidence that they are a reusable scene
42
+ * building block rather than one-off composition machinery. */
43
+ sourceUseCount: number;
44
+ sourceCollectionUse: boolean;
45
+ surface: 'three' | 'canvas' | 'dom' | 'unknown';
46
+ /** Inline SVG components are image assets, not general UI components. */
47
+ contentKind?: 'component' | 'image';
48
+ contract: R3fComponentContract;
49
+ }
50
+
51
+ export interface ProjectContentSpritesheetFrame {
52
+ readonly sheetPath: string;
53
+ readonly x: number;
54
+ readonly y: number;
55
+ readonly width: number;
56
+ readonly height: number;
57
+ readonly rotated: boolean;
58
+ readonly sourceWidth: number;
59
+ readonly sourceHeight: number;
60
+ readonly trimX: number;
61
+ readonly trimY: number;
62
+ }
63
+
64
+ export interface ProjectContentAsset {
65
+ /** Root-relative asset path (the root is {@link ProjectContentAsset.root}). */
66
+ path: string;
67
+ /** Which project asset root this row was listed from. `public` ships with the
68
+ * game; `references` is reference material the project keeps and no export
69
+ * copies — see `project-asset-roots.ts`. */
70
+ root: AssetRootId;
71
+ entry: ProjectContentAssetEntry;
72
+ /** Present when this row is one frame of a Pixi/TexturePacker sheet. */
73
+ spritesheet?: ProjectContentSpritesheetFrame;
74
+ }
75
+
76
+ export interface ProjectContentAssetEntry {
77
+ name: string;
78
+ type: 'file' | 'directory';
79
+ /** Bytes, when the backend reports it. ABSENT means unmeasured — not zero. */
80
+ size?: number;
81
+ /** Epoch ms, when the backend reports it. ABSENT means unmeasured — not 1970. */
82
+ modifiedAt?: number;
83
+ }
84
+
85
+ /** An asset medium, the component chip, or an OPEN document kind
86
+ * (ARCHITECTURE-CORE §The project model) — never a closed list. */
87
+ export type ProjectContentFacet = string;
88
+
89
+ /**
90
+ * Flatten every project asset root for the semantic Content view. Browse Files
91
+ * keeps using shallow listings and folder navigation.
92
+ *
93
+ * Both roots are walked the same way and their rows differ only by the `root`
94
+ * they carry: reference media is ORDINARY FILES in the project, so it is
95
+ * indexed by listing the directory, never by a side database or an import step.
96
+ * A project with no `references/` folder simply contributes nothing — an absent
97
+ * root lists empty (the server route's own rule), it does not fail.
98
+ *
99
+ * `failedListings` is returned beside the assets rather than folded into them:
100
+ * a directory whose listing FAILED contributes nothing, exactly like an empty
101
+ * one, and without this count the gallery cannot tell "the project has no
102
+ * content" from "we could not read it".
103
+ */
104
+ export async function collectProjectContentAssets(
105
+ list: (
106
+ root: string,
107
+ directory: string,
108
+ ) => Promise<{ ok: true; entries: ProjectContentAssetEntry[] } | { ok: false; reason: string }>,
109
+ roots: readonly AssetRootId[] = ASSET_ROOTS,
110
+ ): Promise<{ assets: ProjectContentAsset[]; failedListings: string[] }> {
111
+ const walked = await Promise.all(roots.map((root) => collectAssetRoot(list, root)));
112
+ return {
113
+ assets: walked.flatMap((result) => result.assets),
114
+ failedListings: walked.flatMap((result) => result.failedListings),
115
+ };
116
+ }
117
+
118
+ async function collectAssetRoot(
119
+ list: (
120
+ root: string,
121
+ directory: string,
122
+ ) => Promise<{ ok: true; entries: ProjectContentAssetEntry[] } | { ok: false; reason: string }>,
123
+ root: AssetRootId,
124
+ ): Promise<{ assets: ProjectContentAsset[]; failedListings: string[] }> {
125
+ const pending = [''];
126
+ const assets: ProjectContentAsset[] = [];
127
+ const failedListings: string[] = [];
128
+ let listings = 0;
129
+ while (pending.length > 0 && listings < 512) {
130
+ const batch = pending.splice(0, 8);
131
+ const results = await Promise.all(batch.map((directory) => list(root, directory)));
132
+ listings += batch.length;
133
+ results.forEach((result, index) => {
134
+ const directory = batch[index]!;
135
+ if (!result.ok) {
136
+ failedListings.push(`${root}/${directory}: ${result.reason}`);
137
+ return;
138
+ }
139
+ for (const entry of result.entries) {
140
+ const path = directory ? `${directory}/${entry.name}` : entry.name;
141
+ if (entry.type === 'directory') pending.push(path);
142
+ else assets.push({ path, root, entry });
143
+ }
144
+ });
145
+ }
146
+ return { assets, failedListings };
147
+ }
148
+
149
+ /**
150
+ * Replace packed atlas pages with the frames the game actually names.
151
+ * Sidecars (`image.png.json`) are Pixi's spritesheet document; the PNG is
152
+ * only the page. Resolution variants (`@0.5x`) of the same family collapse
153
+ * to the preferred sidecar.
154
+ *
155
+ * SHIPPED ASSETS ONLY. An atlas is a thing the game loads, so this reads the
156
+ * `public` root and leaves every other root's rows exactly as listed — a
157
+ * reference `.json` beside a reference `.png` is two files someone put there,
158
+ * not a sheet to unpack, and unpacking it would hide both behind frames that
159
+ * name a sheet no game reads.
160
+ */
161
+ export async function expandSpritesheetContentAssets(
162
+ assets: readonly ProjectContentAsset[],
163
+ readText: (path: string) => Promise<string | null>,
164
+ ): Promise<ProjectContentAsset[]> {
165
+ const shipped = assets.filter((asset) => asset.root === 'public');
166
+ const preferred = preferredSpritesheetSidecars(shipped);
167
+ const sheets = (
168
+ await Promise.all(
169
+ preferred.map(async (sidecar) => {
170
+ const source = await readText(sidecar.path);
171
+ if (!source) return null;
172
+ const parsed = parsePixiSpritesheet(source);
173
+ if (!parsed) return null;
174
+ return { sidecar, parsed };
175
+ }),
176
+ )
177
+ ).flatMap((entry) => (entry ? [entry] : []));
178
+
179
+ const hidden = new Set<string>();
180
+ for (const { sidecar, parsed } of sheets) {
181
+ hidden.add(sidecar.path);
182
+ const dir = parentDir(sidecar.path);
183
+ for (const variant of sheetVariantsFor(parsed.image)) {
184
+ hidden.add(dir ? `${dir}/${variant}` : variant);
185
+ }
186
+ for (const asset of shipped) {
187
+ if (spritesheetFamilyKey(asset.path) === spritesheetFamilyKey(sidecar.path)) {
188
+ hidden.add(asset.path);
189
+ }
190
+ }
191
+ }
192
+
193
+ const frames = sheets.flatMap(({ sidecar, parsed }) => {
194
+ const dir = parentDir(sidecar.path);
195
+ const sheetPath = dir ? `${dir}/${parsed.image}` : parsed.image;
196
+ return parsed.frames.map((frame) => ({
197
+ path: `${sheetPath}#${frame.name}`,
198
+ root: sidecar.root,
199
+ entry: {
200
+ name: `${frame.name}.png`,
201
+ type: 'file' as const,
202
+ // The frame inherits the SHEET's measurements; when the sheet was not
203
+ // measured, neither was the frame — it does not become 0 bytes here.
204
+ ...(sidecar.entry.size === undefined ? {} : { size: sidecar.entry.size }),
205
+ ...(sidecar.entry.modifiedAt === undefined ? {} : { modifiedAt: sidecar.entry.modifiedAt }),
206
+ },
207
+ spritesheet: {
208
+ sheetPath,
209
+ x: frame.x,
210
+ y: frame.y,
211
+ width: frame.width,
212
+ height: frame.height,
213
+ rotated: frame.rotated,
214
+ sourceWidth: frame.sourceWidth,
215
+ sourceHeight: frame.sourceHeight,
216
+ trimX: frame.trimX,
217
+ trimY: frame.trimY,
218
+ },
219
+ }));
220
+ });
221
+
222
+ // `hidden` holds PUBLIC paths, so the root is part of the test: a reference
223
+ // file that happens to share a sheet's path is a different file.
224
+ return [
225
+ ...assets.filter((asset) => asset.root !== 'public' || !hidden.has(asset.path)),
226
+ ...frames,
227
+ ];
228
+ }
229
+
230
+ function preferredSpritesheetSidecars(
231
+ assets: readonly ProjectContentAsset[],
232
+ ): ProjectContentAsset[] {
233
+ const best = new Map<string, ProjectContentAsset>();
234
+ for (const asset of assets) {
235
+ if (!/\.json$/i.test(asset.path)) continue;
236
+ const key = spritesheetFamilyKey(asset.path);
237
+ const current = best.get(key);
238
+ if (
239
+ !current ||
240
+ spritesheetResolutionRank(asset.path) > spritesheetResolutionRank(current.path)
241
+ ) {
242
+ best.set(key, asset);
243
+ }
244
+ }
245
+ return [...best.values()];
246
+ }
247
+
248
+ function parentDir(path: string): string {
249
+ const slash = path.lastIndexOf('/');
250
+ return slash < 0 ? '' : path.slice(0, slash);
251
+ }
252
+
253
+ export function projectContentAssetFacet(name: string): ProjectContentFacet {
254
+ const kind = assetCapabilities(name).kind;
255
+ if (kind === 'model' || kind === 'image' || kind === 'video' || kind === 'audio') {
256
+ return kind;
257
+ }
258
+ return 'other';
259
+ }
260
+
261
+ /** Lower values are more useful in the default gallery. */
262
+ export function projectContentAssetPriority(asset: ProjectContentAsset): number {
263
+ const capability = assetCapabilities(asset.entry.name);
264
+ if (capability.placeable && capability.runtimeReady) return 10;
265
+ if (capability.kind === 'model' && capability.runtimeReady) return 15;
266
+ if (capability.kind === 'prefab') return 25;
267
+ if (capability.runtimeReady && (capability.kind === 'image' || capability.kind === 'audio')) {
268
+ return 30;
269
+ }
270
+ if (capability.runtimeReady) return 40;
271
+ if (capability.importable) return 70;
272
+ return 90;
273
+ }
274
+
275
+ /** Lower values are more useful in the default Content gallery — a
276
+ * PRESENTATION rule, which is why it sits beside the gallery's other ordering
277
+ * helpers rather than with the discovery that produced the row. */
278
+ export function projectComponentPriority(component: ProjectComponentEntry): number {
279
+ const surface =
280
+ component.surface === 'three'
281
+ ? 0
282
+ : component.surface === 'canvas'
283
+ ? 10
284
+ : component.surface === 'dom'
285
+ ? 20
286
+ : 30;
287
+ return surface + (component.exported ? 0 : 4);
288
+ }