@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,112 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* WHICH PRODUCT THIS SESSION IS SERVING — the session's half of the resolution
|
|
3
|
+
* the CLI already did.
|
|
4
|
+
*
|
|
5
|
+
* `vgai edit` resolves the product from the project's own dependencies
|
|
6
|
+
* (`@volter/editor-sdk/session/product-locator`) so a bad or missing declaration
|
|
7
|
+
* is named before a server exists, then hands the directory over in
|
|
8
|
+
* `VGAI_PRODUCT_DIR`, beside `VGAI_WORKBENCH_DIR`. The session reads it back
|
|
9
|
+
* for the two things only it can do: SERVE the product's entry through
|
|
10
|
+
* `/__editor/served-modules`, and REPORT it (`EditorState.product`, printed by
|
|
11
|
+
* `vgai status` on the workbench's line) — a process reports what it is running.
|
|
12
|
+
*
|
|
13
|
+
* A session started without the variable resolves from the project itself
|
|
14
|
+
* rather than guessing, so `npx tsx packages/editor/server/dev.ts` by hand
|
|
15
|
+
* behaves the same as a CLI launch and fails with the same sentence.
|
|
16
|
+
*/
|
|
17
|
+
import { existsSync, readFileSync } from 'node:fs';
|
|
18
|
+
import { createRequire } from 'node:module';
|
|
19
|
+
import { dirname, join } from 'node:path';
|
|
20
|
+
import { pathToFileURL } from 'node:url';
|
|
21
|
+
import {
|
|
22
|
+
productComposedPackages as composedPackages,
|
|
23
|
+
type ProductIdentity,
|
|
24
|
+
readProductManifest,
|
|
25
|
+
resolveProductForProject,
|
|
26
|
+
} from '@volter/editor-sdk/session/product-locator';
|
|
27
|
+
|
|
28
|
+
/** The product directory the CLI resolved and handed over. */
|
|
29
|
+
export const PRODUCT_DIR_ENV = 'VGAI_PRODUCT_DIR';
|
|
30
|
+
|
|
31
|
+
/**
|
|
32
|
+
* The product this session serves, or `null` when there is none to find — a
|
|
33
|
+
* session with no project open yet, or one whose project declares none. The
|
|
34
|
+
* served-modules door turns that `null` into its own refusal, naming the
|
|
35
|
+
* install line, rather than serving nothing silently.
|
|
36
|
+
*/
|
|
37
|
+
export function sessionProduct(projectPath: string | null): ProductIdentity | null {
|
|
38
|
+
const handed = process.env[PRODUCT_DIR_ENV];
|
|
39
|
+
if (handed !== undefined && handed !== '' && existsSync(handed)) {
|
|
40
|
+
const product = readProductManifest(handed);
|
|
41
|
+
if (product !== null) return product;
|
|
42
|
+
}
|
|
43
|
+
if (projectPath === null) return null;
|
|
44
|
+
try {
|
|
45
|
+
return resolveProductForProject(projectPath);
|
|
46
|
+
} catch {
|
|
47
|
+
// The refusal belongs to the door that was asked, not to this read: the CLI
|
|
48
|
+
// already prints it at launch, and `served-modules` prints it to the frame.
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
/** `resolveProductForProject` — the same resolution, refusal and all, for the
|
|
54
|
+
* door that must say why. `productComposedPackages` — what that product
|
|
55
|
+
* mounts, read through the manifest mirror the estate gate keeps equal to the
|
|
56
|
+
* composition in its entry. */
|
|
57
|
+
export {
|
|
58
|
+
productComposedPackages,
|
|
59
|
+
resolveProductForProject,
|
|
60
|
+
} from '@volter/editor-sdk/session/product-locator';
|
|
61
|
+
|
|
62
|
+
/**
|
|
63
|
+
* EVERY CONTRIBUTION MODULE THE PRODUCT COMPOSES, as absolute files — what
|
|
64
|
+
* Vite's dependency crawl has to be HANDED, because it cannot walk to them.
|
|
65
|
+
*
|
|
66
|
+
* The product names a package as `vgai:contributions/<name>`, and that module
|
|
67
|
+
* is synthesized (`vite-plugin-product-contributions.ts`): it hangs off no file
|
|
68
|
+
* on disk, so `optimizeDeps`' esbuild scanner never reaches the `import()` rows
|
|
69
|
+
* inside it. `vite-plugin-module-doorways.ts`'s header records the same failure
|
|
70
|
+
* class from the other synthesized module and the same cure — read the entries
|
|
71
|
+
* out of the SAME declaration the browser is served, rather than letting the
|
|
72
|
+
* optimizer discover them when a lane first mounts.
|
|
73
|
+
*
|
|
74
|
+
* MEASURED 2026-09-21 on a `--template game` scaffold, before this existed: the
|
|
75
|
+
* boot pass prebundled the kit's own graph, the game editor's five packages
|
|
76
|
+
* then dragged in `storybook/internal/preview-api`, `storybook/internal/csf`,
|
|
77
|
+
* `@gltf-transform/{core,extensions,functions}` and `axe-core` as their
|
|
78
|
+
* contributions loaded, and Vite answered with `optimized dependencies changed.
|
|
79
|
+
* reloading` — a hard reload of the one tab, mid-boot, which drops the
|
|
80
|
+
* session's editor and every command with it.
|
|
81
|
+
*/
|
|
82
|
+
export function productContributionFiles(product: ProductIdentity): string[] {
|
|
83
|
+
const resolveFrom = createRequire(pathToFileURL(join(product.dir, 'package.json')));
|
|
84
|
+
const files: string[] = [];
|
|
85
|
+
for (const name of composedPackages(product)) {
|
|
86
|
+
let manifestPath: string;
|
|
87
|
+
try {
|
|
88
|
+
manifestPath = resolveFrom.resolve(`${name}/package.json`);
|
|
89
|
+
} catch {
|
|
90
|
+
continue;
|
|
91
|
+
}
|
|
92
|
+
let declared: unknown;
|
|
93
|
+
try {
|
|
94
|
+
declared = (JSON.parse(readFileSync(manifestPath, 'utf8')) as ContributingManifest).vgai
|
|
95
|
+
?.contributions;
|
|
96
|
+
} catch {
|
|
97
|
+
continue;
|
|
98
|
+
}
|
|
99
|
+
if (!Array.isArray(declared)) continue;
|
|
100
|
+
const dir = dirname(manifestPath);
|
|
101
|
+
for (const entry of declared) {
|
|
102
|
+
if (typeof entry !== 'string') continue;
|
|
103
|
+
const file = join(dir, entry);
|
|
104
|
+
if (existsSync(file)) files.push(file);
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
return files;
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
interface ContributingManifest {
|
|
111
|
+
vgai?: { contributions?: unknown };
|
|
112
|
+
}
|
|
@@ -0,0 +1,230 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Editor session registry — the file-backed ledger of live editor dev servers.
|
|
3
|
+
* This module is the WRITER (dev.ts registers on listen, re-registers on
|
|
4
|
+
* project switch, unregisters on shutdown). The FORMAT — entry shape, guards,
|
|
5
|
+
* path, liveness-filtered read — lives once in `@vgai/sdk`'s
|
|
6
|
+
* `session-registry-format`, imported by every reader (this file, the CLI,
|
|
7
|
+
* and both SDK transports) instead of copied.
|
|
8
|
+
*
|
|
9
|
+
* Entries are best-effort — every reader must PID-liveness-filter (a crashed
|
|
10
|
+
* server can't unregister itself), and writers sweep dead entries on write.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import {
|
|
14
|
+
EDITOR_SESSIONS_REGISTRY_FILE,
|
|
15
|
+
type EditorSessionEntry as EditorSession,
|
|
16
|
+
isEditorSessionEntry,
|
|
17
|
+
normalizeEditorSessionEntry,
|
|
18
|
+
pidAlive,
|
|
19
|
+
} from '@volter/editor-sdk/session/registry-format';
|
|
20
|
+
|
|
21
|
+
export type { EditorSessionEntry as EditorSession } from '@volter/editor-sdk/session/registry-format';
|
|
22
|
+
export { pidAlive } from '@volter/editor-sdk/session/registry-format';
|
|
23
|
+
|
|
24
|
+
import { randomBytes, randomUUID } from 'node:crypto';
|
|
25
|
+
import { chmodSync, mkdirSync, readFileSync, renameSync, writeFileSync } from 'node:fs';
|
|
26
|
+
import { homedir } from 'node:os';
|
|
27
|
+
import { join } from 'node:path';
|
|
28
|
+
import { resolveWorktreeIdentity, type WorktreeIdentity } from './worktree-identity';
|
|
29
|
+
|
|
30
|
+
export type EditorSessionAnnouncement = Pick<
|
|
31
|
+
EditorSession,
|
|
32
|
+
'project' | 'port' | 'pid' | 'startedAt'
|
|
33
|
+
>;
|
|
34
|
+
|
|
35
|
+
const PROCESS_SESSION_ID = randomUUID();
|
|
36
|
+
const PROCESS_CONTROL_SECRET = randomBytes(32).toString('base64url');
|
|
37
|
+
|
|
38
|
+
export function processSessionId(): string {
|
|
39
|
+
return PROCESS_SESSION_ID;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
export function processControlSecret(): string {
|
|
43
|
+
return PROCESS_CONTROL_SECRET;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
export function sessionIdentity(project: string | null): WorktreeIdentity | null {
|
|
47
|
+
return project === null ? null : resolveWorktreeIdentity(project);
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
export function materializeSession(
|
|
51
|
+
announcement: EditorSessionAnnouncement,
|
|
52
|
+
id: string = PROCESS_SESSION_ID,
|
|
53
|
+
): EditorSession {
|
|
54
|
+
const identity = sessionIdentity(announcement.project);
|
|
55
|
+
return {
|
|
56
|
+
...announcement,
|
|
57
|
+
sessionId: id,
|
|
58
|
+
controlSecret: PROCESS_CONTROL_SECRET,
|
|
59
|
+
repositoryId: identity?.repositoryId ?? null,
|
|
60
|
+
worktreeId: identity?.worktreeId ?? null,
|
|
61
|
+
worktreeRoot: identity?.worktreeRoot ?? null,
|
|
62
|
+
projectRelativePath: identity?.projectRelativePath ?? null,
|
|
63
|
+
branch: identity?.branch ?? null,
|
|
64
|
+
headCommit: identity?.headCommit ?? null,
|
|
65
|
+
baseCommit: identity?.baseCommit ?? null,
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
const REGISTRY_DIR = join(homedir(), '.vgai');
|
|
70
|
+
const REGISTRY_FILE = EDITOR_SESSIONS_REGISTRY_FILE;
|
|
71
|
+
|
|
72
|
+
export function sessionRegistryPath(): string {
|
|
73
|
+
return REGISTRY_FILE;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Is this dev server an EPHEMERAL PROBE rather than a session anyone owns?
|
|
78
|
+
*
|
|
79
|
+
* `vgai doctor` spawns a real dev server on the target folder for a few
|
|
80
|
+
* seconds and drives it with its own headless browser. It is not an editing
|
|
81
|
+
* session: nobody should be able to reuse it, `vgai close` should not list
|
|
82
|
+
* it, and — the defect this exists for (SimCity ingest dogfood, S-6) — it
|
|
83
|
+
* must not touch the project's `.vgai/session.json`, which belongs to
|
|
84
|
+
* whichever `vgai edit` session is actually serving that folder. The probe
|
|
85
|
+
* used to OVERWRITE that file at boot with its own throwaway port/pid and
|
|
86
|
+
* then DELETE it on exit, so a live session the user was watching became
|
|
87
|
+
* undiscoverable (`cat .vgai/session.json` → ENOENT) because they ran a
|
|
88
|
+
* read-only diagnostic against it.
|
|
89
|
+
*
|
|
90
|
+
* Same shape as `VGAI_NO_OPEN`: an env flag the spawning tool sets on the
|
|
91
|
+
* child, never a mode the server infers. `'0'` explicitly opts back in, so
|
|
92
|
+
* the variable can be cleared by value in an inherited environment.
|
|
93
|
+
*/
|
|
94
|
+
export function isEphemeralSession(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
95
|
+
const value = env['VGAI_EPHEMERAL_SESSION'];
|
|
96
|
+
return value !== undefined && value !== '' && value !== '0';
|
|
97
|
+
}
|
|
98
|
+
|
|
99
|
+
/**
|
|
100
|
+
* Does this dev server contribute to the PERSON's launcher memory
|
|
101
|
+
* (`~/.vgai/recent-projects.json`, read by the Projects hub and by the
|
|
102
|
+
* opt-in "Reopen last project on launch")?
|
|
103
|
+
*
|
|
104
|
+
* Recents is machine-local state that belongs to a
|
|
105
|
+
* HUMAN at a launcher — it is what the hub shows first and what reopen-last
|
|
106
|
+
* reaches for. Two kinds of dev server have no such human by construction and
|
|
107
|
+
* must therefore stay out of it:
|
|
108
|
+
*
|
|
109
|
+
* - an EPHEMERAL PROBE (`isEphemeralSession`, today `vgai doctor`), which is
|
|
110
|
+
* not an editing session at all; and
|
|
111
|
+
* - a HEADLESS session (`VGAI_NO_OPEN` — the CLI's `--no-open`), which
|
|
112
|
+
* maintains no browser tab whatsoever: CI, headless harnesses, and every
|
|
113
|
+
* background-agent session. Measured: an agent's transient session wrote
|
|
114
|
+
* its scratchpad project into the owner's Recents, and the owner's next
|
|
115
|
+
* launcher boot reached for it.
|
|
116
|
+
*
|
|
117
|
+
* The read is the same truthiness `dev.ts`/`packaged.ts` already use for
|
|
118
|
+
* `tabBijection.enabled`, so "this session maintains a tab" and "this session
|
|
119
|
+
* is someone's launcher memory" can never disagree.
|
|
120
|
+
*/
|
|
121
|
+
export function writesRecentProjects(env: NodeJS.ProcessEnv = process.env): boolean {
|
|
122
|
+
if (isEphemeralSession(env)) return false;
|
|
123
|
+
return !env['VGAI_NO_OPEN'];
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/** All recorded sessions, unvalidated beyond shape (callers liveness-filter). */
|
|
127
|
+
export function readSessions(): EditorSession[] {
|
|
128
|
+
try {
|
|
129
|
+
const raw: unknown = JSON.parse(readFileSync(REGISTRY_FILE, 'utf8'));
|
|
130
|
+
return Array.isArray(raw)
|
|
131
|
+
? raw.filter(isEditorSessionEntry).map(normalizeEditorSessionEntry)
|
|
132
|
+
: [];
|
|
133
|
+
} catch {
|
|
134
|
+
return [];
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
/** Sessions whose server process is still alive. */
|
|
139
|
+
export function liveSessions(): EditorSession[] {
|
|
140
|
+
return readSessions().filter((s) => pidAlive(s.pid));
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
/**
|
|
144
|
+
* Atomic registry replace: write a private temp file, then rename() it over
|
|
145
|
+
* the registry. rename(2) is atomic on POSIX (and effectively so on NTFS), so
|
|
146
|
+
* a concurrent reader always parses either the complete old array or the
|
|
147
|
+
* complete new one — never a torn/truncated file. Torn reads are not
|
|
148
|
+
* hypothetical: `readSessions()` maps ANY parse failure to `[]`, so a
|
|
149
|
+
* reader-that-then-writes (register/unregister — which now runs on every
|
|
150
|
+
* dev-server source-change restart) that catches another writer mid-truncate
|
|
151
|
+
* would persist that empty view and silently wipe every other live session's
|
|
152
|
+
* entry. Reproduced live 2026-07-25: two concurrent restart-churn processes
|
|
153
|
+
* emptied a registry seeded with three entries whose PIDs were still alive —
|
|
154
|
+
* the wiped sessions kept running but became invisible to `vgai
|
|
155
|
+
* edit`/`sessions`/`close`, which is the "new editors starting over and over
|
|
156
|
+
* while strays accumulate" failure mode.
|
|
157
|
+
*/
|
|
158
|
+
function replaceRegistry(sessions: EditorSession[]): void {
|
|
159
|
+
const tmp = `${REGISTRY_FILE}.${process.pid}.tmp`;
|
|
160
|
+
writeFileSync(tmp, `${JSON.stringify(sessions, null, 2)}\n`, { mode: 0o600 });
|
|
161
|
+
renameSync(tmp, REGISTRY_FILE);
|
|
162
|
+
// Owner-only is the intent; a filesystem without modes (a browser runtime)
|
|
163
|
+
// keeps the file and skips the bit.
|
|
164
|
+
try {
|
|
165
|
+
chmodSync(REGISTRY_FILE, 0o600);
|
|
166
|
+
} catch {
|
|
167
|
+
/* no modes here */
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/**
|
|
172
|
+
* A registry record whose pid is not alive is HISTORY, not identity.
|
|
173
|
+
*
|
|
174
|
+
* A dead record must
|
|
175
|
+
* never contribute a project — or anything else — to the port it used to
|
|
176
|
+
* hold, and no live server may inherit one. The registry is a ledger of what
|
|
177
|
+
* IS running, so every write prunes what is not; a reader that forgets to
|
|
178
|
+
* liveness-filter can then only ever see stale entries this process has not
|
|
179
|
+
* swept yet, never entries the registry deliberately kept.
|
|
180
|
+
*
|
|
181
|
+
* `isAlive` is injectable so the rule is testable against fabricated pids
|
|
182
|
+
* without spawning (or killing) real processes.
|
|
183
|
+
*/
|
|
184
|
+
export function pruneDeadSessions(
|
|
185
|
+
sessions: readonly EditorSession[],
|
|
186
|
+
isAlive: (pid: number) => boolean = pidAlive,
|
|
187
|
+
): EditorSession[] {
|
|
188
|
+
return sessions.filter((s) => isAlive(s.pid));
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* The registry as it must look once `incoming` has taken its port: every dead
|
|
193
|
+
* record gone, the previous claim on this pid or this port replaced, and
|
|
194
|
+
* `incoming` appended. Pure, for the same reason as `pruneDeadSessions`.
|
|
195
|
+
*/
|
|
196
|
+
export function registryAfterRegistration(
|
|
197
|
+
sessions: readonly EditorSession[],
|
|
198
|
+
incoming: EditorSession,
|
|
199
|
+
isAlive: (pid: number) => boolean = pidAlive,
|
|
200
|
+
): EditorSession[] {
|
|
201
|
+
const rest = pruneDeadSessions(sessions, isAlive).filter(
|
|
202
|
+
(s) => s.pid !== incoming.pid && s.port !== incoming.port,
|
|
203
|
+
);
|
|
204
|
+
return [...rest, incoming];
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* Record (or refresh) this process's session. Sweeps dead entries and any
|
|
209
|
+
* stale claim on the same port while it's here.
|
|
210
|
+
*/
|
|
211
|
+
export function registerSession(announcement: EditorSessionAnnouncement): void {
|
|
212
|
+
try {
|
|
213
|
+
mkdirSync(REGISTRY_DIR, { recursive: true });
|
|
214
|
+
replaceRegistry(registryAfterRegistration(readSessions(), materializeSession(announcement)));
|
|
215
|
+
} catch {
|
|
216
|
+
// Registry is best-effort — never let bookkeeping kill the server.
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
export function unregisterSession(pid: number): void {
|
|
221
|
+
try {
|
|
222
|
+
// Same rule on the way out: this process's record goes, and so does every
|
|
223
|
+
// record whose server is already gone. Leaving those behind is what lets a
|
|
224
|
+
// dead entry outlive the server it described and keep answering "which
|
|
225
|
+
// project is on port N?" long after nothing is.
|
|
226
|
+
replaceRegistry(pruneDeadSessions(readSessions().filter((s) => s.pid !== pid)));
|
|
227
|
+
} catch {
|
|
228
|
+
// Best-effort (see registerSession).
|
|
229
|
+
}
|
|
230
|
+
}
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
import { createHmac, timingSafeEqual } from 'node:crypto';
|
|
2
|
+
|
|
3
|
+
export interface ShareGatewayClaims {
|
|
4
|
+
participantId: string;
|
|
5
|
+
invitationId: string;
|
|
6
|
+
credentialId: string;
|
|
7
|
+
role: 'viewer' | 'commenter' | 'tester' | 'editor' | 'terminal';
|
|
8
|
+
account: { id: string; email: string; name?: string };
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
const CLAIM_HEADERS = [
|
|
12
|
+
'x-vgai-share-participant-id',
|
|
13
|
+
'x-vgai-share-invitation-id',
|
|
14
|
+
'x-vgai-share-credential-id',
|
|
15
|
+
'x-vgai-share-role',
|
|
16
|
+
'x-vgai-share-account-id',
|
|
17
|
+
'x-vgai-share-account-email',
|
|
18
|
+
'x-vgai-share-account-name',
|
|
19
|
+
'x-vgai-share-signed-at',
|
|
20
|
+
'x-vgai-share-signature',
|
|
21
|
+
] as const;
|
|
22
|
+
|
|
23
|
+
export const shareClaimHeaders: readonly string[] = CLAIM_HEADERS;
|
|
24
|
+
|
|
25
|
+
function payload(
|
|
26
|
+
method: string,
|
|
27
|
+
url: string,
|
|
28
|
+
claims: ShareGatewayClaims,
|
|
29
|
+
signedAt: string,
|
|
30
|
+
): string {
|
|
31
|
+
return [
|
|
32
|
+
method.toUpperCase(),
|
|
33
|
+
url,
|
|
34
|
+
claims.participantId,
|
|
35
|
+
claims.invitationId,
|
|
36
|
+
claims.credentialId,
|
|
37
|
+
claims.role,
|
|
38
|
+
claims.account.id,
|
|
39
|
+
claims.account.email,
|
|
40
|
+
claims.account.name ?? '',
|
|
41
|
+
signedAt,
|
|
42
|
+
].join('\n');
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function signature(secret: string, content: string): string {
|
|
46
|
+
return createHmac('sha256', secret).update(content).digest('base64url');
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
export function signedShareClaimHeaders(
|
|
50
|
+
secret: string,
|
|
51
|
+
method: string,
|
|
52
|
+
url: string,
|
|
53
|
+
claims: ShareGatewayClaims,
|
|
54
|
+
now: number = Date.now(),
|
|
55
|
+
): Record<string, string> {
|
|
56
|
+
const signedAt = String(now);
|
|
57
|
+
return {
|
|
58
|
+
'x-vgai-share-participant-id': claims.participantId,
|
|
59
|
+
'x-vgai-share-invitation-id': claims.invitationId,
|
|
60
|
+
'x-vgai-share-credential-id': claims.credentialId,
|
|
61
|
+
'x-vgai-share-role': claims.role,
|
|
62
|
+
'x-vgai-share-account-id': claims.account.id,
|
|
63
|
+
'x-vgai-share-account-email': claims.account.email,
|
|
64
|
+
...(claims.account.name
|
|
65
|
+
? { 'x-vgai-share-account-name': encodeURIComponent(claims.account.name) }
|
|
66
|
+
: {}),
|
|
67
|
+
'x-vgai-share-signed-at': signedAt,
|
|
68
|
+
'x-vgai-share-signature': signature(secret, payload(method, url, claims, signedAt)),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
export function verifyShareClaimHeaders(
|
|
73
|
+
secret: string,
|
|
74
|
+
method: string,
|
|
75
|
+
url: string,
|
|
76
|
+
read: (name: string) => string | undefined,
|
|
77
|
+
now: number = Date.now(),
|
|
78
|
+
): ShareGatewayClaims | null {
|
|
79
|
+
const values = Object.fromEntries(CLAIM_HEADERS.map((name) => [name, read(name)?.trim()]));
|
|
80
|
+
const any = CLAIM_HEADERS.some((name) => values[name]);
|
|
81
|
+
if (!any) return null;
|
|
82
|
+
const participantId = values['x-vgai-share-participant-id'];
|
|
83
|
+
const invitationId = values['x-vgai-share-invitation-id'];
|
|
84
|
+
const credentialId = values['x-vgai-share-credential-id'];
|
|
85
|
+
const role = values['x-vgai-share-role'];
|
|
86
|
+
const accountId = values['x-vgai-share-account-id'];
|
|
87
|
+
const accountEmail = values['x-vgai-share-account-email'];
|
|
88
|
+
const encodedName = values['x-vgai-share-account-name'];
|
|
89
|
+
const signedAt = values['x-vgai-share-signed-at'];
|
|
90
|
+
const supplied = values['x-vgai-share-signature'];
|
|
91
|
+
if (
|
|
92
|
+
!participantId ||
|
|
93
|
+
participantId.length > 200 ||
|
|
94
|
+
!invitationId ||
|
|
95
|
+
invitationId.length > 200 ||
|
|
96
|
+
!credentialId ||
|
|
97
|
+
credentialId.length > 200 ||
|
|
98
|
+
!role ||
|
|
99
|
+
!['viewer', 'commenter', 'tester', 'editor', 'terminal'].includes(role) ||
|
|
100
|
+
!accountId ||
|
|
101
|
+
accountId.length > 200 ||
|
|
102
|
+
!accountEmail ||
|
|
103
|
+
accountEmail.length > 320 ||
|
|
104
|
+
!signedAt ||
|
|
105
|
+
!supplied
|
|
106
|
+
)
|
|
107
|
+
throw new Error('Invalid share gateway claims.');
|
|
108
|
+
const signedAtMs = Number(signedAt);
|
|
109
|
+
if (!Number.isSafeInteger(signedAtMs) || Math.abs(now - signedAtMs) > 30_000) {
|
|
110
|
+
throw new Error('Expired share gateway claims.');
|
|
111
|
+
}
|
|
112
|
+
let name: string | undefined;
|
|
113
|
+
if (encodedName) {
|
|
114
|
+
try {
|
|
115
|
+
name = decodeURIComponent(encodedName);
|
|
116
|
+
} catch {
|
|
117
|
+
throw new Error('Invalid share gateway claims.');
|
|
118
|
+
}
|
|
119
|
+
if (name.length > 200) throw new Error('Invalid share gateway claims.');
|
|
120
|
+
}
|
|
121
|
+
const claims: ShareGatewayClaims = {
|
|
122
|
+
participantId,
|
|
123
|
+
invitationId,
|
|
124
|
+
credentialId,
|
|
125
|
+
role: role as ShareGatewayClaims['role'],
|
|
126
|
+
account: { id: accountId, email: accountEmail, ...(name ? { name } : {}) },
|
|
127
|
+
};
|
|
128
|
+
const expected = signature(secret, payload(method, url, claims, signedAt));
|
|
129
|
+
const actualBuffer = Buffer.from(supplied);
|
|
130
|
+
const expectedBuffer = Buffer.from(expected);
|
|
131
|
+
if (
|
|
132
|
+
actualBuffer.length !== expectedBuffer.length ||
|
|
133
|
+
!timingSafeEqual(actualBuffer, expectedBuffer)
|
|
134
|
+
) {
|
|
135
|
+
throw new Error('Invalid share gateway signature.');
|
|
136
|
+
}
|
|
137
|
+
return claims;
|
|
138
|
+
}
|