@volter/editor-core 0.5.57
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.
- package/BUNDLED_NOTICES +1527 -0
- package/LICENSE +686 -0
- package/LICENSE-APACHE +202 -0
- package/NOTICE +18 -0
- package/README.md +24 -0
- package/dist/build/chunk-JS4D4XZ3.js +175 -0
- package/dist/build/chunk-JS4D4XZ3.js.map +7 -0
- package/dist/build/vite-plugin-product-contributions.js +100 -0
- package/dist/build/vite-plugin-product-contributions.js.map +7 -0
- package/dist/build/vite-plugin-shared-react.js +25 -0
- package/dist/build/vite-plugin-shared-react.js.map +7 -0
- package/dist/build/vite-plugin-shared-three.js +86 -0
- package/dist/build/vite-plugin-shared-three.js.map +7 -0
- package/dist/server/chunk-KMJC7AGO.js +98 -0
- package/dist/server/chunk-KMJC7AGO.js.map +7 -0
- package/dist/server/chunk-PSILUMGS.js +46 -0
- package/dist/server/chunk-PSILUMGS.js.map +7 -0
- package/dist/server/frame-proxy.js +255 -0
- package/dist/server/frame-proxy.js.map +7 -0
- package/dist/server/open-browser.js +53 -0
- package/dist/server/open-browser.js.map +7 -0
- package/dist/server/process-shutdown.js +127 -0
- package/dist/server/process-shutdown.js.map +7 -0
- package/dist/server/session-registry.js +141 -0
- package/dist/server/session-registry.js.map +7 -0
- package/dist/server/spawn-opener.js +11 -0
- package/dist/server/spawn-opener.js.map +7 -0
- package/dist/server/worktree-identity.js +11 -0
- package/dist/server/worktree-identity.js.map +7 -0
- package/dist-server/packaged.mjs +88816 -0
- package/package.json +118 -0
- package/scripts/build-plugins.mjs +14 -0
- package/scripts/build-server.mjs +26 -0
- package/scripts/build-session.mjs +9 -0
- package/server/account-credentials.ts +60 -0
- package/server/account-service.ts +1434 -0
- package/server/adapter-region-includes.ts +47 -0
- package/server/asset-catalog-v2.ts +175 -0
- package/server/asset-history-snapshots.ts +196 -0
- package/server/asset-ledger-store.ts +195 -0
- package/server/asset-library-routes.ts +1595 -0
- package/server/blender-wasm-artifact.ts +430 -0
- package/server/boot-timings.ts +106 -0
- package/server/canonical-path.ts +50 -0
- package/server/checkout-workspace-preflight.ts +349 -0
- package/server/cloud-asset-catalog.ts +158 -0
- package/server/coding-inference-launch.ts +237 -0
- package/server/collaboration-account-client.ts +202 -0
- package/server/collaboration-attribution.ts +122 -0
- package/server/collaboration-session.ts +934 -0
- package/server/comfyui-bridge.ts +248 -0
- package/server/console-ledger.ts +499 -0
- package/server/creation-site-transform.ts +304 -0
- package/server/creation-site-write.ts +648 -0
- package/server/data-file-serialize.ts +158 -0
- package/server/editor-brand-html.ts +72 -0
- package/server/editor-control-socket.ts +366 -0
- package/server/editor-server-options.ts +190 -0
- package/server/editor-server.ts +1483 -0
- package/server/editor-sse.ts +352 -0
- package/server/engine-provenance.ts +169 -0
- package/server/engine-source-restart.ts +117 -0
- package/server/frame-bridge.ts +115 -0
- package/server/frame-proxy.ts +490 -0
- package/server/frame-workbench.ts +259 -0
- package/server/frontend-handoff.ts +229 -0
- package/server/game-globals-shadow.ts +113 -0
- package/server/gameplay-session-retention.ts +149 -0
- package/server/gameplay-sessions.ts +123 -0
- package/server/generation-jobs.ts +201 -0
- package/server/generation-reconciler.ts +137 -0
- package/server/generative-execution-context.ts +59 -0
- package/server/git-workflow.ts +612 -0
- package/server/harness-chat-caller.ts +36 -0
- package/server/harness-chat-service.ts +1681 -0
- package/server/idle-shutdown.ts +170 -0
- package/server/js-profiling-policy.ts +52 -0
- package/server/launcher-settings.ts +84 -0
- package/server/local-asset-catalog.ts +410 -0
- package/server/managed-account-defaults.ts +22 -0
- package/server/mock-control-plane.ts +540 -0
- package/server/model-import-conversion.ts +345 -0
- package/server/native-credential-store.ts +162 -0
- package/server/open-browser.ts +118 -0
- package/server/packaged.ts +1192 -0
- package/server/play-stall.ts +126 -0
- package/server/process-shutdown.ts +218 -0
- package/server/product-presets.ts +55 -0
- package/server/project-build-artifact.ts +95 -0
- package/server/project-components.ts +100 -0
- package/server/project-dependency-invalidation.ts +114 -0
- package/server/project-file-scan.ts +235 -0
- package/server/project-hmr-files.ts +215 -0
- package/server/project-install-roots.ts +210 -0
- package/server/project-kinds.ts +71 -0
- package/server/project-mcp-servers.ts +82 -0
- package/server/project-module-freshness.ts +109 -0
- package/server/project-module-instance.ts +375 -0
- package/server/project-optimize-deps-entries.ts +827 -0
- package/server/project-output-writer.ts +679 -0
- package/server/project-package-origin.ts +63 -0
- package/server/project-root-surface.ts +831 -0
- package/server/project-scratch-path.ts +47 -0
- package/server/project-script-hmr.ts +619 -0
- package/server/project-serving-plugins.ts +236 -0
- package/server/project-tools.ts +653 -0
- package/server/project-validation.ts +250 -0
- package/server/project-verbs.ts +127 -0
- package/server/project-view.ts +52 -0
- package/server/project-watch.ts +1134 -0
- package/server/project-work-coordinator.ts +288 -0
- package/server/provider-credentials.ts +331 -0
- package/server/recent-projects-store.ts +98 -0
- package/server/redact-secrets.ts +71 -0
- package/server/repository-presence.ts +267 -0
- package/server/routes/account.ts +357 -0
- package/server/routes/agents.ts +60 -0
- package/server/routes/assets.ts +154 -0
- package/server/routes/build.ts +13 -0
- package/server/routes/collaboration.ts +595 -0
- package/server/routes/configurations.ts +419 -0
- package/server/routes/context.ts +264 -0
- package/server/routes/control-plane.ts +1811 -0
- package/server/routes/logs.ts +272 -0
- package/server/routes/project-identity.ts +302 -0
- package/server/routes/project-open.ts +429 -0
- package/server/routes/project-source.ts +686 -0
- package/server/routes/project-state.ts +383 -0
- package/server/routes/relay.ts +1029 -0
- package/server/routes/route-helpers.ts +29 -0
- package/server/routes/served-modules.ts +138 -0
- package/server/routes/session-tabs.ts +196 -0
- package/server/routes/settings.ts +121 -0
- package/server/routes/share-control.ts +486 -0
- package/server/routes/themes.ts +116 -0
- package/server/routes/tools.ts +230 -0
- package/server/routes/worktrees.ts +595 -0
- package/server/scoped-game-css.ts +461 -0
- package/server/server-utils.ts +1194 -0
- package/server/session-product.ts +112 -0
- package/server/session-registry.ts +230 -0
- package/server/share-claims.ts +138 -0
- package/server/share-host.ts +526 -0
- package/server/share-session-gateway.ts +1362 -0
- package/server/share-tunnel.ts +123 -0
- package/server/spawn-opener.ts +74 -0
- package/server/support/play/log-format.ts +76 -0
- package/server/support/play/session-record.ts +199 -0
- package/server/support/project/build-discipline.ts +718 -0
- package/server/support/project/inspection-node.ts +119 -0
- package/server/support/project/log-naming.ts +54 -0
- package/server/support/project/provenance.ts +290 -0
- package/server/support/project/run-name.ts +18 -0
- package/server/support/project/session-journal.ts +830 -0
- package/server/support/project/shared.ts +327 -0
- package/server/tab-bootstrap.ts +62 -0
- package/server/tab-heartbeat.ts +477 -0
- package/server/tab-lifecycle.ts +550 -0
- package/server/tab-presence.ts +1508 -0
- package/server/team-agent-mirror.ts +95 -0
- package/server/twin-auth.ts +138 -0
- package/server/vendored-lock-recorder.ts +968 -0
- package/server/worktree-identity.ts +121 -0
- package/server/worktree-management.ts +398 -0
- package/server/worktree-retention.d.mts +13 -0
- package/server/worktree-retention.mjs +205 -0
- package/src/EditorContext.tsx +169 -0
- package/src/account.ts +333 -0
- package/src/action-registry.ts +532 -0
- package/src/active-product.ts +74 -0
- package/src/active-project.ts +155 -0
- package/src/adapter-editor-config.ts +25 -0
- package/src/adapter-observation.ts +49 -0
- package/src/animation/stage-transport.ts +379 -0
- package/src/animation/three-clips-subject.ts +172 -0
- package/src/api/asset-library-wire.ts +45 -0
- package/src/api/assets.ts +365 -0
- package/src/api/base.ts +10 -0
- package/src/api/build.ts +99 -0
- package/src/api/git-wire.ts +56 -0
- package/src/api/logs.ts +92 -0
- package/src/api/project-identity.ts +74 -0
- package/src/api/project-open.ts +355 -0
- package/src/api/project-source.ts +162 -0
- package/src/api/project-state.ts +107 -0
- package/src/api/relay.ts +268 -0
- package/src/api/settings.ts +36 -0
- package/src/api/themes.ts +45 -0
- package/src/api/worktrees.ts +257 -0
- package/src/asset-compare-core.ts +171 -0
- package/src/asset-compare.ts +294 -0
- package/src/asset-editor-context.tsx +100 -0
- package/src/asset-events.ts +97 -0
- package/src/asset-inspector-actions.ts +87 -0
- package/src/asset-preview-framing.ts +357 -0
- package/src/asset-preview.ts +2802 -0
- package/src/asset-selection-viewer-registry.ts +113 -0
- package/src/asset-selection.ts +133 -0
- package/src/asset-workflow/asset-capabilities.ts +344 -0
- package/src/asset-workflow/asset-import-jobs.ts +106 -0
- package/src/asset-workflow/asset-ledger-backend.ts +126 -0
- package/src/asset-workflow/asset-ledger.ts +156 -0
- package/src/asset-workflow/asset-materialization-report.ts +140 -0
- package/src/asset-workflow/asset-pack-manifest.ts +320 -0
- package/src/asset-workflow/asset-types.ts +142 -0
- package/src/asset-workflow/asset-workflow-quality.ts +61 -0
- package/src/asset-workflow/audio-preview-player.ts +193 -0
- package/src/asset-workflow/audio-waveform.ts +22 -0
- package/src/asset-workflow/cloud-asset-client.ts +263 -0
- package/src/asset-workflow/folder-preview.ts +345 -0
- package/src/asset-workflow/hosted-asset-materialization.ts +236 -0
- package/src/asset-workflow/image-view-scale.ts +32 -0
- package/src/asset-workflow/import-contract.ts +124 -0
- package/src/asset-workflow/ledger-write-lock.ts +244 -0
- package/src/asset-workflow/model-inspection.ts +818 -0
- package/src/asset-workflow/pixi-spritesheet.ts +197 -0
- package/src/asset-workflow/preview-resource-lifetime.ts +44 -0
- package/src/asset-workflow/project-asset-commands.ts +23 -0
- package/src/asset-workflow/project-asset-health.ts +139 -0
- package/src/asset-workflow/project-asset-operations.ts +154 -0
- package/src/asset-workflow/project-asset-roots.ts +68 -0
- package/src/asset-workflow/project-content.ts +288 -0
- package/src/asset-workflow/project-source-index.ts +550 -0
- package/src/asset-workflow/thumbnail-system.ts +256 -0
- package/src/authoring/active-adapter.ts +199 -0
- package/src/authoring/active-systems.ts +422 -0
- package/src/authoring/adapter-key.ts +18 -0
- package/src/authoring/authoring-asset-url.ts +27 -0
- package/src/authoring/bootstrap-state.ts +49 -0
- package/src/authoring/boundary-authoring-adapter.ts +184 -0
- package/src/authoring/breakpoint-state.ts +43 -0
- package/src/authoring/canvas-scene-guides.ts +76 -0
- package/src/authoring/component-instance-root.ts +171 -0
- package/src/authoring/composite-authoring-adapter.ts +2110 -0
- package/src/authoring/consumer-actions.ts +520 -0
- package/src/authoring/css-numeric-style.ts +97 -0
- package/src/authoring/design-time-layers.ts +849 -0
- package/src/authoring/design-time-mount-registry.ts +235 -0
- package/src/authoring/design-time-settle.ts +343 -0
- package/src/authoring/edit-mode-authoring.ts +619 -0
- package/src/authoring/eyedropper-session.ts +60 -0
- package/src/authoring/instance-source-menu-register.ts +13 -0
- package/src/authoring/instance-source-menu.ts +135 -0
- package/src/authoring/layered-pick.ts +183 -0
- package/src/authoring/live-gesture-lock.ts +50 -0
- package/src/authoring/live-object-transform.ts +62 -0
- package/src/authoring/mount-failure-report.ts +154 -0
- package/src/authoring/mounted-root-subjects.ts +144 -0
- package/src/authoring/no-authoring-adapter.ts +55 -0
- package/src/authoring/null-inspection-subjects.tsx +75 -0
- package/src/authoring/object3d-document-persistence.ts +106 -0
- package/src/authoring/object3d-document-session-registry.ts +120 -0
- package/src/authoring/object3d-document-session.ts +1326 -0
- package/src/authoring/object3d-gesture-controller.ts +113 -0
- package/src/authoring/panel-authoring.ts +121 -0
- package/src/authoring/prefab-instance-inspector-section.tsx +237 -0
- package/src/authoring/prefab-instance-section-model.ts +55 -0
- package/src/authoring/project-authoring-session.ts +105 -0
- package/src/authoring/provenance.ts +99 -0
- package/src/authoring/quarks-particle-systems.ts +19 -0
- package/src/authoring/react-canvas-navigation.ts +255 -0
- package/src/authoring/react-design-canvas-style.ts +20 -0
- package/src/authoring/react-story-board.ts +937 -0
- package/src/authoring/selection-scope.ts +195 -0
- package/src/authoring/shell-document-ops.ts +169 -0
- package/src/authoring/shell-object3d-document-write-policy.ts +108 -0
- package/src/authoring/shell-viewport-policy.ts +48 -0
- package/src/authoring/source-object3d-authoring-adapter.ts +526 -0
- package/src/authoring/stories-scope.ts +35 -0
- package/src/authoring/story-board-chrome-fit.ts +107 -0
- package/src/authoring/story-board-presentation.ts +111 -0
- package/src/authoring/three-projection-core.ts +226 -0
- package/src/authoring/viewport-pick-context.ts +40 -0
- package/src/authoring/viewport-raycast.ts +240 -0
- package/src/authoring/viewport-tool-context.ts +73 -0
- package/src/authoring/world-canvas-viewport-state.ts +35 -0
- package/src/authoring/world-hidden-viewport.ts +152 -0
- package/src/authoring/world-pan-state.ts +198 -0
- package/src/authoring/world-session-state.ts +101 -0
- package/src/authoring/write-pipe.ts +173 -0
- package/src/availability-tick.ts +66 -0
- package/src/bitmap-label.ts +120 -0
- package/src/blender-tab-metrics.ts +161 -0
- package/src/board-open-actions.ts +20 -0
- package/src/boot-routing.ts +391 -0
- package/src/build-identity.ts +15 -0
- package/src/bytes-codec.ts +62 -0
- package/src/camera-authoring.ts +175 -0
- package/src/cancellation-reason.ts +58 -0
- package/src/canvas-preview-frames.ts +482 -0
- package/src/capture-camera-pose.ts +77 -0
- package/src/chrome-registry.ts +159 -0
- package/src/chrome-slot-registry.ts +91 -0
- package/src/collaboration-client.ts +264 -0
- package/src/collaboration-presence.ts +41 -0
- package/src/command-dispatch.ts +19 -0
- package/src/command-listener.ts +2743 -0
- package/src/command-registry.ts +70 -0
- package/src/component-board-registry.ts +205 -0
- package/src/component-states-registry.ts +200 -0
- package/src/components/AgentPresentationNotice.tsx +75 -0
- package/src/components/AlignToolbar.tsx +204 -0
- package/src/components/AppRoot.tsx +394 -0
- package/src/components/ApplicationMenus.tsx +415 -0
- package/src/components/AssetBrowser.tsx +2843 -0
- package/src/components/AssetEditorShell.tsx +216 -0
- package/src/components/AssetInspectorToolSection.tsx +124 -0
- package/src/components/BoardRulers.tsx +354 -0
- package/src/components/CameraInfo.tsx +81 -0
- package/src/components/CanvasSceneViewport.tsx +556 -0
- package/src/components/CapabilityCoverageSection.tsx +185 -0
- package/src/components/CenterDocuments.tsx +22 -0
- package/src/components/ChromeSlot.tsx +20 -0
- package/src/components/CodeView.tsx +470 -0
- package/src/components/CollaborationHeaderControl.css +74 -0
- package/src/components/CompactInspectorCard.tsx +190 -0
- package/src/components/CompactInspectorShell.tsx +39 -0
- package/src/components/ConsolePanel.css +55 -0
- package/src/components/ConsolePanel.tsx +270 -0
- package/src/components/DefaultEditorLayout.tsx +106 -0
- package/src/components/DocumentHeaderStrip.tsx +96 -0
- package/src/components/DocumentShelfRail.tsx +45 -0
- package/src/components/DocumentThumbnail.tsx +345 -0
- package/src/components/EditorLeaseGuard.tsx +372 -0
- package/src/components/ErrorBanner.tsx +123 -0
- package/src/components/FolderPreviewTile.tsx +159 -0
- package/src/components/GameHierarchy.tsx +3842 -0
- package/src/components/GameplaySessionTimeline.tsx +295 -0
- package/src/components/InspectionProjection.tsx +968 -0
- package/src/components/Inspector.tsx +233 -0
- package/src/components/InspectorCanvasPreview.tsx +35 -0
- package/src/components/InspectorFieldsSection.tsx +290 -0
- package/src/components/InspectorObjectPreview.tsx +57 -0
- package/src/components/InspectorStoriesSection.tsx +92 -0
- package/src/components/InspectorToolSection.tsx +96 -0
- package/src/components/InspectorTransformSection.tsx +245 -0
- package/src/components/LightExplorerPanel.tsx +433 -0
- package/src/components/MediaProperties.tsx +145 -0
- package/src/components/NonThreeAuthoringBootstrap.tsx +19 -0
- package/src/components/Object3DDocumentToolbar.css +100 -0
- package/src/components/Object3DDocumentToolbar.tsx +454 -0
- package/src/components/Object3DDocumentViewport.tsx +58 -0
- package/src/components/ProjectHeader.css +617 -0
- package/src/components/ProjectHeader.tsx +328 -0
- package/src/components/ProjectLayout.tsx +249 -0
- package/src/components/ReactCanvasControls.tsx +284 -0
- package/src/components/RootSelectionOverlay.tsx +3162 -0
- package/src/components/RootTextEditor.tsx +79 -0
- package/src/components/SaveStatus.tsx +70 -0
- package/src/components/StageHost.tsx +1954 -0
- package/src/components/StageOverlays.tsx +21 -0
- package/src/components/StartupErrorScreen.tsx +76 -0
- package/src/components/StartupLoadingScreen.tsx +65 -0
- package/src/components/StatsOverlay.tsx +78 -0
- package/src/components/SurfaceStateOverlay.tsx +24 -0
- package/src/components/ToolContributionSurfaces.tsx +65 -0
- package/src/components/ToolHost.tsx +370 -0
- package/src/components/ToolObject3DPreview.tsx +39 -0
- package/src/components/Toolbar.tsx +595 -0
- package/src/components/TransientHint.tsx +44 -0
- package/src/components/TransportStrip.tsx +174 -0
- package/src/components/VersionControlSection.tsx +470 -0
- package/src/components/VgaiLogo.css +83 -0
- package/src/components/VgaiLogo.tsx +35 -0
- package/src/components/ViewportControlsHint.tsx +60 -0
- package/src/components/ViewportFurniture.tsx +401 -0
- package/src/components/ViewportOverlay.tsx +145 -0
- package/src/components/ViewportOverlaysMenu.tsx +153 -0
- package/src/components/ViewportShadingMenu.tsx +300 -0
- package/src/components/ViewportViewMenu.tsx +101 -0
- package/src/components/WorkspaceDocumentSurface.tsx +204 -0
- package/src/components/WorkspaceUtilitySurface.tsx +22 -0
- package/src/components/WorktreeSwitcher.css +239 -0
- package/src/components/WorktreeSwitcher.tsx +890 -0
- package/src/components/account-documents.tsx +1162 -0
- package/src/components/asset-documents.tsx +812 -0
- package/src/components/asset-editor-persistence.ts +216 -0
- package/src/components/asset-selection-section.tsx +535 -0
- package/src/components/asset-thumbnails.tsx +312 -0
- package/src/components/asset-viewers/AudioViewer.tsx +201 -0
- package/src/components/asset-viewers/EntityModelDocument.tsx +122 -0
- package/src/components/asset-viewers/EnvironmentAssetDocument.tsx +440 -0
- package/src/components/asset-viewers/GenericJsonViewer.tsx +102 -0
- package/src/components/asset-viewers/ImageViewer.tsx +300 -0
- package/src/components/asset-viewers/JsonAssetDocument.tsx +93 -0
- package/src/components/asset-viewers/LiveModuleDocument.tsx +417 -0
- package/src/components/asset-viewers/LutAssetDocument.tsx +444 -0
- package/src/components/asset-viewers/ModelAssetDocument.tsx +105 -0
- package/src/components/asset-viewers/Object3DPreview.tsx +359 -0
- package/src/components/asset-viewers/OnlineAssetDetail.tsx +421 -0
- package/src/components/asset-viewers/PasteboardModuleDocument.tsx +67 -0
- package/src/components/asset-viewers/QuarksAssetDocument.tsx +526 -0
- package/src/components/asset-viewers/ShaderAssetDocument.tsx +743 -0
- package/src/components/asset-viewers/SourceAssetViewer.tsx +281 -0
- package/src/components/asset-viewers/SpritesheetSpriteView.tsx +102 -0
- package/src/components/asset-viewers/VideoViewer.tsx +101 -0
- package/src/components/asset-viewers/shader-source.ts +144 -0
- package/src/components/asset-workflow.css +731 -0
- package/src/components/board-guides.ts +150 -0
- package/src/components/compact-inspector.css +539 -0
- package/src/components/core-utilities.tsx +90 -0
- package/src/components/editor-notifications.css +40 -0
- package/src/components/engine-workspace.css +274 -0
- package/src/components/inspector-preview-section.tsx +238 -0
- package/src/components/inspector-property-grouping.ts +64 -0
- package/src/components/inspector-revert-label.ts +20 -0
- package/src/components/inspector-selection.ts +42 -0
- package/src/components/inspector-stories-gating.ts +171 -0
- package/src/components/inspector-transform-subject.ts +11 -0
- package/src/components/inspector-transform.ts +75 -0
- package/src/components/kind-documents.tsx +500 -0
- package/src/components/palette-action-publisher.tsx +140 -0
- package/src/components/primitives/DraftColorInput.tsx +74 -0
- package/src/components/product-shell.css +1829 -0
- package/src/components/project-tool-documents.tsx +410 -0
- package/src/components/scene-documents.tsx +223 -0
- package/src/components/stage-keyboard.tsx +37 -0
- package/src/components/stage-overlay-set.tsx +107 -0
- package/src/components/stage-presence-markers.ts +478 -0
- package/src/components/standard-viewport-dressing.ts +417 -0
- package/src/components/status-contributions.tsx +403 -0
- package/src/components/tool-documents.tsx +309 -0
- package/src/components/tool-schema-form.tsx +262 -0
- package/src/components/use-after-paint.ts +41 -0
- package/src/components/use-project-image-assets.ts +86 -0
- package/src/components/viewport-header-controls.css +90 -0
- package/src/components/viewport-surface-status.tsx +55 -0
- package/src/components/workspace-history.ts +32 -0
- package/src/components/workspace-static-panel-registry.tsx +152 -0
- package/src/components/workspace-surfaces.css +621 -0
- package/src/components/world-documents.tsx +586 -0
- package/src/components/world-overlay-gestures.ts +1694 -0
- package/src/composite-screenshot.ts +1641 -0
- package/src/console-sync.ts +131 -0
- package/src/constraint-helper.ts +338 -0
- package/src/content-entry-source-registry.ts +184 -0
- package/src/coverage/authoring-seam-evidence.ts +300 -0
- package/src/coverage/canvas-reveal.ts +192 -0
- package/src/coverage/design-time-surfaces.ts +101 -0
- package/src/coverage/live-seam-evidence.ts +11 -0
- package/src/coverage/ontology-invariants.ts +466 -0
- package/src/coverage/session-vitals.ts +501 -0
- package/src/coverage/system-seam-evidence.ts +72 -0
- package/src/crash-null-boundary.ts +36 -0
- package/src/creation-site-edit.ts +1479 -0
- package/src/creation-site-registry.ts +160 -0
- package/src/delegate-harness-registry.ts +143 -0
- package/src/document-context-registry.ts +177 -0
- package/src/document-open-registry.ts +200 -0
- package/src/document-preview-source.ts +20 -0
- package/src/document-renderer-session.ts +138 -0
- package/src/editor-api.ts +46 -0
- package/src/editor-chrome-capture.ts +139 -0
- package/src/editor-commands.ts +164 -0
- package/src/editor-console.ts +563 -0
- package/src/editor-current-view.ts +82 -0
- package/src/editor-document-probe.ts +881 -0
- package/src/editor-git-client.ts +115 -0
- package/src/editor-host-door.ts +462 -0
- package/src/editor-hotkeys.ts +842 -0
- package/src/editor-lease-view.ts +39 -0
- package/src/editor-lease.ts +415 -0
- package/src/editor-mode.ts +19 -0
- package/src/editor-notifications.ts +140 -0
- package/src/editor-presence.ts +563 -0
- package/src/editor-presentation-activity.ts +50 -0
- package/src/editor-presentation-notice.ts +42 -0
- package/src/editor-runtime.tsx +145 -0
- package/src/editor-server-response.ts +86 -0
- package/src/editor-session-attribution.ts +75 -0
- package/src/editor-session-mode.ts +54 -0
- package/src/editor-shell-store.ts +1304 -0
- package/src/editor-state-facets.ts +74 -0
- package/src/editor-styles.css +33 -0
- package/src/editor-view-presentation.ts +810 -0
- package/src/editor-viewport.ts +5302 -0
- package/src/entity-lod.ts +31 -0
- package/src/entity-object.ts +91 -0
- package/src/files/file-provider.ts +62 -0
- package/src/files/project-files.ts +264 -0
- package/src/finders/index.ts +136 -0
- package/src/finders/scenes-from-entrypoint-selection.ts +387 -0
- package/src/frame/bridge.tsx +1408 -0
- package/src/frame/product.ts +77 -0
- package/src/gameplay-dom-recording.ts +319 -0
- package/src/gameplay-export-state.ts +14 -0
- package/src/gameplay-replay.ts +417 -0
- package/src/gameplay-session-time.ts +9 -0
- package/src/gameplay-sessions.ts +204 -0
- package/src/harness-chat-types.ts +253 -0
- package/src/hierarchy-component-marks.ts +298 -0
- package/src/hierarchy-drop.ts +91 -0
- package/src/hierarchy-expansion-state.ts +80 -0
- package/src/hierarchy-header-slot.ts +52 -0
- package/src/hierarchy-internals.ts +197 -0
- package/src/hierarchy-kind-icon.ts +217 -0
- package/src/hierarchy-mark-reader.ts +73 -0
- package/src/hierarchy-menu-registry.ts +67 -0
- package/src/hierarchy-node-rows.ts +307 -0
- package/src/hierarchy-panel-view.ts +280 -0
- package/src/hierarchy-projection.ts +76 -0
- package/src/hierarchy-row-cache.ts +243 -0
- package/src/hierarchy-row-model.ts +308 -0
- package/src/hierarchy-rows.ts +11 -0
- package/src/hierarchy-walk.ts +86 -0
- package/src/history/editor-session.ts +25 -0
- package/src/history/history-commands.ts +147 -0
- package/src/history/history-delegate.ts +163 -0
- package/src/history/history-limit-notices.ts +43 -0
- package/src/history/history-service.ts +1173 -0
- package/src/history/persistence-coordinator.ts +35 -0
- package/src/history/project-file-history.ts +386 -0
- package/src/history/project-root-history-backends.ts +139 -0
- package/src/history/resource-registry.ts +209 -0
- package/src/history/snapshot-store.ts +103 -0
- package/src/history/source-history-backend.ts +546 -0
- package/src/history/types.ts +124 -0
- package/src/hmr-registration-group.ts +67 -0
- package/src/hmr-stable-react-context.ts +23 -0
- package/src/hotkeys.ts +188 -0
- package/src/inference-diagnostics.ts +69 -0
- package/src/initial-project.ts +80 -0
- package/src/inspection/active-subject.ts +578 -0
- package/src/inspection/active-surface.ts +142 -0
- package/src/inspection/compose.ts +1064 -0
- package/src/inspection/display.ts +170 -0
- package/src/inspection/document-subject.ts +109 -0
- package/src/inspection/game-subject.ts +85 -0
- package/src/inspection/model.ts +542 -0
- package/src/inspection/null-subject.ts +115 -0
- package/src/inspection/serialize.ts +357 -0
- package/src/inspection/use-active-inspection.ts +180 -0
- package/src/inspector-presentation.ts +201 -0
- package/src/inspector-section-registry.ts +221 -0
- package/src/instance-source-actions.ts +163 -0
- package/src/instanced-presentation.ts +164 -0
- package/src/js-heap.ts +71 -0
- package/src/key-actions.ts +91 -0
- package/src/keymap-presets.ts +401 -0
- package/src/layout-policy.ts +31 -0
- package/src/learn-links.ts +73 -0
- package/src/light-explorer-model.ts +134 -0
- package/src/live-canvas-frame.ts +55 -0
- package/src/live-document.ts +279 -0
- package/src/live-module-source.ts +230 -0
- package/src/live-session-registry.ts +220 -0
- package/src/live-transition.ts +633 -0
- package/src/manifest-project.ts +107 -0
- package/src/model-thumbnail.ts +523 -0
- package/src/native-selection-style.ts +202 -0
- package/src/object3d-document-write-policy.ts +137 -0
- package/src/packaged-runtime.ts +108 -0
- package/src/palettes/maya.palette.json +57 -0
- package/src/palettes/substance.palette.json +57 -0
- package/src/pasteboard-module.ts +81 -0
- package/src/performance-profiler.ts +367 -0
- package/src/performance-sources.ts +69 -0
- package/src/play-boot-phase.ts +145 -0
- package/src/presentation-surface.ts +248 -0
- package/src/project-adapter.ts +1143 -0
- package/src/project-asset-refresh.ts +26 -0
- package/src/project-declaration-refresh.ts +31 -0
- package/src/project-local-state.ts +118 -0
- package/src/project-manager.ts +243 -0
- package/src/project-module-changes.ts +163 -0
- package/src/project-module-split.ts +266 -0
- package/src/project-provenance.ts +115 -0
- package/src/project-ready.ts +42 -0
- package/src/project-session-reset.ts +67 -0
- package/src/project-shape.ts +68 -0
- package/src/project-tool-discovery.ts +66 -0
- package/src/project-tools.ts +107 -0
- package/src/project-work-types.ts +149 -0
- package/src/projection/three.ts +898 -0
- package/src/projection/types.ts +44 -0
- package/src/readiness.ts +113 -0
- package/src/reflection-probe-helper.ts +142 -0
- package/src/reported-play-state.ts +90 -0
- package/src/resolve-relative-specifier.ts +33 -0
- package/src/scene-document-plan.ts +315 -0
- package/src/scene-framing.ts +315 -0
- package/src/scene-live-open.ts +210 -0
- package/src/scene-view-fog.ts +89 -0
- package/src/scoped-game-css.ts +152 -0
- package/src/session-orphan-record.ts +193 -0
- package/src/session-tombstone.ts +126 -0
- package/src/settings/settings-provider.ts +82 -0
- package/src/settings-store.ts +345 -0
- package/src/shared-view-restore.ts +42 -0
- package/src/shell-store-door.ts +45 -0
- package/src/source-conflict.ts +122 -0
- package/src/spatial-handle-visuals.ts +332 -0
- package/src/stage-context.ts +341 -0
- package/src/stage-store-registry.ts +63 -0
- package/src/stale-chunk-recovery.ts +34 -0
- package/src/state-report-deferral.ts +73 -0
- package/src/storage/host-files-storage.ts +97 -0
- package/src/storage/http-storage.ts +174 -0
- package/src/storage/index.ts +75 -0
- package/src/storage/mem-storage.ts +149 -0
- package/src/storage/path-lock.ts +44 -0
- package/src/storage/paths.ts +26 -0
- package/src/storage/types.ts +116 -0
- package/src/stories/StoryComponentThumbnail.tsx +184 -0
- package/src/stories/StoryPreviewMount.tsx +306 -0
- package/src/stories/component-content-source.tsx +106 -0
- package/src/stories/component-states-source.ts +78 -0
- package/src/stories/compose-project-stories.ts +255 -0
- package/src/stories/pixi-story-model.ts +30 -0
- package/src/stories/prefabs-finder.ts +54 -0
- package/src/stories/prefabs-from-stories.ts +182 -0
- package/src/stories/project-story-discovery.ts +78 -0
- package/src/stories/project-story-regions.ts +24 -0
- package/src/stories/story-actions.ts +54 -0
- package/src/stories/story-capture-command.ts +124 -0
- package/src/stories/story-capture.ts +584 -0
- package/src/stories/story-declared-medium.ts +126 -0
- package/src/stories/story-discovery.ts +176 -0
- package/src/stories/story-document-openers.ts +36 -0
- package/src/stories/story-dom-runtime.ts +78 -0
- package/src/stories/story-grouping.ts +111 -0
- package/src/stories/story-lane.ts +88 -0
- package/src/stories/story-mount-turn.ts +27 -0
- package/src/stories/story-opener.ts +260 -0
- package/src/stories/story-pixi-preview.ts +408 -0
- package/src/stories/story-presentation.ts +215 -0
- package/src/stories/story-registry.ts +517 -0
- package/src/stories/story-three-preview.ts +807 -0
- package/src/stories/three-story-model.ts +96 -0
- package/src/story-three-preview-runtime.ts +56 -0
- package/src/surface-keyboard.ts +112 -0
- package/src/surface-state.ts +124 -0
- package/src/tab-bootstrap.js +628 -0
- package/src/tab-census.ts +198 -0
- package/src/tab-lifecycle-client.ts +196 -0
- package/src/theme-library.ts +844 -0
- package/src/theme-preference.ts +378 -0
- package/src/theme.css +3437 -0
- package/src/three-viewport/bone-selection-highlight.ts +119 -0
- package/src/three-viewport/camera-fit.ts +41 -0
- package/src/three-viewport/interactive-renderer.ts +132 -0
- package/src/three-viewport/selection-brackets.ts +310 -0
- package/src/three-viewport/selection-outline.ts +183 -0
- package/src/three-viewport/skeleton-helper.ts +61 -0
- package/src/three-viewport/source-color.ts +167 -0
- package/src/three-viewport/studio-environment.ts +96 -0
- package/src/three-viewport-presentation.ts +23 -0
- package/src/tool-contribution-play.ts +74 -0
- package/src/tool-loader.ts +1798 -0
- package/src/transform-mode-request.ts +57 -0
- package/src/transient-hint.ts +78 -0
- package/src/trigger-volume-helper.ts +116 -0
- package/src/ui-source/adapter-region-includes.ts +241 -0
- package/src/ui-source/ensure-import.ts +132 -0
- package/src/ui-source/file-region-resolver.ts +302 -0
- package/src/ui-source/inspect.ts +775 -0
- package/src/ui-source/oid-transform.ts +1845 -0
- package/src/ui-source/plan-csf-story.ts +196 -0
- package/src/ui-source/plan-extract-component.ts +421 -0
- package/src/ui-source/plan-fork-component.ts +621 -0
- package/src/ui-source/plan-named-style.ts +95 -0
- package/src/ui-source/plan-source-edit.ts +353 -0
- package/src/ui-source/r3f-contract-resolver.ts +327 -0
- package/src/ui-source/r3f-diagnostic-index.ts +165 -0
- package/src/ui-source/r3f-environment-binding.ts +133 -0
- package/src/ui-source/r3f-joint-binding.ts +251 -0
- package/src/ui-source/r3f-lod-binding.ts +91 -0
- package/src/ui-source/r3f-particle-binding.ts +235 -0
- package/src/ui-source/r3f-physics-binding.ts +483 -0
- package/src/ui-source/r3f-project-contracts.ts +444 -0
- package/src/ui-source/relative-import-specifier.ts +34 -0
- package/src/ui-source/reparent-guard.ts +544 -0
- package/src/ui-source/source-edit-request.ts +97 -0
- package/src/ui-source/source-write-backend.ts +618 -0
- package/src/ui-source/syntactic-prop-specs.ts +296 -0
- package/src/ui-source/tier-source-write-backend.ts +279 -0
- package/src/ui-source/ts-ast.ts +171 -0
- package/src/ui-source/utility-class-support.ts +169 -0
- package/src/ui-source/write-component-default.ts +133 -0
- package/src/ui-source/writer.ts +1989 -0
- package/src/viewport-activation-timings.ts +840 -0
- package/src/viewport-authoring-policy.ts +186 -0
- package/src/viewport-controls-hint.ts +57 -0
- package/src/viewport-door.ts +237 -0
- package/src/viewport-shading-boundary.ts +12 -0
- package/src/vite-error-surface.ts +141 -0
- package/src/wait-until.ts +37 -0
- package/src/workspace-areas.ts +156 -0
- package/src/workspace-aux-commands.ts +11 -0
- package/src/workspace-available-documents.ts +127 -0
- package/src/workspace-core-utilities.ts +31 -0
- package/src/workspace-document-ids.ts +59 -0
- package/src/workspace-document-registry.ts +612 -0
- package/src/workspace-document-restore.ts +145 -0
- package/src/workspace-host-commands.ts +141 -0
- package/src/workspace-persistence-gate.ts +40 -0
- package/src/workspace-play-utilities.ts +44 -0
- package/src/workspace-presets.ts +425 -0
- package/src/workspace-regions.ts +294 -0
- package/src/workspace-state-persistence.ts +536 -0
- package/src/workspace-static-panels.ts +73 -0
- package/src/workspace-status-registry.ts +121 -0
- package/src/workspace-style.ts +239 -0
- package/src/workspace-utility-commands.ts +74 -0
- package/src/workspace-utility-registry.ts +263 -0
- package/src/workspace-viewport-rect.ts +97 -0
- package/src/world-adoption.ts +115 -0
- package/src/world-document-routing.ts +104 -0
- package/vite-plugin-creation-site-write.ts +184 -0
- package/vite-plugin-creation-site.ts +80 -0
- package/vite-plugin-game-static.ts +303 -0
- package/vite-plugin-module-doorways.ts +336 -0
- package/vite-plugin-product-contributions.ts +197 -0
- package/vite-plugin-project-game-static.ts +125 -0
- package/vite-plugin-project-jsx-js.ts +65 -0
- package/vite-plugin-project-root-absolute-assets.ts +359 -0
- package/vite-plugin-shared-react.ts +420 -0
- package/vite-plugin-shared-three.ts +203 -0
- package/vite-plugin-ui-oid.ts +2106 -0
|
@@ -0,0 +1,542 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The INSPECTION MODEL — the data the inspector is a view of (design:
|
|
3
|
+
* `docs/ARCHITECTURE-CORE.md` §Editor chrome, "The Inspection Model"; build
|
|
4
|
+
* ledger: `docs/WORK.md` §Inspection Model program).
|
|
5
|
+
*
|
|
6
|
+
* Layer 0 is the typed field vocabulary ({@link FieldDescriptor}, a superset
|
|
7
|
+
* of the engine's `PropertyDescriptor`, plus the {@link MIXED} sentinel so
|
|
8
|
+
* multi-select is in the value model from day one). Layer 1 is
|
|
9
|
+
* {@link InspectionSubject} — identity, quick actions, related links,
|
|
10
|
+
* sections. Layer 2 is {@link InspectionSection} — an IDENTIFIED block whose
|
|
11
|
+
* `body` is a field list, an opaque custom render, or the subject's live
|
|
12
|
+
* preview.
|
|
13
|
+
*
|
|
14
|
+
* EVERYTHING a projection shows is here. What you click on decides the
|
|
15
|
+
* subject; the subject decides the sections; the box is a pure view of that —
|
|
16
|
+
* the section-icon strip IS `subject.sections`, each stacked section's body IS
|
|
17
|
+
* its own render, the header IS its title and icon. There is deliberately no
|
|
18
|
+
* channel beside the section list, not even for the live preview
|
|
19
|
+
* ({@link PREVIEW_SECTION_ID} is an ordinary section): a subject part that
|
|
20
|
+
* only one projection knew where to put is how two projections stop being the
|
|
21
|
+
* same box.
|
|
22
|
+
*
|
|
23
|
+
* Layer 3 — the projections — is NOT here: `components/Inspector.tsx` renders
|
|
24
|
+
* this model as the narrow column or the mini card, and
|
|
25
|
+
* `inspector-presentation.ts` maps the same sections onto the section-icon
|
|
26
|
+
* strip. A projection reads identity/order/title/icon off the model; it never
|
|
27
|
+
* re-derives what a section IS.
|
|
28
|
+
*
|
|
29
|
+
* This module is deliberately close to React-free: only the opaque section
|
|
30
|
+
* bodies (a contributed custom block, the live preview) name `ReactNode`.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { IconDefinition } from '@fortawesome/free-solid-svg-icons';
|
|
34
|
+
import type { PropertyDescriptor, WriteAck } from '@volter/editor-project/adapter';
|
|
35
|
+
import type { ReactNode } from 'react';
|
|
36
|
+
|
|
37
|
+
// ---- Layer 0: fields -----------------------------------------------------
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* "These subjects disagree about this field." Reserved by the design so that
|
|
41
|
+
* multi-select is expressible in the value model before multi-select EDITING
|
|
42
|
+
* is built: an io that spans more than one subject returns this instead of
|
|
43
|
+
* inventing one of the values. Single-subject inspection (all of W1) never
|
|
44
|
+
* produces it; the field renderer normalizes it to "no single value" (blank +
|
|
45
|
+
* placeholder), which is the correct reading, not a special case.
|
|
46
|
+
*/
|
|
47
|
+
export const MIXED: unique symbol = Symbol('vgai.inspection.mixed');
|
|
48
|
+
export type Mixed = typeof MIXED;
|
|
49
|
+
|
|
50
|
+
/** A value read from an inspection subject: a real value, or {@link MIXED}. */
|
|
51
|
+
export type FieldValue<T> = T | Mixed;
|
|
52
|
+
|
|
53
|
+
export function isMixed(value: unknown): value is Mixed {
|
|
54
|
+
return value === MIXED;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/**
|
|
58
|
+
* The inspection layer's field vocabulary — structurally the engine adapter
|
|
59
|
+
* seam's `PropertyDescriptor` (stable scriptable `path`, `type`, `label`,
|
|
60
|
+
* `group`, `defaulted`, `readonly`, `resettable`, `revertsTo`), named here so
|
|
61
|
+
* the model has one address space of its own. Additive kinds
|
|
62
|
+
* (`color`/`vec3`/`asset-ref` beyond what the seam already carries) land in a
|
|
63
|
+
* later wave by widening the seam, never by forking a second descriptor
|
|
64
|
+
* shape here.
|
|
65
|
+
*/
|
|
66
|
+
export interface FieldDescriptor extends PropertyDescriptor {}
|
|
67
|
+
|
|
68
|
+
/** The one explanation every projection and write door uses for a read-only
|
|
69
|
+
* field. An adapter can name its actual gate; the fallback remains honest for
|
|
70
|
+
* inherently informational fields that have no more specific refusal. */
|
|
71
|
+
export function fieldReadonlyReason(field: FieldDescriptor): string {
|
|
72
|
+
return field.readonlyReason ?? 'This field is read-only.';
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
/** Read/write access to one subject's fields, addressed by `path`. */
|
|
76
|
+
export interface InspectionFieldIo {
|
|
77
|
+
get(path: string): FieldValue<unknown>;
|
|
78
|
+
/**
|
|
79
|
+
* Write one field — and answer for THAT write with the persistence pipe's
|
|
80
|
+
* own {@link WriteAck} (`authoring/write-pipe.ts`), passed straight through
|
|
81
|
+
* from whichever provider performed it. `void` is the honest report of an io
|
|
82
|
+
* that performed no persisted write; the caller then reports the live-only
|
|
83
|
+
* floor rather than reading a destination off the surface, which is what
|
|
84
|
+
* made a three-root edit ack the DOM root's file with `persisted: true`.
|
|
85
|
+
*/
|
|
86
|
+
set(path: string, value: unknown): void | WriteAck | Promise<void | WriteAck>;
|
|
87
|
+
/**
|
|
88
|
+
* Optional — SHOW a value without writing it, for a control the user drags
|
|
89
|
+
* (seam: `InspectorProvider.preview`). Never persists; the control calls
|
|
90
|
+
* {@link set} once when its gesture ends. Absent ⇒ the control's preview is
|
|
91
|
+
* a no-op and the value still lands on commit.
|
|
92
|
+
*/
|
|
93
|
+
preview?(path: string, value: unknown): void;
|
|
94
|
+
/**
|
|
95
|
+
* Drop the document's override (Unity's revert arrow) — the ONE door that can
|
|
96
|
+
* express byte-ABSENCE, because {@link set} can only write a value.
|
|
97
|
+
*
|
|
98
|
+
* Same ack contract as `set`: the persistence pipe's own {@link WriteAck} for
|
|
99
|
+
* THIS removal, passed straight through, awaited. Absent ⇒ no field in this
|
|
100
|
+
* section can lose its override, and `remove-inspection-field` refuses by name
|
|
101
|
+
* instead of silently degrading to a value write that would leave the prop in
|
|
102
|
+
* the file.
|
|
103
|
+
*/
|
|
104
|
+
remove?(path: string): void | WriteAck | Promise<void | WriteAck>;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// ---- Layer 1: subjects ---------------------------------------------------
|
|
108
|
+
|
|
109
|
+
/**
|
|
110
|
+
* The SURFACE a subject belongs to — the axis presentation affinity and the
|
|
111
|
+
* user's presentation preference are keyed by. `three`/`canvas`/`dom` are the
|
|
112
|
+
* engine's own `AdapterSurface` values; `asset-lab` is an open asset document,
|
|
113
|
+
* which is the three paradigm scoped to a SUBTREE (Unity's prefab-isolation
|
|
114
|
+
* mode: same view, same hierarchy, same inspector — only the root changes).
|
|
115
|
+
*
|
|
116
|
+
* A surface decides two things and NOTHING else: which producer composes the
|
|
117
|
+
* subject, and which key the presentation preference is stored under. It never
|
|
118
|
+
* decides what a projection renders — that is subject data, all of it.
|
|
119
|
+
*/
|
|
120
|
+
export type InspectionSurfaceKind = 'three' | 'canvas' | 'dom' | 'asset-lab';
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Layer 3's three projections, named in the model so a subject can say which
|
|
124
|
+
* one FITS it (never which one is showing — that is the resolver's answer):
|
|
125
|
+
* - `column` — the DEFAULT: the subject's full inspector as a slim vertical
|
|
126
|
+
* column — identity row, a section-icon strip that signposts what the
|
|
127
|
+
* subject has and jumps to a section, then every section stacked and
|
|
128
|
+
* collapsible;
|
|
129
|
+
* - `properties` — the same docked column with the sections TABBED instead
|
|
130
|
+
* of stacked: a vertical icon rail down the left edge, one section body at
|
|
131
|
+
* a time (Blender's Properties editor, Substance's too). A workspace
|
|
132
|
+
* chooses it as data (`EditorWorkspaceRegions.inspector`); the user's
|
|
133
|
+
* per-surface preference still wins;
|
|
134
|
+
* - `card` — the space-tight fallback: a MINI card (preview, name, the same
|
|
135
|
+
* icon strip) collapsing at the floor to a single-line PILL. Clicking any
|
|
136
|
+
* collapsed form restores the column.
|
|
137
|
+
*
|
|
138
|
+
* They differ in LAYOUT only. All three read the same subject, render the
|
|
139
|
+
* same identity and section data; the icon strip, the rail and the column's
|
|
140
|
+
* collapse triangles are the layout's own affordances.
|
|
141
|
+
*/
|
|
142
|
+
export type InspectionPresentation = 'card' | 'column' | 'properties';
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* The subject's presentation AFFINITY — what fits this surface when the user
|
|
146
|
+
* has expressed no preference for it. The default is the narrow `column` on
|
|
147
|
+
* every surface (owner, 2026-08-19): with agents doing most editing the
|
|
148
|
+
* inspector's daily job is looking, and an always-present slim column reads
|
|
149
|
+
* details with no discovery-dependent expand gesture. The mini card is a
|
|
150
|
+
* space-tight fallback the user opts into, not a per-surface default.
|
|
151
|
+
*/
|
|
152
|
+
export interface InspectionPresentationAffinity {
|
|
153
|
+
readonly preferred: InspectionPresentation;
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
/**
|
|
157
|
+
* The affinity for a surface — the ONE place the default lives, shared by the
|
|
158
|
+
* composer (which stamps it onto the subject) and the workspace (which must
|
|
159
|
+
* resolve the same answer without composing).
|
|
160
|
+
*
|
|
161
|
+
* The narrow `column` is the default for EVERY surface (owner, 2026-08-19):
|
|
162
|
+
* the card demoted from default to a space-tight fallback the user opts into
|
|
163
|
+
* per surface. The `kind` still selects which producer composed the subject
|
|
164
|
+
* and which key a preference is stored under; it no longer picks the layout.
|
|
165
|
+
*/
|
|
166
|
+
export function inspectionAffinityFor(
|
|
167
|
+
_kind: InspectionSurfaceKind | undefined,
|
|
168
|
+
): InspectionPresentation {
|
|
169
|
+
return 'column';
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
/**
|
|
173
|
+
* Where a projection puts a verb. `identity` verbs sit on the subject's name
|
|
174
|
+
* row (today: the visibility eye); `preview` verbs are rendered over the
|
|
175
|
+
* preview SECTION's body, in the box, identically in both projections (today:
|
|
176
|
+
* the Asset Editor jump). A projection places by this, never by action id — a
|
|
177
|
+
* renderer that branches on "is this the asset-editor button" would be exactly
|
|
178
|
+
* the content knowledge this model exists to remove.
|
|
179
|
+
*/
|
|
180
|
+
export type InspectionActionPlacement = 'identity' | 'preview';
|
|
181
|
+
|
|
182
|
+
/** A verb on the subject itself. */
|
|
183
|
+
export interface InspectionAction {
|
|
184
|
+
/** Stable id; also the projection's `data-testid`. */
|
|
185
|
+
readonly id: string;
|
|
186
|
+
/** Accessible name + tooltip — ONE string, both roles. */
|
|
187
|
+
readonly title: string;
|
|
188
|
+
/** Visible text, for verbs presented as a labelled button. */
|
|
189
|
+
readonly label?: string | undefined;
|
|
190
|
+
/** Icon, for verbs presented as an icon button. */
|
|
191
|
+
readonly icon?: IconDefinition | undefined;
|
|
192
|
+
readonly placement: InspectionActionPlacement;
|
|
193
|
+
/** Toggle state (`aria-pressed`), for verbs that have one. */
|
|
194
|
+
readonly pressed?: boolean | undefined;
|
|
195
|
+
readonly disabled?: boolean | undefined;
|
|
196
|
+
readonly run: () => void | Promise<void>;
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/** The subject's verbs for one placement — the ONE expression both
|
|
200
|
+
* projections filter with, so "the eye is on the identity row and the Asset
|
|
201
|
+
* Editor jump is in the preview box" cannot be true in one and false in the
|
|
202
|
+
* other. */
|
|
203
|
+
export function actionsPlacedAt(
|
|
204
|
+
subject: InspectionSubject,
|
|
205
|
+
placement: InspectionActionPlacement,
|
|
206
|
+
): readonly InspectionAction[] {
|
|
207
|
+
return subject.quickActions.filter((action) => action.placement === placement);
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
/**
|
|
211
|
+
* A jump to a RELATED subject (the derivation chain: entity → its Asset Lab
|
|
212
|
+
* document → its state machine). Adapters publish these links from the same
|
|
213
|
+
* subject they inspect, so every projection and the serialized agent view get
|
|
214
|
+
* the same navigation without hand-rolled "Open in X" buttons.
|
|
215
|
+
*/
|
|
216
|
+
export interface SubjectLink {
|
|
217
|
+
readonly id: string;
|
|
218
|
+
readonly title: string;
|
|
219
|
+
readonly open: () => void;
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
/** The editable name field on the identity row. */
|
|
223
|
+
export interface InspectionRename {
|
|
224
|
+
readonly readOnly: boolean;
|
|
225
|
+
readonly set: (next: string) => void;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
/** A secondary provenance line under the identity row (today: where the
|
|
229
|
+
* object was constructed in the game's own source). */
|
|
230
|
+
export interface InspectionNote {
|
|
231
|
+
readonly text: string;
|
|
232
|
+
/** Long-form tooltip, when the one-line text is a summary. */
|
|
233
|
+
readonly title?: string | undefined;
|
|
234
|
+
readonly testId?: string | undefined;
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* The subject's identity ROW — the editable name, what to call its type, and
|
|
239
|
+
* the provenance line under it. Identity belongs to the SUBJECT, not to any
|
|
240
|
+
* section (design: ARCHITECTURE-CORE §Editor chrome), so it is one nullable
|
|
241
|
+
* group here rather than a boolean gate over loose fields. Sections are
|
|
242
|
+
* FACETS of the subject and never stand in for its identity; a projection
|
|
243
|
+
* renders this row exactly when it is present.
|
|
244
|
+
*/
|
|
245
|
+
/**
|
|
246
|
+
* WHERE the subject's truth is written — the active adapter's own persistence
|
|
247
|
+
* destination, as a secondary line on the identity row.
|
|
248
|
+
*
|
|
249
|
+
* This is Blender's Properties datablock row, and it is the reason the
|
|
250
|
+
* Hierarchy panel no longer carries a breadcrumb row of its own: which file
|
|
251
|
+
* and which kind is a fact about the THING being inspected, not about the
|
|
252
|
+
* tree that lists it (Blender's Outliner header is one row and names no
|
|
253
|
+
* file). The seam word — `source`, an ingest's own label — is already on this
|
|
254
|
+
* row in {@link InspectionIdentity.kindLabel}, so the line carries the path
|
|
255
|
+
* and nothing else.
|
|
256
|
+
*/
|
|
257
|
+
export interface InspectionDocumentLine {
|
|
258
|
+
/** The adapter's persistence destination, verbatim (`src/models/cube.ts`). */
|
|
259
|
+
readonly path: string;
|
|
260
|
+
/** Long-form provenance for the row's tooltip, when the seam declares one. */
|
|
261
|
+
readonly title?: string | undefined;
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
export interface InspectionIdentity {
|
|
265
|
+
readonly rename: InspectionRename;
|
|
266
|
+
/** What to CALL this thing's type (+ seam provenance), under the name. */
|
|
267
|
+
readonly kindLabel?: string | undefined;
|
|
268
|
+
/**
|
|
269
|
+
* The adapter's own KIND NAME for this thing — `mesh`, `light`,
|
|
270
|
+
* `mesh-data`, `three-source` — unformatted, which is the only difference
|
|
271
|
+
* between it and {@link InspectionIdentity.kindLabel}: both are built from
|
|
272
|
+
* the same `EditorNode.kind`, and a projection that has to DRAW the kind
|
|
273
|
+
* cannot draw a sentence.
|
|
274
|
+
*
|
|
275
|
+
* It exists because Blender's Properties breadcrumb leads with the
|
|
276
|
+
* DATABLOCK's glyph and never the open tab's — proved byte-identically on
|
|
277
|
+
* the frames: the first breadcrumb glyph in `properties-object.png`,
|
|
278
|
+
* `properties-modifier.png` and `properties-data-edit.png` is the same
|
|
279
|
+
* 28x28 device crop with 0 of 784 pixels differing, while the open tab is
|
|
280
|
+
* Object, Modifier and Data in turn. Neither derivation the row had could
|
|
281
|
+
* answer that: `sections[0].icon` is RAIL ORDER and the active tab's icon
|
|
282
|
+
* is the tab. The host already turns a kind name into a glyph in exactly
|
|
283
|
+
* one place (`hierarchy-kind-icon.ts`, which rules that the kind name is
|
|
284
|
+
* the carrier and `EditorNode` gains no field for it), so this carries the
|
|
285
|
+
* name there rather than a second glyph anywhere.
|
|
286
|
+
*/
|
|
287
|
+
readonly kind?: string | undefined;
|
|
288
|
+
/** The document this subject is written back to. */
|
|
289
|
+
readonly document?: InspectionDocumentLine | undefined;
|
|
290
|
+
readonly note?: InspectionNote | undefined;
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
export interface InspectionSubject {
|
|
294
|
+
readonly id: string;
|
|
295
|
+
/** Display name of the thing being inspected. */
|
|
296
|
+
readonly title: string;
|
|
297
|
+
/** The identity row, or `null` for a subject that has no identity to show
|
|
298
|
+
* (a no-selection subject whose surface named no type). */
|
|
299
|
+
readonly identity: InspectionIdentity | null;
|
|
300
|
+
/**
|
|
301
|
+
* A quiet line for a subject with nothing to EDIT — today the no-selection
|
|
302
|
+
* subject's own explanation of what its surface inspects ("Select an
|
|
303
|
+
* element in the canvas…"). A projection renders it under
|
|
304
|
+
* {@link InspectionSubject.title} in place of the identity row; it is a
|
|
305
|
+
* string off the model, so no renderer learns which surface produced it.
|
|
306
|
+
*/
|
|
307
|
+
readonly hint?: string | undefined;
|
|
308
|
+
/** Which projection FITS this subject's surface. The resolver
|
|
309
|
+
* (`inspector-presentation.ts`) picks the actual presentation from this
|
|
310
|
+
* plus the user's per-surface override. */
|
|
311
|
+
readonly presentation: InspectionPresentationAffinity;
|
|
312
|
+
/** Descriptor writes represented outside a section body. The identity-row
|
|
313
|
+
* visibility eye is the first case: it must stay one compact verb for a
|
|
314
|
+
* person while remaining the same `editor.setField` adjustment for an
|
|
315
|
+
* agent. This is a control seam only; projections render the owning chrome. */
|
|
316
|
+
readonly editable?: {
|
|
317
|
+
readonly fields: readonly FieldDescriptor[];
|
|
318
|
+
readonly io: InspectionFieldIo;
|
|
319
|
+
};
|
|
320
|
+
/**
|
|
321
|
+
* How many OTHER things are selected alongside this subject, when more than
|
|
322
|
+
* one is. The box describes ONE of them — the one whose fields these are —
|
|
323
|
+
* but a gizmo drag moves all of them, so a panel headed by a single name
|
|
324
|
+
* while three objects move is the box lying about its own scope: a tester
|
|
325
|
+
* shift-selected three models, watched all three move, and reported that
|
|
326
|
+
* "the inspector only shows the first object" (runhuman pass 94). Absent
|
|
327
|
+
* for a single selection, which is the overwhelmingly common case and needs
|
|
328
|
+
* no count.
|
|
329
|
+
*/
|
|
330
|
+
readonly alsoSelected?: number | undefined;
|
|
331
|
+
readonly quickActions: readonly InspectionAction[];
|
|
332
|
+
readonly related: readonly SubjectLink[];
|
|
333
|
+
/** Sections in display order (already sorted by {@link InspectionSection.order}). */
|
|
334
|
+
readonly sections: readonly InspectionSection[];
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
// ---- Layer 2: sections ---------------------------------------------------
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* The JSON-safe VALUES a custom body publishes beside its render — the one
|
|
341
|
+
* thing an opaque body can honestly say about its own contents.
|
|
342
|
+
*
|
|
343
|
+
* A custom body replaces rendering, so the visual projections read nothing
|
|
344
|
+
* here and the serialized projection (`inspection/serialize.ts`) is its only
|
|
345
|
+
* reader: an agent calling `editor.inspect` gets the section's values instead
|
|
346
|
+
* of a name it cannot look inside. The channel is deliberately a flat,
|
|
347
|
+
* anonymous record rather than a per-section body kind — the producer
|
|
348
|
+
* (`inspection/compose.ts`) is the layer that knows what a section IS, and
|
|
349
|
+
* teaching the serializer one more content name would put that knowledge back
|
|
350
|
+
* in a projection.
|
|
351
|
+
*
|
|
352
|
+
* The rule for a producer filling it: publish WHAT THE BODY DISPLAYS, in the
|
|
353
|
+
* body's own units — the Transform section shows Euler XYZ degrees, so that
|
|
354
|
+
* is what it publishes, not the quaternion behind them.
|
|
355
|
+
*/
|
|
356
|
+
export type InspectionSectionData = Readonly<Record<string, unknown>>;
|
|
357
|
+
|
|
358
|
+
export type InspectionSectionBody =
|
|
359
|
+
| {
|
|
360
|
+
readonly kind: 'fields';
|
|
361
|
+
readonly fields: readonly FieldDescriptor[];
|
|
362
|
+
readonly io: InspectionFieldIo;
|
|
363
|
+
}
|
|
364
|
+
/** An opaque block the model does not model — a contributed React section,
|
|
365
|
+
* or a built-in with chrome of its own (Transform, Stories). Custom
|
|
366
|
+
* bodies replace RENDERING, never identity: the section keeps its id,
|
|
367
|
+
* title, icon and order — and may publish its displayed values as
|
|
368
|
+
* {@link InspectionSectionData} for the readers that cannot render. */
|
|
369
|
+
| {
|
|
370
|
+
readonly kind: 'custom';
|
|
371
|
+
readonly render: () => ReactNode;
|
|
372
|
+
readonly data?: InspectionSectionData;
|
|
373
|
+
/**
|
|
374
|
+
* The WRITE half of {@link data}, for a body whose chrome is custom but
|
|
375
|
+
* whose values are ordinary editable fields.
|
|
376
|
+
*
|
|
377
|
+
* Without it, a custom body is readable over the wire and writable only
|
|
378
|
+
* by a person typing in its rendered rows — which for the TRANSFORM
|
|
379
|
+
* section meant an agent could read a position, read the sentence
|
|
380
|
+
* explaining whether it may be moved, and have no way to move it. An
|
|
381
|
+
* ingest root has no source file to hand-edit instead, so that was the
|
|
382
|
+
* whole authoring surface, closed.
|
|
383
|
+
*
|
|
384
|
+
* `io.set` must be the SAME write the rendered chrome performs (the
|
|
385
|
+
* Transform section's is `onCommit`'s begin/apply/end), so there is one
|
|
386
|
+
* write path and not two that can disagree.
|
|
387
|
+
*/
|
|
388
|
+
readonly editable?: {
|
|
389
|
+
readonly fields: readonly FieldDescriptor[];
|
|
390
|
+
readonly io: InspectionFieldIo;
|
|
391
|
+
};
|
|
392
|
+
}
|
|
393
|
+
/**
|
|
394
|
+
* The subject's live PREVIEW — a square view of the thing itself. It is a
|
|
395
|
+
* section like every other: it has an id, a title, an icon and an order, it
|
|
396
|
+
* is one glyph on the section-icon strip and one block in the column, and it
|
|
397
|
+
* exists exactly when the subject has something honest to show.
|
|
398
|
+
*
|
|
399
|
+
* `render` fills whatever box it is given, at any size — the section body,
|
|
400
|
+
* the mini card's preview square, and the pill's small thumb — which is why
|
|
401
|
+
* one function serves them all and no host re-derives what the subject looks
|
|
402
|
+
* like. The {@link InspectionPreviewMode} is how the host says which of those
|
|
403
|
+
* it is; omitting it means `'section'`.
|
|
404
|
+
*/
|
|
405
|
+
| {
|
|
406
|
+
readonly kind: 'preview';
|
|
407
|
+
readonly render: (mode?: InspectionPreviewMode) => ReactNode;
|
|
408
|
+
};
|
|
409
|
+
|
|
410
|
+
/**
|
|
411
|
+
* How a preview body is being HOSTED — the one thing a preview's renderer
|
|
412
|
+
* needs to know about its box, and deliberately not a second render function.
|
|
413
|
+
*
|
|
414
|
+
* - `section` (the default): the full box. The subject's `preview`-placed
|
|
415
|
+
* verbs sit in it, inside the section's own inset and border — the panel is
|
|
416
|
+
* the preview's landing view, so its verbs belong there.
|
|
417
|
+
* - `thumbnail`: chrome-free FILL — the live view alone, edge to edge, with no
|
|
418
|
+
* inset, no border and NO VERBS. The small hosts (the mini card's preview
|
|
419
|
+
* square, the pill's round thumb) clip it and own the single click on it
|
|
420
|
+
* themselves, so an interactive control inside would be both a second
|
|
421
|
+
* navigation from one press and a focusable fragment of a clipped button.
|
|
422
|
+
*/
|
|
423
|
+
export type InspectionPreviewMode = 'section' | 'thumbnail';
|
|
424
|
+
|
|
425
|
+
/**
|
|
426
|
+
* One identified block of a subject. EVERY section is headed by its own title
|
|
427
|
+
* and icon in EVERY projection (owner, 2026-08-06: "the title of that specific
|
|
428
|
+
* section is always supposed to be at the top of the section — this should be
|
|
429
|
+
* consistent for all sections. And all sections need to have an icon") — the
|
|
430
|
+
* column, the mini card, and the Asset Lab's box alike. So
|
|
431
|
+
* there is no opt-out flag here: `title` and `icon` are required, and a
|
|
432
|
+
* projection renders the header unconditionally. A custom body that also
|
|
433
|
+
* printed its own name would say it twice, which is why the bodies that used
|
|
434
|
+
* to (Transform, Stories, Navigation) no longer do.
|
|
435
|
+
*/
|
|
436
|
+
export interface InspectionSection {
|
|
437
|
+
/** Stable id — the section-icon strip's jump target, and the key a registry
|
|
438
|
+
* contribution CLAIMS to replace a built-in. */
|
|
439
|
+
readonly id: string;
|
|
440
|
+
readonly title: string;
|
|
441
|
+
readonly icon: IconDefinition;
|
|
442
|
+
/** Display order; the composer returns sections already sorted by it. */
|
|
443
|
+
readonly order: number;
|
|
444
|
+
readonly body: InspectionSectionBody;
|
|
445
|
+
/** Supporting line beside the title ("3 set of 12"). */
|
|
446
|
+
readonly description?: string | undefined;
|
|
447
|
+
/** Initial open state for the section header. */
|
|
448
|
+
readonly defaultOpen?: boolean | undefined;
|
|
449
|
+
/** `data-testid` for the section's wrapper, when it has one. */
|
|
450
|
+
readonly testId?: string | undefined;
|
|
451
|
+
/**
|
|
452
|
+
* Stay MOUNTED while another tab is showing. The properties column shows one
|
|
453
|
+
* section at a time; a section that HOSTS contributions which publish what
|
|
454
|
+
* they know while rendered (an asset's `asset.inspector` sections and the
|
|
455
|
+
* verbs they publish into the identity row and `editor.inspect()`) must keep
|
|
456
|
+
* rendering, hidden, or the verb would exist only after a person visits its
|
|
457
|
+
* tab. Sections that merely display leave this unset.
|
|
458
|
+
*/
|
|
459
|
+
readonly keepMounted?: boolean | undefined;
|
|
460
|
+
/**
|
|
461
|
+
* WHICH GROUP OF THE RAIL this section belongs to — read by the PROPERTIES
|
|
462
|
+
* presentation alone, which draws a separator wherever the group changes.
|
|
463
|
+
*
|
|
464
|
+
* Blender's own rail is grouped rather than flat: `ED_buttons_tabs_list`
|
|
465
|
+
* (`space_buttons/space_buttons.cc:201-255`) calls `add_spacer()` between
|
|
466
|
+
* the tool tab, the scene group (Render, Output, View Layer, Scene, World),
|
|
467
|
+
* Collection, the object group (Object, Modifiers, Effects, Particles,
|
|
468
|
+
* Physics, Constraints, Data, Bone, Bone Constraints, Material) and
|
|
469
|
+
* Texture, and each spacer appends a `BCONTEXT_SEPARATOR` the rail draws as
|
|
470
|
+
* a gap rather than a tab. The name is free and compared for equality only;
|
|
471
|
+
* consecutive sections sharing one form a group, and sections that name
|
|
472
|
+
* none form a group of their own.
|
|
473
|
+
*/
|
|
474
|
+
readonly railGroup?: string | undefined;
|
|
475
|
+
/**
|
|
476
|
+
* THE TAB THE RAIL OPENS ON, before a person has chosen one for this
|
|
477
|
+
* subject. The Properties presentation otherwise takes the FIRST tab, and
|
|
478
|
+
* Blender does not: its `SpaceProperties.context` is stored per screen in
|
|
479
|
+
* the startup file, and at factory settings `bpy.data.screens['Layout']`
|
|
480
|
+
* reads `OBJECT` while the rail's first tab is Render (measured against
|
|
481
|
+
* Blender 5.2 LTS, walk 5 parity row 3). At most one section should declare
|
|
482
|
+
* it; the first that does wins, and a rail with none opens on its first tab
|
|
483
|
+
* as before.
|
|
484
|
+
*/
|
|
485
|
+
readonly railDefault?: boolean | undefined;
|
|
486
|
+
}
|
|
487
|
+
|
|
488
|
+
// ---- Section identity ----------------------------------------------------
|
|
489
|
+
//
|
|
490
|
+
// The ids are a CONTRACT: they are the section-icon strip's jump targets, and
|
|
491
|
+
// a registry contribution REPLACES a built-in by claiming its id
|
|
492
|
+
// (`inspection/compose.ts`) — the whole of the positive-space replacement
|
|
493
|
+
// protocol.
|
|
494
|
+
|
|
495
|
+
/** The subject's live preview. First in every projection: the first block in
|
|
496
|
+
* the column, and on the mini card the preview square above the name. */
|
|
497
|
+
export const PREVIEW_SECTION_ID = 'preview';
|
|
498
|
+
export const TRANSFORM_SECTION_ID = 'transform';
|
|
499
|
+
/**
|
|
500
|
+
* The adapter's DESCRIPTOR GRID — the ungrouped (loose) fields, plus the
|
|
501
|
+
* `group:<id>` sub-sections its named `PropertyDescriptor.group`s produce.
|
|
502
|
+
* Claiming this id therefore claims the whole descriptor channel: a
|
|
503
|
+
* contribution that renders a node's properties richly presents its groups
|
|
504
|
+
* too, and the generic grid must not double-render them beside it.
|
|
505
|
+
*/
|
|
506
|
+
export const PROPERTIES_SECTION_ID = 'properties';
|
|
507
|
+
export const STORIES_SECTION_ID = 'stories';
|
|
508
|
+
|
|
509
|
+
/** A shared FACET id, contributed rather than built in: the args of the open
|
|
510
|
+
* story document. Every story-document surface (React CSF, three) registers
|
|
511
|
+
* its own body for it under this one identity, because it is the same facet
|
|
512
|
+
* of the same kind of subject seen from a different lane. */
|
|
513
|
+
export const STORY_ARGS_SECTION_ID = 'story-args';
|
|
514
|
+
export const STORY_ARGS_SECTION_TITLE = 'Story Args';
|
|
515
|
+
// The section's GLYPH lives in `components/story-args-section.ts` — this
|
|
516
|
+
// data-model module stays free of the icon package (see that file), and the
|
|
517
|
+
// icon must be DISTINCT from the generic property grid's `faSliders` so the
|
|
518
|
+
// section-icon strip's glyphs never collide.
|
|
519
|
+
|
|
520
|
+
/** A named `PropertyDescriptor.group`'s section (`groupId` is the slug from
|
|
521
|
+
* `inspector-property-grouping.ts`) — a sub-section OF
|
|
522
|
+
* {@link PROPERTIES_SECTION_ID}'s channel. */
|
|
523
|
+
export function groupSectionId(groupId: string): string {
|
|
524
|
+
return `group:${groupId}`;
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
// ---- Section order -------------------------------------------------------
|
|
528
|
+
//
|
|
529
|
+
// Display order, spaced so a channel can grow without colliding with the
|
|
530
|
+
// next. A contribution declares its own order on the same scale
|
|
531
|
+
// (`InspectorSectionContribution.order`); the composer sorts STABLY, so
|
|
532
|
+
// equal-ordered contributions keep registration order.
|
|
533
|
+
|
|
534
|
+
export const PREVIEW_SECTION_ORDER = 100;
|
|
535
|
+
export const TRANSFORM_SECTION_ORDER = 1000;
|
|
536
|
+
export const PROPERTIES_SECTION_ORDER = 2000;
|
|
537
|
+
export const GROUP_SECTION_ORDER = 3000;
|
|
538
|
+
export const STORIES_SECTION_ORDER = 4000;
|
|
539
|
+
/** Where a registry contribution sits unless it says otherwise: after every
|
|
540
|
+
* built-in block. A contribution that CLAIMS a built-in id replaces that
|
|
541
|
+
* block's identity, not necessarily its position. */
|
|
542
|
+
export const CONTRIBUTED_SECTION_ORDER = 5000;
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The NO-SELECTION subject seam — `describeSubject(null)`, per adapter
|
|
3
|
+
* (design: `docs/ARCHITECTURE-CORE.md` §Editor chrome, "The Inspection
|
|
4
|
+
* Model"; build ledger: `docs/WORK.md` §Inspection Model program, W3).
|
|
5
|
+
*
|
|
6
|
+
* An empty inspector is not a shared blank: it is a SUBJECT, and whose
|
|
7
|
+
* subject it is depends entirely on which surface you are looking at. The
|
|
8
|
+
* defect this exists for (measured live, 2026-08-05): with a react/DOM
|
|
9
|
+
* document active and nothing selected in it, the inspector rendered the
|
|
10
|
+
* THREE scene's Background/Fog/Bake-NavMesh controls — another surface's
|
|
11
|
+
* subject leaking in, because "nothing selected" was ONE hardcoded branch in
|
|
12
|
+
* `components/Inspector.tsx` instead of an answer the active adapter gave.
|
|
13
|
+
*
|
|
14
|
+
* So the answer moves behind a provider keyed on the ADAPTER. A provider
|
|
15
|
+
* matches the adapters whose surface it speaks for and returns that surface's
|
|
16
|
+
* own empty-state subject; `composeInspectionSubject` turns it into the same
|
|
17
|
+
* {@link InspectionSubject} a real selection produces, and both projections
|
|
18
|
+
* stay dumb. No provider matching means the surface honestly has no
|
|
19
|
+
* empty-state subject — the inspector shows nothing at all, which is the
|
|
20
|
+
* correct answer, not a gap to fill with someone else's content.
|
|
21
|
+
*
|
|
22
|
+
* Why a provider list and not a method on `AuthoringAdapter`: an empty-state
|
|
23
|
+
* subject carries React section bodies, and the engine's adapter seam stays
|
|
24
|
+
* React-free (D6) — the same constraint that put
|
|
25
|
+
* `inspector-section-registry.ts` in the editor. Why not fold it INTO that
|
|
26
|
+
* registry: a registration there contributes one SECTION to a subject, while
|
|
27
|
+
* this names the subject itself (its title and its quiet hint). Registrations
|
|
28
|
+
* are import-time side effects (`authoring/null-inspection-subjects.tsx`,
|
|
29
|
+
* imported by `main.tsx`), so there is no store here — only a list and a
|
|
30
|
+
* first-match lookup.
|
|
31
|
+
*/
|
|
32
|
+
|
|
33
|
+
import type { AuthoringAdapter } from '@volter/editor-project/adapter';
|
|
34
|
+
import type { EditorShellStore } from '../editor-shell-store';
|
|
35
|
+
import type {
|
|
36
|
+
InspectionAction,
|
|
37
|
+
InspectionNote,
|
|
38
|
+
InspectionSection,
|
|
39
|
+
InspectionSurfaceKind,
|
|
40
|
+
} from './model';
|
|
41
|
+
|
|
42
|
+
export interface NullSubjectContext {
|
|
43
|
+
/** The adapter whose surface is showing — the basis for the match. */
|
|
44
|
+
readonly adapter: AuthoringAdapter;
|
|
45
|
+
/** That adapter's surface, resolved once by the shell
|
|
46
|
+
* (`inspection/active-surface.ts`) so every provider matches against the
|
|
47
|
+
* same answer instead of re-deriving one. Absent in a bounded host, where
|
|
48
|
+
* no provider matches and the honest answer is no empty-state subject. */
|
|
49
|
+
readonly surface?: InspectionSurfaceKind | undefined;
|
|
50
|
+
readonly store: EditorShellStore;
|
|
51
|
+
/** Notify the shell that the adapter's (or scene's) truth changed. */
|
|
52
|
+
readonly onEdit: () => void;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
/** One surface's answer to "what am I inspecting when nothing is selected?" */
|
|
56
|
+
export interface NullInspectionSubject {
|
|
57
|
+
/** Stable subject id (`InspectionSubject.id`). */
|
|
58
|
+
readonly id: string;
|
|
59
|
+
/** What this surface calls its empty state ("Scene", the UI root's name). */
|
|
60
|
+
readonly title: string;
|
|
61
|
+
/** The quiet line under the title, for a subject with nothing to edit. */
|
|
62
|
+
readonly hint?: string;
|
|
63
|
+
/** What to CALL this thing's type, under the name — an Asset Lab document
|
|
64
|
+
* says what KIND of document it is. Present ⇒ the composer gives the
|
|
65
|
+
* subject a read-only identity ROW instead of a bare headline (a document
|
|
66
|
+
* is a thing with a name, a type and a provenance; the three scene's empty
|
|
67
|
+
* state is not). */
|
|
68
|
+
readonly kindLabel?: string;
|
|
69
|
+
/** The provenance line under the identity row (an asset's source path). */
|
|
70
|
+
readonly note?: InspectionNote;
|
|
71
|
+
/** The surface's own no-selection sections, in any order — the composer
|
|
72
|
+
* sorts. Empty is a legitimate answer (title + hint, nothing to edit). */
|
|
73
|
+
readonly sections: readonly InspectionSection[];
|
|
74
|
+
/** Verbs this subject offers, the same shape a selected node's carry: the
|
|
75
|
+
* panel renders them and `editor.runAction(id)` runs them. An asset
|
|
76
|
+
* selection's come from the `asset.inspector` contributions that matched
|
|
77
|
+
* it, which is what gives a project's own Inspector section a door in the
|
|
78
|
+
* control API instead of only a mouse. */
|
|
79
|
+
readonly quickActions?: readonly InspectionAction[];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
export interface NullSubjectProvider {
|
|
83
|
+
/** Which surfaces this provider speaks for. A provider that matches a
|
|
84
|
+
* surface it does not own is exactly the leak this seam removes. */
|
|
85
|
+
readonly match: (ctx: NullSubjectContext) => boolean;
|
|
86
|
+
readonly describe: (ctx: NullSubjectContext) => NullInspectionSubject | null;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const providers: NullSubjectProvider[] = [];
|
|
90
|
+
|
|
91
|
+
/** Register a provider. FIRST match wins, so a narrower provider must be
|
|
92
|
+
* registered before a broader one. Returns an unregister function. */
|
|
93
|
+
export function registerNullSubjectProvider(provider: NullSubjectProvider): () => void {
|
|
94
|
+
providers.push(provider);
|
|
95
|
+
return () => {
|
|
96
|
+
const index = providers.indexOf(provider);
|
|
97
|
+
if (index >= 0) providers.splice(index, 1);
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/** The active adapter's no-selection subject, or `null` when this surface
|
|
102
|
+
* has none. */
|
|
103
|
+
export function describeNullInspectionSubject(
|
|
104
|
+
ctx: NullSubjectContext,
|
|
105
|
+
): NullInspectionSubject | null {
|
|
106
|
+
for (const provider of providers) {
|
|
107
|
+
if (provider.match(ctx)) return provider.describe(ctx);
|
|
108
|
+
}
|
|
109
|
+
return null;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
/** Test-only reset (mirrors `__resetInspectorSectionRegistryForTest`). */
|
|
113
|
+
export function __resetNullSubjectProvidersForTest(): void {
|
|
114
|
+
providers.length = 0;
|
|
115
|
+
}
|