@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,728 @@
1
+ import { collectAllNodeIds } from '@volter/sdk/kit/authoring/active-adapter';
2
+ import {
3
+ copyAuthoringNodes,
4
+ cutAuthoringNodes,
5
+ duplicateAuthoringNode,
6
+ duplicateManyAuthoringNodes,
7
+ groupAuthoringNodes,
8
+ pasteAuthoringNodes,
9
+ removeAuthoringNode,
10
+ removeManyAuthoringNodes,
11
+ setAuthoringSelection,
12
+ unwrapAuthoringNode,
13
+ wrapAuthoringNode,
14
+ } from '@volter/sdk/kit/authoring/consumer-actions';
15
+ import { resolvePanelAuthoring } from '@volter/sdk/kit/authoring/panel-authoring';
16
+ import {
17
+ currentSelectionScopeId,
18
+ enterSelectedScope,
19
+ exitSelectionScope,
20
+ } from '@volter/sdk/kit/authoring/selection-scope';
21
+ import { activeSelectionIds, saveActiveAuthoring } from '@volter/sdk/kit/authoring/shell-document-ops';
22
+ import { resetRootPan } from '@volter/sdk/kit/world-pan-state';
23
+ import {
24
+ boxEditForId,
25
+ computeArrowNudgePatch,
26
+ readSpacingValues,
27
+ rectForId,
28
+ } from '@volter/sdk/kit/components/world-overlay-gestures';
29
+ import { openCommandPalette } from '@volter/sdk/kit/editor-commands';
30
+ import { editorConsole } from '@volter/sdk/kit/editor-console';
31
+ import type { EditorHostKeyAction } from '@volter/sdk/host';
32
+ import type { ShellStore } from '@volter/sdk/kit/shell-store';
33
+ import type { HistoryCommands } from '@volter/sdk/kit/history/history-commands';
34
+ import {
35
+ allowsAppUndoWhileEditable,
36
+ type HotkeyBinding,
37
+ installHotkeys,
38
+ isEditableTarget,
39
+ registerHotkeys,
40
+ } from '@volter/sdk/kit/hotkeys';
41
+ import { type KeyActionScope, registerKeyAction } from '@volter/sdk/kit/key-actions';
42
+ import {
43
+ type EditorKeyActionId,
44
+ keyChordsFor,
45
+ subscribeEditorKeymap,
46
+ } from '@volter/sdk/kit/keymap-presets';
47
+ import { stopAllLiveSessions } from '@volter/sdk/kit/live-session-registry';
48
+ import { showTransientHint } from '@volter/sdk/kit/transient-hint';
49
+ import { saveActiveWorkspaceDocument } from '@volter/sdk/kit/workspace-document-registry';
50
+ import { toggleWorkspaceFocus } from '@volter/sdk/kit/workspace-host-commands';
51
+ import { cycleEditorWorkspace } from './workspace-presets';
52
+ import { toggleConsoleUtility } from '@volter/sdk/kit/workspace-utility-commands';
53
+
54
+ // 'inspector' belongs here: the inspector shows the SELECTED NODE, so a user
55
+ // who just edited a field expects node-scoped clipboard/duplicate to still
56
+ // answer (a human pressed Ctrl+D after typing a color and read the silence as
57
+ // "duplicate is broken" — runhuman pass 41). Focused text inputs stay safe:
58
+ // isEditableTarget refuses there, and clipboard keys keep their native-DOM
59
+ // `when` guard.
60
+ const AUTHORING_SELECTION_SCOPES = ['viewport', 'hierarchy', 'inspector'] as const;
61
+
62
+ /**
63
+ * D4 (spec27 §6 D4, §8 "Keyboard / undo / pan-zoom" row) — RECONCILED by the
64
+ * `overlay-panzoom` unit (D-E's own reconciliation note).
65
+ *
66
+ * Space-pan is BUILT: `RootSelectionOverlay.tsx`'s own Space-held +
67
+ * pointer-drag handling (its `spaceHeldRef`/`panDragRef`), writing the shared
68
+ * `world-pan-state.ts` singleton, which `design-time-layers.ts` applies to
69
+ * every world-layer host IN LOCKSTEP with the overlay's own wrapper — a pure
70
+ * CSS `transform: translate()` on both. Not registered here in
71
+ * `editor-hotkeys.ts`'s `registerHotkeys` array because that registry is a
72
+ * single-fire-per-keydown dispatcher with no "held" concept (see
73
+ * `hotkeys.ts`); Space-pan needs a literal hold state, so it follows the
74
+ * SAME precedent this file's own vertex-snap `V`-key handling below already
75
+ * set (a raw `window` keydown/keyup pair) — just owned by the overlay
76
+ * component instead of this file, since the gesture IS a pointer-drag over
77
+ * the overlay's own interaction layer, not a stateless action like
78
+ * duplicate/delete/nudge above.
79
+ *
80
+ * Zoom-fit/selection is a stated EXCLUDE — evidence checked (not assumed):
81
+ * the 3D viewport (`world-root-stage.ts`/`editor-viewport.ts`) already has a
82
+ * real zoom substrate (Three.js `OrbitControls`, numpad view presets), so
83
+ * zoom-fit there is pure duplication, not a gap. The react/DOM world
84
+ * surface's `RectProvider.rect(id)` is `getBoundingClientRect()`-derived and
85
+ * host-relative (`react-world-authoring-adapter.ts`'s `toHostRelative`) —
86
+ * UNLIKE pan (a pure translation, which cancels out of that subtraction with
87
+ * zero consumer changes, per `world-pan-state.ts`'s own soundness doc
88
+ * comment), a host `scale()` bakes the zoom factor into every rect AND every
89
+ * screen-space gesture delta (`toHostLocal`), so it would require an
90
+ * explicit zoom-aware conversion at all ~14 host-relative chrome consumers
91
+ * (selection/hover box, 8 handles, rotate, labels, spacing bands, measure
92
+ * lines, snap guides, badges, parent outline, drag-ghost, reorder marker,
93
+ * empty-container hints, align-toolbar anchor, marquee) and the 3
94
+ * screen-delta gesture patches (`computeResizePatch`/`computeMovePatch`/
95
+ * `computeSpacingPatch`) — a foundation rebase against the ~2360-test unit
96
+ * suite + the full 27x e2e series (all pinned at the implicit `scale=1`
97
+ * frame) that is disproportionate to one keyboard-row affordance the
98
+ * visual-edit reference itself only had live in its own demo host, not its
99
+ * reusable library. No dead keybinding is registered for it.
100
+ */
101
+
102
+ // The five action functions below (`duplicateSelection` … `nudgeSelection`)
103
+ // are exported for two reasons: `registerEditorShellHotkeys` wires them to
104
+ // their keybindings below, AND `editor-hotkeys.test.ts` unit-tests the
105
+ // capability-gate behavior (structure/boxEdit absent -> no-op) directly
106
+ // against them, without needing a full `EditorViewport`/canvas fixture.
107
+
108
+ /** Entity clipboard shortcuts yield to ordinary DOM text selection. Editable
109
+ * controls already yield in `hotkeys.ts`; this covers selectable labels/logs
110
+ * inside the hierarchy or viewport scopes. */
111
+ export function shouldHandleEditorClipboard(): boolean {
112
+ return (globalThis.getSelection?.()?.toString() ?? '').length === 0;
113
+ }
114
+
115
+ /**
116
+ * THE SUBJECT THESE ACTIONS ACT ON — the ACTIVE DOCUMENT's selection, which is
117
+ * the same place they already take their adapter from.
118
+ *
119
+ * `store.selectedEntityIds` is the SHELL store's set, and for a document whose
120
+ * adapter owns its own selection it is a different set entirely: every one of
121
+ * these functions resolved its adapter through `resolvePanelAuthoring` and then
122
+ * read the ids from the shell, so on such a document they saw an empty
123
+ * selection and returned at the guard — a silent no-op with nothing to report.
124
+ *
125
+ * MEASURED 2026-09-21 on the Blender Model document, whose Outliner adapter
126
+ * publishes its selection in Blender's own row ids: with the Sphere selected
127
+ * and highlighted in the panel, `volter.edit.delete` ran, found
128
+ * `store.selectedEntityIds` empty and deleted nothing — X and Shift+D were
129
+ * dead for every object on that document. `activeSelectionIds` is what
130
+ * `editor.status()` already reports and what the hierarchy panel already
131
+ * draws, so reading it here makes the three agree instead of two against one.
132
+ */
133
+ function actionSelectionIds(store: ShellStore): string[] {
134
+ return activeSelectionIds(store);
135
+ }
136
+
137
+ export async function copySelection(store: ShellStore): Promise<void> {
138
+ const ids = actionSelectionIds(store);
139
+ if (ids.length === 0) return;
140
+ await copyAuthoringNodes(resolvePanelAuthoring(store).adapter, ids);
141
+ }
142
+
143
+ export async function cutSelection(store: ShellStore): Promise<void> {
144
+ const ids = actionSelectionIds(store);
145
+ if (ids.length === 0) return;
146
+ await cutAuthoringNodes(resolvePanelAuthoring(store).adapter, ids);
147
+ }
148
+
149
+ /** Ordinary Paste creates siblings: the current selection's native parent is
150
+ * the destination. With no selection, the adapter's document root is used. */
151
+ export async function pasteSelection(store: ShellStore): Promise<void> {
152
+ const adapter = resolvePanelAuthoring(store).adapter;
153
+ const selectedId = actionSelectionIds(store)[0];
154
+ const parentId = selectedId ? (adapter.hierarchy.node(selectedId)?.parentId ?? null) : null;
155
+ await pasteAuthoringNodes(adapter, parentId);
156
+ }
157
+
158
+ /**
159
+ * D4 (spec27 §6 D4 "Ctrl+D duplicate, Del/Backspace delete — route through
160
+ * adapter.structure.* (capability-gated)"). `store.selectedEntityIds` is the
161
+ * shared, adapter-routed selection set (every adapter's own `selection.set`
162
+ * funnels into it); the ACTION goes through the active adapter's
163
+ * `StructureProvider`, and is a capability-gated no-op when that adapter has
164
+ * none (e.g. the ingested `react-dom` adapter, spec:308-309).
165
+ *
166
+ * There is no fork here: every adapter is reached the same way, through its
167
+ * `StructureProvider`.
168
+ *
169
+ * Each id's ack is AWAITED before the next fires, exactly as `deleteSelection`
170
+ * awaits `remove`: for a source lane every duplicate in the loop rewrites the
171
+ * SAME file, and two un-awaited writes each read it before either wrote back,
172
+ * so whichever landed second silently loses the first. That is why the id and
173
+ * the ack come back together (`StructuralIdWrite`) — a synchronous id with a
174
+ * `void`ed write would leave this loop nothing to await. Awaiting a lane whose
175
+ * duplicate is in-memory (`ack: undefined`) is a harmless no-op.
176
+ */
177
+ /**
178
+ * SERIALIZED ACROSS PRESSES. One invocation already awaits each id's write,
179
+ * but a BURST of Ctrl+D presses ran concurrently: every press read the same
180
+ * pre-write selection and the same stale source, so five presses produced five
181
+ * copies with one name at one position, stacked (runhuman pass 66 —
182
+ * "they are all stacked somewhere together... the names are HeroBox 2, 2, 2").
183
+ * Queuing makes each press start from what the previous one produced, which is
184
+ * also what a human means by pressing it again: a chain of copies, each named
185
+ * and offset from the last.
186
+ */
187
+ let duplicateQueue: Promise<void> = Promise.resolve();
188
+
189
+ export function duplicateSelection(store: ShellStore): Promise<void> {
190
+ const queued = duplicateQueue.then(() => runDuplicateSelection(store));
191
+ // The queue never inherits a rejection — one failed duplicate must not
192
+ // strand every later press (the commit-queue rule in the canvas lane).
193
+ duplicateQueue = queued.then(
194
+ () => undefined,
195
+ () => undefined,
196
+ );
197
+ return queued;
198
+ }
199
+
200
+ async function runDuplicateSelection(store: ShellStore): Promise<void> {
201
+ const selection = actionSelectionIds(store);
202
+ if (selection.length === 0) return;
203
+ const adapter = resolvePanelAuthoring(store).adapter;
204
+ const structure = adapter.structure;
205
+ if (!structure) return;
206
+ // Immediate acknowledgement: a source-lane duplicate takes a visible moment
207
+ // (write + remount), and the silence in between reads as a dead hotkey — a
208
+ // human pressed Ctrl+D repeatedly and ended up with three copies (runhuman
209
+ // pass 41). The hint is published BEFORE the first await and replaced by the
210
+ // done line when the writes land.
211
+ const label =
212
+ selection.length === 1
213
+ ? (adapter.hierarchy.node(selection[0] as string)?.label ?? 'selection')
214
+ : `${selection.length} objects`;
215
+ showTransientHint(`Duplicating ${label}…`);
216
+ if (structure.duplicateMany) {
217
+ const ack = await duplicateManyAuthoringNodes(adapter, selection);
218
+ if (ack && !ack.persisted) {
219
+ showTransientHint(ack.destination);
220
+ return;
221
+ }
222
+ } else {
223
+ for (const id of selection) {
224
+ const ack = await duplicateAuthoringNode(adapter, id).ack;
225
+ if (ack && !ack.persisted) {
226
+ showTransientHint(ack.destination);
227
+ return;
228
+ }
229
+ }
230
+ }
231
+ showTransientHint(`Duplicated ${label}`);
232
+ }
233
+
234
+ /**
235
+ * D4.R2 (spec27 §6 D4 reopen) — a multi-node override delete prefers the
236
+ * batched `structure.removeMany` (ONE undo entry for the whole selection,
237
+ * matching the first-party `store.deleteEntities` batched-undo semantics
238
+ * below) when the active adapter implements it; falls back to the per-id
239
+ * `structure.remove` loop for any adapter that doesn't (N undo entries).
240
+ * `await`ed the same way `remove` is (harmless no-op for a synchronous/
241
+ * in-memory implementer) — see `StructureProvider.removeMany`'s doc comment.
242
+ *
243
+ * SOURCE-CORRUPTION FIX (bug-panel reopen, post-D4.R2) + DELETE-ORDER-
244
+ * RESIDUAL FIX (bug-panel follow-up, post-50f90a6d): the per-id fallback loop
245
+ * used to fire `structure.remove(id)` for every id in RAW selection order —
246
+ * document/top-first, the same order a marquee/DFS walk produces — with NO
247
+ * `await` between iterations. For an adapter whose per-op target offset is
248
+ * resolved from an index that is only refreshed by a real reparse (never
249
+ * between same-file writes — `ReactRootAuthoringAdapter`'s `OidStore.index`),
250
+ * that is a real, default-gesture-reachable source-corruption hazard:
251
+ * deleting an EARLIER element first shifts every LATER element's still-stale
252
+ * `{line, col}` out from under it, and firing every write in the same tick
253
+ * can race the underlying network request, letting a later write silently
254
+ * clobber an earlier one. Both mechanisms are fixed for the fallback loop,
255
+ * together (see the CORRECTNESS INVARIANT comment on
256
+ * `ReactRootAuthoringAdapter.structure`'s per-id `remove` for the full
257
+ * soundness argument, including its own remaining caveat):
258
+ * 1. sort `ids` into REVERSE DOCUMENT ORDER (bottom-most/deepest first) —
259
+ * derived from the SAME DFS pre-order `collectAllNodeIds` walks (the
260
+ * marquee/select-all candidate order), reversed, so a selected
261
+ * descendant is always deleted before a selected ancestor;
262
+ * 2. `await` each `structure.remove(id)` before starting the next, so
263
+ * write N only ever begins once write N-1 has landed on disk.
264
+ * A synchronous/in-memory `remove` (e.g. `UIAuthoringAdapter`'s) is
265
+ * unaffected — awaiting a non-promise return is a harmless no-op, and its own
266
+ * `removeMany` batches instead of ever reaching this loop. This fallback loop
267
+ * is sound ONLY when `collectAllNodeIds`' walk order matches true SOURCE
268
+ * order — `ReactRootAuthoringAdapter` now implements `removeMany` (a single
269
+ * shared-snapshot batched delete, order-independent by construction) exactly
270
+ * so THIS loop is never reached for it; it stays here, documented and tested,
271
+ * as the honest degrade for any override adapter that has no batched delete.
272
+ */
273
+ export async function deleteSelection(store: ShellStore): Promise<void> {
274
+ const ids = actionSelectionIds(store);
275
+ if (ids.length === 0) return;
276
+ const adapter = resolvePanelAuthoring(store).adapter;
277
+ const structure = adapter.structure;
278
+ if (!structure) return;
279
+ if (structure.removeMany) {
280
+ await removeManyAuthoringNodes(adapter, ids);
281
+ } else {
282
+ // Reverse DOCUMENT order (bottom-most/deepest first) — see this
283
+ // function's own doc comment. `collectAllNodeIds` walks the adapter's
284
+ // hierarchy in the same DFS pre-order (parent-before-child, top-first)
285
+ // a marquee/select-all uses; an id outside that walk (should not
286
+ // happen — every selected id came FROM this adapter's own hierarchy)
287
+ // sorts last (rank -1) as a defensive fallback, never a throw.
288
+ const rank = new Map(collectAllNodeIds(adapter).map((id, i) => [id, i]));
289
+ const ordered = [...ids].sort((a, b) => (rank.get(b) ?? -1) - (rank.get(a) ?? -1));
290
+ for (const id of ordered) await removeAuthoringNode(adapter, id);
291
+ }
292
+ }
293
+
294
+ /** D4 — `Ctrl+Alt+G` wrap / `Ctrl+Shift+G` unwrap (spec §6 D4, §5 "wrap/
295
+ * unwrap ... via `structure.*`"): no first-party equivalent exists (a 3D
296
+ * entity can't be "wrapped"), so this is override-only, capability-gated on
297
+ * the OPTIONAL `structure.wrap`/`structure.unwrap` (absent for the
298
+ * ingested `react-dom` adapter and the first-party three adapter alike —
299
+ * both correctly no-op). Applies to every selected id, same multi-select
300
+ * loop `duplicateSelection`/`deleteSelection` use. */
301
+ /** Awaited per id for the same reason `deleteSelection` awaits `remove`: two
302
+ * in-flight structural writes against the SAME source file each read it before
303
+ * either wrote back, and whichever lands second silently loses the first. The
304
+ * awaited value is that edit's own `{destination, persisted}` ack. */
305
+ export async function wrapSelection(store: ShellStore): Promise<void> {
306
+ const ids = actionSelectionIds(store);
307
+ if (ids.length === 0) return;
308
+ const adapter = resolvePanelAuthoring(store).adapter;
309
+ const structure = adapter.structure;
310
+ if (!structure?.wrap) return;
311
+ for (const id of ids) await wrapAuthoringNode(adapter, id);
312
+ }
313
+
314
+ export async function unwrapSelection(store: ShellStore): Promise<void> {
315
+ const ids = actionSelectionIds(store);
316
+ if (ids.length === 0) return;
317
+ const adapter = resolvePanelAuthoring(store).adapter;
318
+ const structure = adapter.structure;
319
+ if (!structure?.unwrap) return;
320
+ for (const id of ids) await unwrapAuthoringNode(adapter, id);
321
+ }
322
+
323
+ /** Group the current selection as one real spatial parent when its adapter
324
+ * supports lossless grouping. One provider call owns one undo entry, and its
325
+ * ack is awaited the same way `wrapSelection` awaits `wrap` — a caller that
326
+ * awaits this function has awaited the byte. */
327
+ export async function groupSelection(store: ShellStore): Promise<void> {
328
+ const ids = actionSelectionIds(store);
329
+ if (ids.length === 0) return;
330
+ const adapter = resolvePanelAuthoring(store).adapter;
331
+ if (!adapter.structure?.group) return;
332
+ await groupAuthoringNodes(adapter, ids).ack;
333
+ }
334
+
335
+ /**
336
+ * D4.c (spec §6 D4 "arrow-nudge (↑↓←→, Shift=×10) ... writes margins/
337
+ * offsets"): nudges every currently-selected id whose owner exposes
338
+ * `boxEdit` (capability-gated — silently skips ids that don't, e.g. a 3D
339
+ * entity or an ingested-world node with no spatial write path). Position/
340
+ * margin math is the pure, independently-tested `computeArrowNudgePatch`
341
+ * (`world-overlay-gestures.ts`); this function only resolves the per-id
342
+ * rect/position/margin inputs it needs and brackets the write in a single
343
+ * `begin`/`apply`/`end` (one undo step per nudged node, per B1/D-1).
344
+ */
345
+ export function nudgeSelection(store: ShellStore, dx: number, dy: number): void {
346
+ const ids = actionSelectionIds(store);
347
+ if (ids.length === 0) return;
348
+ const adapter = resolvePanelAuthoring(store).adapter;
349
+ for (const id of ids) {
350
+ const boxEdit = boxEditForId(adapter, id);
351
+ if (!boxEdit) continue;
352
+ const rect = rectForId(adapter, id);
353
+ if (!rect) continue;
354
+ const position = adapter.inspector?.get(id, 'style.position');
355
+ const isPositioned = position === 'absolute' || position === 'fixed';
356
+ const spacing = readSpacingValues(adapter, id);
357
+ const patch = computeArrowNudgePatch(dx, dy, isPositioned, rect, {
358
+ left: spacing.marginLeft,
359
+ top: spacing.marginTop,
360
+ });
361
+ if (Object.keys(patch).length === 0) continue;
362
+ boxEdit.begin(id);
363
+ boxEdit.apply(id, patch);
364
+ boxEdit.end(id);
365
+ }
366
+ }
367
+
368
+ // ---------------------------------------------------------------------------
369
+ // The keymap seam
370
+ // ---------------------------------------------------------------------------
371
+ // No binding below spells a literal key. Each names a LOGICAL ACTION and
372
+ // `keymap-presets.ts` supplies the chords the active keymap assigns it, so
373
+ // `volter` and `blender` are two tables rather than two code paths. See that
374
+ // module's header for the ruling, the collision resolutions, and the boundary
375
+ // against play-mode input isolation (which this seam does not touch).
376
+
377
+ /** How the FRAME reads a binding's scope when it turns one into a `when`
378
+ * clause (`key-actions.ts`): the viewport is the stage, the
379
+ * selection panels are the editor's own parts, global is everywhere in it. */
380
+ function frameScopeOf(scope: HotkeyBinding['scope']): KeyActionScope {
381
+ const scopes = Array.isArray(scope) ? scope : [scope];
382
+ if (scopes.includes('global')) return 'global';
383
+ if (scopes.length === 1 && scopes[0] === 'viewport') return 'stage';
384
+ return 'panel';
385
+ }
386
+
387
+ /**
388
+ * The action ids one `build()` pass registered, collected so the pass's
389
+ * disposal can take them back out. `bind` is the one place an action's body
390
+ * is written, so it is also the one place the frame's table is filled; the
391
+ * collector is how a call inside the build closure reaches the registration
392
+ * that owns it without every call site threading it.
393
+ */
394
+ let keyActionCollector: (() => void)[] | null = null;
395
+
396
+ /** Expand one logical action into the dispatcher's per-chord binding rows,
397
+ * and record what the action DOES in the chord-independent table the frame
398
+ * dispatches through (`key-actions.ts`). */
399
+ function bind(
400
+ action: EditorKeyActionId,
401
+ binding: Omit<HotkeyBinding, 'key' | 'code' | 'mod' | 'shift' | 'alt'> & {
402
+ /** This binding's `when`, in the form the FRAME can ask — no event. Set
403
+ * it wherever `when` ignores its argument; see `KeyActionEntry.enabled`. */
404
+ frameEnabled?: () => boolean;
405
+ },
406
+ ): HotkeyBinding[] {
407
+ const { frameEnabled, ...row } = binding;
408
+ keyActionCollector?.push(
409
+ registerKeyAction({
410
+ id: action,
411
+ run: (event) => row.action(event ?? new KeyboardEvent('keydown')),
412
+ scope: frameScopeOf(row.scope),
413
+ ...(frameEnabled ? { enabled: frameEnabled } : {}),
414
+ }),
415
+ );
416
+ return keyChordsFor(action).map((chord) => ({ ...row, ...chord }));
417
+ }
418
+
419
+ /**
420
+ * Register a binding set that REBUILDS on a keymap switch — the "live, no
421
+ * reload" half of the setting. Nothing else re-registers: the actions are the
422
+ * same objects, only their chords move.
423
+ *
424
+ * The action TABLE is filled by the same pass, and it is filled whoever owns
425
+ * the keyboard: under the frame the chord rows below go unread (the host
426
+ * dispatcher is never installed — `hotkeys.ts`) while the table is what every
427
+ * `volter.*` VS Code command dispatches into.
428
+ */
429
+ function registerKeymapBindings(build: () => HotkeyBinding[]): () => void {
430
+ const runBuild = (): { rows: HotkeyBinding[]; actions: (() => void)[] } => {
431
+ const actions: (() => void)[] = [];
432
+ const previous = keyActionCollector;
433
+ keyActionCollector = actions;
434
+ try {
435
+ return { rows: build(), actions };
436
+ } finally {
437
+ keyActionCollector = previous;
438
+ }
439
+ };
440
+ let pass = runBuild();
441
+ let dispose = registerHotkeys(pass.rows);
442
+ const disposePass = (): void => {
443
+ dispose();
444
+ for (const drop of pass.actions) drop();
445
+ };
446
+ const unsubscribe = subscribeEditorKeymap(() => {
447
+ disposePass();
448
+ pass = runBuild();
449
+ dispose = registerHotkeys(pass.rows);
450
+ });
451
+ return () => {
452
+ unsubscribe();
453
+ disposePass();
454
+ };
455
+ }
456
+
457
+ /**
458
+ * Shell-lifetime bindings: undo/redo, save, clipboard, delete, command palette.
459
+ * These do not need a Three viewport. Canvas-only projects (Bubbo isolation
460
+ * documents, first-party Pixi worlds) never mount a three stage at all, so they
461
+ * only get these keys if THIS function is registered from the editor shell.
462
+ *
463
+ * `mod+Z` matches Ctrl OR Cmd (`hotkeys.ts`); on Mac the menu prints ⌘Z and
464
+ * both chords fire the same action.
465
+ */
466
+ export function registerEditorShellHotkeys(
467
+ store: ShellStore,
468
+ history: HistoryCommands,
469
+ ): () => void {
470
+ // NARRATED undo/redo: the hint names what just happened ("Undid Paste 3
471
+ // Entities"). Undoing a paste empties the selection (the pasted ids die
472
+ // with it), and the silent no-gizmo viewport that follows read as "a Play
473
+ // preview I had to click out of" to a human (runhuman passes 52/53).
474
+ const narratedUndo = (): void => {
475
+ const label = history.getSnapshot().undoLabel;
476
+ void history.undo().then((done) => {
477
+ if (done && label) showTransientHint(`Undid ${label}`);
478
+ });
479
+ };
480
+ const narratedRedo = (): void => {
481
+ const label = history.getSnapshot().redoLabel;
482
+ void history.redo().then((done) => {
483
+ if (done && label) showTransientHint(`Redid ${label}`);
484
+ });
485
+ };
486
+ const unregister = registerKeymapBindings(() => [
487
+ // --- Global (fire regardless of active panel) ---
488
+ // H2: one project-scoped async command queue owns shell undo/redo. Ctrl+Y
489
+ // mirrors Ctrl+Shift+Z (Windows convention) — both are chords of the one
490
+ // `edit.redo` action in the keymap table.
491
+ // Undo/redo also fire inside fields that opted into app undo
492
+ // (`APP_UNDO_PASSTHROUGH_ATTR` — per-keystroke-committing numeric inputs,
493
+ // where native text undo is a dead key); every other editable keeps the
494
+ // guard so typing retains the browser's own undo.
495
+ ...bind('edit.redo', {
496
+ scope: 'global',
497
+ allowInEditable: true,
498
+ when: (e) => !isEditableTarget(e.target) || allowsAppUndoWhileEditable(e.target),
499
+ action: narratedRedo,
500
+ }),
501
+ ...bind('edit.undo', {
502
+ scope: 'global',
503
+ allowInEditable: true,
504
+ when: (e) => !isEditableTarget(e.target) || allowsAppUndoWhileEditable(e.target),
505
+ action: narratedUndo,
506
+ }),
507
+ ...bind('edit.copy', {
508
+ scope: AUTHORING_SELECTION_SCOPES,
509
+ when: shouldHandleEditorClipboard,
510
+ frameEnabled: shouldHandleEditorClipboard,
511
+ action: () => void copySelection(store),
512
+ }),
513
+ ...bind('edit.cut', {
514
+ scope: AUTHORING_SELECTION_SCOPES,
515
+ when: shouldHandleEditorClipboard,
516
+ frameEnabled: shouldHandleEditorClipboard,
517
+ action: () => void cutSelection(store),
518
+ }),
519
+ ...bind('edit.paste', {
520
+ scope: AUTHORING_SELECTION_SCOPES,
521
+ when: shouldHandleEditorClipboard,
522
+ frameEnabled: shouldHandleEditorClipboard,
523
+ action: () => void pasteSelection(store),
524
+ }),
525
+ ...bind('edit.duplicate', {
526
+ scope: AUTHORING_SELECTION_SCOPES,
527
+ action: () => void duplicateSelection(store),
528
+ }),
529
+ // D4 — wrap/unwrap (override-only, capability-gated — see
530
+ // `wrapSelection`/`unwrapSelection`'s doc comments).
531
+ ...bind('edit.group', {
532
+ scope: AUTHORING_SELECTION_SCOPES,
533
+ action: () => void groupSelection(store),
534
+ }),
535
+ ...bind('edit.wrap', {
536
+ scope: AUTHORING_SELECTION_SCOPES,
537
+ action: () => wrapSelection(store),
538
+ }),
539
+ ...bind('edit.unwrap', {
540
+ scope: AUTHORING_SELECTION_SCOPES,
541
+ action: () => unwrapSelection(store),
542
+ }),
543
+ // D4 — arrow-nudge (↑↓←→, Shift=×10 — see `nudgeSelection`'s doc comment).
544
+ ...bind('edit.nudgeUp', { scope: 'viewport', action: () => nudgeSelection(store, 0, -1) }),
545
+ ...bind('edit.nudgeUpCoarse', {
546
+ scope: 'viewport',
547
+ action: () => nudgeSelection(store, 0, -10),
548
+ }),
549
+ ...bind('edit.nudgeDown', { scope: 'viewport', action: () => nudgeSelection(store, 0, 1) }),
550
+ ...bind('edit.nudgeDownCoarse', {
551
+ scope: 'viewport',
552
+ action: () => nudgeSelection(store, 0, 10),
553
+ }),
554
+ ...bind('edit.nudgeLeft', { scope: 'viewport', action: () => nudgeSelection(store, -1, 0) }),
555
+ ...bind('edit.nudgeLeftCoarse', {
556
+ scope: 'viewport',
557
+ action: () => nudgeSelection(store, -10, 0),
558
+ }),
559
+ ...bind('edit.nudgeRight', { scope: 'viewport', action: () => nudgeSelection(store, 1, 0) }),
560
+ ...bind('edit.nudgeRightCoarse', {
561
+ scope: 'viewport',
562
+ action: () => nudgeSelection(store, 10, 0),
563
+ }),
564
+ ...bind('edit.selectAll', {
565
+ scope: AUTHORING_SELECTION_SCOPES,
566
+ action: () => {
567
+ const a = resolvePanelAuthoring(store).adapter;
568
+ setAuthoringSelection(a, collectAllNodeIds(a));
569
+ },
570
+ }),
571
+ // Blender's Alt+A. Unbound in the volter table, where Escape is the deselect
572
+ // (and carries the scope-exit verb with it); this one only clears.
573
+ ...bind('edit.deselectAll', {
574
+ scope: AUTHORING_SELECTION_SCOPES,
575
+ action: () => setAuthoringSelection(resolvePanelAuthoring(store).adapter, []),
576
+ }),
577
+ ...bind('edit.save', {
578
+ scope: 'global',
579
+ allowInEditable: true,
580
+ action: () => {
581
+ void saveActiveWorkspaceDocument().then((handled) => {
582
+ // Surfaces with no document-local editor fall back to the ACTIVE
583
+ // authoring adapter's own persistence provider.
584
+ if (handled === null) void saveActiveAuthoring(store);
585
+ });
586
+ },
587
+ }),
588
+ // D4 (spec27 §8 "space-pan" row) — Ctrl+0, the conventional "reset
589
+ // zoom/pan to 100%" shortcut (browsers/design tools alike), resets the
590
+ // DOM/react overlay's shared pan translate (`world-pan-state.ts`) back to
591
+ // `(0, 0)`. A no-op when already at rest or when the active surface has
592
+ // no pan-capable world (there is nothing for it to affect either way —
593
+ // `resetRootPan()` itself no-ops at `(0,0)`).
594
+ ...bind('view.resetPan', { scope: 'viewport', action: () => resetRootPan() }),
595
+ ...bind('edit.enterScope', {
596
+ scope: AUTHORING_SELECTION_SCOPES,
597
+ // While playing, Enter belongs to the GAME. The dispatcher preventDefaults
598
+ // every matched binding, so with this bound unconditionally the editor
599
+ // swallowed Enter during play and a game's own Enter binding could never
600
+ // fire — third-person's 'restart' is Enter, and its SQUAD DOWN card says
601
+ // 'PRESS ENTER TO REDEPLOY': a tester pressed it and 'Enter then redeploy
602
+ // doesn't work' (runhuman pass 122; an earlier reproduction had already
603
+ // measured Enter and Escape both exiting Play). Same gate shape as
604
+ // Escape's below, for the same reason.
605
+ when: () => store.playState === 'stopped',
606
+ frameEnabled: () => store.playState === 'stopped',
607
+ action: () => {
608
+ // The PANEL adapter, not the composite: `selection-scope.ts` keys its
609
+ // stack by adapter identity and the Hierarchy's breadcrumb/entry both
610
+ // resolve this one, so all three gestures name the same scope.
611
+ enterSelectedScope(resolvePanelAuthoring(store).adapter);
612
+ },
613
+ }),
614
+ ...bind('edit.delete', {
615
+ scope: AUTHORING_SELECTION_SCOPES,
616
+ action: () => void deleteSelection(store),
617
+ }),
618
+ ...bind('edit.exitScopeOrDeselect', {
619
+ scope: AUTHORING_SELECTION_SCOPES,
620
+ // While playing, Escape is owned by play-mode (stop on Escape) — don't also
621
+ // clear the editor selection out from under the running game. The `when`
622
+ // gate (NOT an action-internal no-op) is load-bearing: the dispatcher
623
+ // preventDefaults every MATCHED binding, and play-mode's own bubble-phase
624
+ // Escape guard (`shouldEscapeStopPlay`) reads `defaultPrevented` as
625
+ // "an overlay consumed this Escape" — an action no-op here would still
626
+ // preventDefault and poison that signal, leaving Escape unable to stop play.
627
+ when: () => currentSelectionScopeId() !== null || store.playState === 'stopped',
628
+ // AND UNDER THE FRAME THAT FALLTHROUGH DOES NOT EXIST, which is why the two
629
+ // gates differ (found by walk 2's beat 17, 2026-09-20). VS Code's keybinding
630
+ // service preventDefaults every rule whose `when` RESOLVES, before the command
631
+ // it names decides anything — so with a `volter.edit.exitScopeOrDeselect` rule on
632
+ // Escape, play-mode's `window` listener never sees an Escape that is not already
633
+ // `defaultPrevented`. A `frameEnabled` that returned false during play therefore
634
+ // produced neither outcome: the command refused ("the editor has no live handler
635
+ // for it right now") and the keystroke was consumed, so Escape did nothing at all
636
+ // while play ran and only the transport's ■ could end an immersive Play.
637
+ // The frame's Escape is this ONE action, and it does what the gesture means: leave
638
+ // the current scope, or — with none to leave — leave PLAY.
639
+ frameEnabled: () => true,
640
+ action: () => {
641
+ // Same one resolution as the Enter binding above — with the composite
642
+ // here, `exitSelectionScope` saw a FOREIGN adapter and dropped the whole
643
+ // stack instead of popping one level.
644
+ const adapter = resolvePanelAuthoring(store).adapter;
645
+ if (exitSelectionScope(adapter)) return;
646
+ // Nothing to pop. Standalone this is only ever reached with play stopped
647
+ // (the `when` above), so it is the deselect it always was; under the frame
648
+ // it is also the Escape that ends a run, through the registry every lane
649
+ // registers into — the same door `stop` reaches, never play-mode by name
650
+ // (the editor does not import `@volter/editor-game`).
651
+ if (store.playState !== 'stopped') {
652
+ stopAllLiveSessions();
653
+ return;
654
+ }
655
+ store.select(null);
656
+ },
657
+ }),
658
+ ...bind('view.commandPalette', {
659
+ scope: 'global',
660
+ // THE PALETTE IS THE WORKBENCH'S. The frame hands over an opener that
661
+ // runs `workbench.action.showCommands`. (This action's own CHORD is
662
+ // unbound — ⌘K is VS Code's chord prefix, U6 — so this path is the
663
+ // command, run from the palette itself or from a keybinding a person
664
+ // made.)
665
+ action: () => {
666
+ if (!openCommandPalette()) {
667
+ editorConsole.warn(
668
+ 'The command palette has not handed over its opener yet — run "Volter Editor: Open Workspace" first, or press the workbench\'s own Show All Commands.',
669
+ );
670
+ }
671
+ },
672
+ }),
673
+ ...bind('view.toggleConsole', {
674
+ scope: 'global',
675
+ action: () => toggleConsoleUtility(),
676
+ }),
677
+ // W5 (§6.2 focus/maximize mode) — Ctrl/Cmd+Shift+F. SHORTCUT DECISION,
678
+ // recorded: the benchmarks are Unity's Shift+Space (maximize view under
679
+ // cursor) and VS Code zen's Ctrl+K Z chord — but this registry is
680
+ // single-fire and chord-less, and Space already participates in the
681
+ // overlay's space-pan HOLD gesture (`RootSelectionOverlay`), so both
682
+ // benchmarks' literal keys would collide. mod+shift+F ("Focus") is free
683
+ // in this registry and unclaimed by Chromium on an app page.
684
+ ...bind('view.focusMode', {
685
+ scope: 'global',
686
+ action: () => toggleWorkspaceFocus(),
687
+ }),
688
+ // NAMED WORKSPACES' cycle pair (ARCHITECTURE-CORE §Editor chrome asks for
689
+ // "a cycle shortcut"). Ctrl/Cmd+PageDown / PageUp is BLENDER'S OWN
690
+ // workspace cycle — the vocabulary rule (docs/BLENDER-PARITY.md) applies
691
+ // to the modeling half of the editor, and both keys are unclaimed here,
692
+ // so both keymaps keep them.
693
+ ...bind('workspace.cycleNext', {
694
+ scope: 'global',
695
+ action: () => {
696
+ cycleEditorWorkspace(1);
697
+ },
698
+ }),
699
+ ...bind('workspace.cyclePrevious', {
700
+ scope: 'global',
701
+ action: () => {
702
+ cycleEditorWorkspace(-1);
703
+ },
704
+ }),
705
+ ]);
706
+ installHotkeys();
707
+ return unregister;
708
+ }
709
+
710
+ /**
711
+ * A LANE'S KEYBOARD ACTIONS, bound through the host door
712
+ * (`host.keyboard.bindActions`): the lane writes what each action does, and the
713
+ * active keymap supplies its chords, rebuilt on a keymap switch like every
714
+ * binding set here. A `'stage'` action answers only while a stage holds the
715
+ * editor's keyboard scope.
716
+ */
717
+ export function bindKeyActions(actions: readonly EditorHostKeyAction[]): () => void {
718
+ return registerKeymapBindings(() =>
719
+ actions.flatMap((entry) => {
720
+ const enabled = entry.enabled;
721
+ return bind(entry.id, {
722
+ scope: entry.scope === 'stage' ? 'viewport' : 'global',
723
+ action: (event) => entry.run(event),
724
+ ...(enabled ? { when: () => enabled(), frameEnabled: () => enabled() } : {}),
725
+ });
726
+ }),
727
+ );
728
+ }