@alpsckr/unitycli 0.4.2 → 0.4.4
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/README.md +5 -5
- package/contracts/command-contract.json +109 -217
- package/contracts/package-files.json +374 -294
- package/contracts/stable-session/direct-call-semantics.json +8 -2
- package/contracts/tool-completion-contract.json +148 -672
- package/dist/bridge/admission.d.ts +17 -1
- package/dist/bridge/admission.js +2 -0
- package/dist/bridge/admission.js.map +1 -1
- package/dist/bridge/domains/asset.js +3 -1
- package/dist/bridge/domains/asset.js.map +1 -1
- package/dist/bridge/domains/camera.js +39 -7
- package/dist/bridge/domains/camera.js.map +1 -1
- package/dist/bridge/domains/console.js +2 -1
- package/dist/bridge/domains/console.js.map +1 -1
- package/dist/bridge/domains/doctor.d.ts +3 -0
- package/dist/bridge/domains/doctor.js +8 -0
- package/dist/bridge/domains/doctor.js.map +1 -0
- package/dist/bridge/domains/editor.js +0 -4
- package/dist/bridge/domains/editor.js.map +1 -1
- package/dist/bridge/domains/game-object.js +4 -12
- package/dist/bridge/domains/game-object.js.map +1 -1
- package/dist/bridge/domains/graphics.js +1 -16
- package/dist/bridge/domains/graphics.js.map +1 -1
- package/dist/bridge/domains/object.js +3 -0
- package/dist/bridge/domains/object.js.map +1 -1
- package/dist/bridge/domains/physics.js +1 -2
- package/dist/bridge/domains/physics.js.map +1 -1
- package/dist/bridge/domains/profiler.js +18 -7
- package/dist/bridge/domains/profiler.js.map +1 -1
- package/dist/bridge/domains/project-tool.js +4 -0
- package/dist/bridge/domains/project-tool.js.map +1 -1
- package/dist/bridge/domains/reflection.js +10 -2
- package/dist/bridge/domains/reflection.js.map +1 -1
- package/dist/bridge/domains/runtime-tool.js +3 -0
- package/dist/bridge/domains/runtime-tool.js.map +1 -1
- package/dist/bridge/domains/scene.js +3 -8
- package/dist/bridge/domains/scene.js.map +1 -1
- package/dist/bridge/domains/screenshot.js +30 -6
- package/dist/bridge/domains/screenshot.js.map +1 -1
- package/dist/bridge/domains/ui.js +3 -1
- package/dist/bridge/domains/ui.js.map +1 -1
- package/dist/bridge/index.d.ts +5 -5
- package/dist/bridge/index.js +6 -9
- package/dist/bridge/index.js.map +1 -1
- package/dist/bridge/registry.js +3 -5
- package/dist/bridge/registry.js.map +1 -1
- package/dist/bridge/session-supervisor.d.ts +6 -3
- package/dist/bridge/session-supervisor.js +122 -34
- package/dist/bridge/session-supervisor.js.map +1 -1
- package/dist/bridge/types.d.ts +6 -5
- package/dist/bridge/types.js +16 -2
- package/dist/bridge/types.js.map +1 -1
- package/dist/catalog-protocol.d.ts +64 -0
- package/dist/catalog-protocol.js +460 -0
- package/dist/catalog-protocol.js.map +1 -0
- package/dist/cli-commands/command.js +84 -61
- package/dist/cli-commands/command.js.map +1 -1
- package/dist/cli-commands/extensions.js +70 -50
- package/dist/cli-commands/extensions.js.map +1 -1
- package/dist/cli-commands/instances.js +1 -1
- package/dist/cli-commands/instances.js.map +1 -1
- package/dist/cli-process-owners.d.ts +6 -0
- package/dist/cli-process-owners.js +27 -0
- package/dist/cli-process-owners.js.map +1 -0
- package/dist/cli.d.ts +1 -1
- package/dist/cli.js +20 -5
- package/dist/cli.js.map +1 -1
- package/dist/contracts/command-contract.js +14 -4
- package/dist/contracts/command-contract.js.map +1 -1
- package/dist/doctor.d.ts +4 -6
- package/dist/doctor.js +429 -398
- package/dist/doctor.js.map +1 -1
- package/dist/editor-blocker-observer.d.ts +2 -1
- package/dist/editor-blocker-observer.js +40 -13
- package/dist/editor-blocker-observer.js.map +1 -1
- package/dist/extension-availability.d.ts +27 -9
- package/dist/extension-availability.js +96 -56
- package/dist/extension-availability.js.map +1 -1
- package/dist/extensions/descriptor-loader.d.ts +2 -2
- package/dist/extensions/descriptor-loader.js +3 -4
- package/dist/extensions/descriptor-loader.js.map +1 -1
- package/dist/extensions/index.d.ts +1 -1
- package/dist/extensions/index.js +1 -1
- package/dist/extensions/index.js.map +1 -1
- package/dist/extensions/installer.d.ts +24 -7
- package/dist/extensions/installer.js +142 -66
- package/dist/extensions/installer.js.map +1 -1
- package/dist/extensions/registry.js +3 -5
- package/dist/extensions/registry.js.map +1 -1
- package/dist/extensions/state-contract.d.ts +11 -0
- package/dist/extensions/state-contract.js +50 -0
- package/dist/extensions/state-contract.js.map +1 -0
- package/dist/instances.d.ts +13 -1
- package/dist/instances.js +26 -0
- package/dist/instances.js.map +1 -1
- package/dist/package-manager.d.ts +0 -24
- package/dist/package-manager.js +5 -58
- package/dist/package-manager.js.map +1 -1
- package/dist/project-tool-discovery.d.ts +5 -2
- package/dist/project-tool-discovery.js +22 -18
- package/dist/project-tool-discovery.js.map +1 -1
- package/dist/runtime-code.js +1 -1
- package/dist/runtime-code.js.map +1 -1
- package/dist/tool-name.d.ts +4 -0
- package/dist/tool-name.js +15 -0
- package/dist/tool-name.js.map +1 -0
- package/dist/tools/.generated-completion-registry.d.ts +2 -0
- package/dist/tools/.generated-completion-registry.js +763 -325
- package/dist/tools/.generated-completion-registry.js.map +1 -1
- package/dist/tools/.generated-registry.d.ts +6 -11
- package/dist/tools/.generated-registry.js +6 -11
- package/dist/tools/.generated-registry.js.map +1 -1
- package/dist/tools/.generated-schemas.js +11 -16
- package/dist/tools/.generated-schemas.js.map +1 -1
- package/dist/tools/asset/refresh-status.d.ts +3 -0
- package/dist/tools/asset/refresh-status.js +12 -0
- package/dist/tools/asset/refresh-status.js.map +1 -0
- package/dist/tools/asset/refresh.js +7 -3
- package/dist/tools/asset/refresh.js.map +1 -1
- package/dist/tools/build/player-status.d.ts +3 -0
- package/dist/tools/build/player-status.js +12 -0
- package/dist/tools/build/player-status.js.map +1 -0
- package/dist/tools/build/run.js +1 -1
- package/dist/tools/build/run.js.map +1 -1
- package/dist/tools/catalog-control.d.ts +22 -0
- package/dist/tools/catalog-control.js +335 -0
- package/dist/tools/catalog-control.js.map +1 -0
- package/dist/tools/catalog.d.ts +7 -9
- package/dist/tools/catalog.js +66 -45
- package/dist/tools/catalog.js.map +1 -1
- package/dist/tools/commands.d.ts +1 -1
- package/dist/tools/commands.js +44 -11
- package/dist/tools/commands.js.map +1 -1
- package/dist/tools/define.js +3 -2
- package/dist/tools/define.js.map +1 -1
- package/dist/tools/dispatcher.d.ts +53 -6
- package/dist/tools/dispatcher.js +277 -108
- package/dist/tools/dispatcher.js.map +1 -1
- package/dist/tools/editor/compile.js +1 -1
- package/dist/tools/editor/compile.js.map +1 -1
- package/dist/tools/editor/play-mode-status.d.ts +3 -0
- package/dist/tools/editor/play-mode-status.js +12 -0
- package/dist/tools/editor/play-mode-status.js.map +1 -0
- package/dist/tools/editor/readiness.d.ts +0 -1
- package/dist/tools/editor/readiness.js +0 -1
- package/dist/tools/editor/readiness.js.map +1 -1
- package/dist/tools/editor/refresh.d.ts +7 -3
- package/dist/tools/editor/refresh.js +20 -15
- package/dist/tools/editor/refresh.js.map +1 -1
- package/dist/tools/editor/state.d.ts +2 -2
- package/dist/tools/editor/state.js +13 -12
- package/dist/tools/editor/state.js.map +1 -1
- package/dist/tools/metadata/derived.js +1 -7
- package/dist/tools/metadata/derived.js.map +1 -1
- package/dist/tools/metadata/status.js +1 -12
- package/dist/tools/metadata/status.js.map +1 -1
- package/dist/tools/metadata/types.d.ts +0 -2
- package/dist/tools/navmesh/live.js +1 -1
- package/dist/tools/navmesh/live.js.map +1 -1
- package/dist/tools/occlusion/live.js +1 -1
- package/dist/tools/occlusion/live.js.map +1 -1
- package/dist/tools/package/deploy.js +2 -2
- package/dist/tools/package/deploy.js.map +1 -1
- package/dist/tools/package/embed.js +1 -1
- package/dist/tools/package/embed.js.map +1 -1
- package/dist/tools/package/install-status.d.ts +3 -0
- package/dist/tools/package/install-status.js +12 -0
- package/dist/tools/package/install-status.js.map +1 -0
- package/dist/tools/package/install.js +3 -3
- package/dist/tools/package/install.js.map +1 -1
- package/dist/tools/package/live-resolve.js +45 -12
- package/dist/tools/package/live-resolve.js.map +1 -1
- package/dist/tools/package/registry-clear.js.map +1 -1
- package/dist/tools/package/registry-set.js.map +1 -1
- package/dist/tools/package/remove-status.d.ts +3 -0
- package/dist/tools/package/remove-status.js +12 -0
- package/dist/tools/package/remove-status.js.map +1 -0
- package/dist/tools/package/remove.js +3 -3
- package/dist/tools/package/remove.js.map +1 -1
- package/dist/tools/package/resolve.js +3 -3
- package/dist/tools/package/resolve.js.map +1 -1
- package/dist/tools/package/restore.js +2 -2
- package/dist/tools/package/restore.js.map +1 -1
- package/dist/tools/package/scoped-registry-add.js.map +1 -1
- package/dist/tools/status/support.d.ts +13 -0
- package/dist/tools/status/support.js +28 -0
- package/dist/tools/status/support.js.map +1 -0
- package/dist/tools/test/cancel.js +2 -2
- package/dist/tools/test/cancel.js.map +1 -1
- package/dist/tools/test/run-status.d.ts +3 -0
- package/dist/tools/test/run-status.js +12 -0
- package/dist/tools/test/run-status.js.map +1 -0
- package/dist/tools/test/run.js +7 -4
- package/dist/tools/test/run.js.map +1 -1
- package/dist/tools/tools/group-summaries.js +10 -14
- package/dist/tools/tools/group-summaries.js.map +1 -1
- package/docs/architecture.md +4 -4
- package/docs/availability-differences.md +4 -4
- package/docs/command-execution.md +4 -3
- package/docs/error-codes.md +13 -5
- package/docs/extensions.md +1 -7
- package/docs/risk-and-side-effects.md +4 -3
- package/docs/safety-boundaries.md +3 -1
- package/docs/target-and-instance.md +1 -1
- package/docs/tool-discovery.md +17 -10
- package/docs/tool-execution.md +18 -7
- package/extensions/cinemachine/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
- package/extensions/hdrp/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
- package/extensions/probuilder/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
- package/extensions/urp/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
- package/extensions/vfx-graph/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
- package/package.json +2 -4
- package/skills/unitycli/SKILL.md +35 -42
- package/skills/unitycli/manifest.json +1 -1
- package/skills/unitycli/references/operation-protocol.md +3 -3
- package/unitypkg/Editor/AssemblyInfo.cs +5 -0
- package/unitypkg/Editor/Bridge/BridgeCommandRegistry.cs +49 -14
- package/unitypkg/Editor/Bridge/BridgeHttpServer.cs +9 -35
- package/unitypkg/Editor/Bridge/BridgeQueueState.cs +672 -0
- package/unitypkg/Editor/Bridge/BridgeWorkQueue.cs +970 -120
- package/unitypkg/Editor/BridgeStartupStateMachine.cs +59 -1
- package/unitypkg/Editor/Commands/ProjectToolCommands.cs +4 -0
- package/unitypkg/Editor/Commands/RuntimeToolCommands.cs +3 -0
- package/unitypkg/Editor/Generated/UnityCliToolCompletionRegistry.g.cs +379 -14
- package/unitypkg/Editor/Infrastructure/CodeExecSupport.cs +28 -13
- package/unitypkg/Editor/Infrastructure/RegistryOwnershipResolver.cs +132 -105
- package/unitypkg/Editor/Infrastructure/UnityCliActiveOperation.cs +138 -29
- package/unitypkg/Editor/Infrastructure/UnityCliAdmission.cs +1856 -237
- package/unitypkg/Editor/Infrastructure/UnityCliDoctorDiagnostics.cs +220 -0
- package/unitypkg/Editor/Infrastructure/UnityCliDurableStatusCoordinator.cs +118 -0
- package/unitypkg/Editor/Infrastructure/UnityCliEditorStateSnapshot.cs +2 -1
- package/unitypkg/Editor/Infrastructure/UnityCliHierarchyPager.cs +203 -0
- package/unitypkg/Editor/Infrastructure/UnityCliInstanceCleanup.cs +2 -1
- package/unitypkg/Editor/Infrastructure/UnityCliInstanceRegistry.cs +201 -63
- package/unitypkg/Editor/Infrastructure/UnityCliJson.cs +2 -3
- package/unitypkg/Editor/Infrastructure/UnityCliLiveBuildCoordinator.cs +289 -46
- package/unitypkg/Editor/Infrastructure/UnityCliLiveRefreshCoordinator.cs +87 -53
- package/unitypkg/Editor/Infrastructure/UnityCliNavMeshBakeCoordinator.cs +4 -4
- package/unitypkg/Editor/Infrastructure/UnityCliObjectRef.cs +128 -25
- package/unitypkg/Editor/Infrastructure/UnityCliObjectSerializer.cs +435 -327
- package/unitypkg/Editor/Infrastructure/UnityCliOcclusionBakeCoordinator.cs +4 -4
- package/unitypkg/Editor/Infrastructure/UnityCliOperationCoordinator.cs +351 -53
- package/unitypkg/Editor/Infrastructure/UnityCliPackageResolveCoordinator.cs +118 -18
- package/unitypkg/Editor/Infrastructure/UnityCliPackageResolveState.cs +20 -1
- package/unitypkg/Editor/Infrastructure/UnityCliReadGeneration.cs +97 -0
- package/unitypkg/Editor/Infrastructure/UnityCliReflection.cs +644 -133
- package/unitypkg/Editor/Infrastructure/UnityCliReloadOperation.cs +128 -41
- package/unitypkg/Editor/Infrastructure/UnityCliRuntimeExecutor.cs +14 -84
- package/unitypkg/Editor/Infrastructure/UnityCliSerializer.cs +220 -0
- package/unitypkg/Editor/Infrastructure/UnityCliSessionMutationLease.cs +69 -29
- package/unitypkg/Editor/Infrastructure/UnityCliTestRunCoordinator.cs +440 -54
- package/unitypkg/Editor/Infrastructure/UnityCliWaiter.cs +128 -35
- package/unitypkg/Editor/ProjectTools/IUnityCliTool.cs +9 -1
- package/unitypkg/Editor/ProjectTools/OfficialAttributeToolRegistry.cs +32 -31
- package/unitypkg/Editor/ProjectTools/ProjectToolRegistry.cs +607 -458
- package/unitypkg/Editor/ProjectTools/ProjectToolSchemaValidator.cs +35 -7
- package/unitypkg/Editor/ProjectTools/RegisteredTool.cs +501 -60
- package/unitypkg/Editor/ProjectTools/UnityCliProjectToolContext.cs +21 -0
- package/unitypkg/Editor/ProjectTools/UnityCliSchemaDeriver.cs +36 -7
- package/unitypkg/Editor/ProjectTools/UnityCliToolName.cs +30 -0
- package/unitypkg/Editor/Properties/AssemblyInfo.cs +3 -0
- package/unitypkg/Editor/Tools/asset/get-data.cs +16 -7
- package/unitypkg/Editor/Tools/build/BuildSceneStateTool.cs +23 -3
- package/unitypkg/Editor/Tools/build/BuildToolDtos.cs +2 -1
- package/unitypkg/Editor/Tools/build/scene/add.cs +6 -3
- package/unitypkg/Editor/Tools/build/scene/disable.cs +1 -1
- package/unitypkg/Editor/Tools/build/scene/enable.cs +1 -1
- package/unitypkg/Editor/Tools/build/scene/list.cs +1 -1
- package/unitypkg/Editor/Tools/build/scene/remove.cs +13 -3
- package/unitypkg/Editor/Tools/camera/CameraToolSupport.cs +38 -38
- package/unitypkg/Editor/Tools/camera/multiview.cs +13 -6
- package/unitypkg/Editor/Tools/camera/screenshot.cs +14 -7
- package/unitypkg/Editor/Tools/component/get.cs +16 -9
- package/unitypkg/Editor/Tools/component/modify.cs +6 -4
- package/unitypkg/Editor/Tools/console/clear.cs +7 -6
- package/unitypkg/Editor/Tools/console/get.cs +48 -16
- package/unitypkg/Editor/Tools/editor/EditorToolSupport.cs +143 -28
- package/unitypkg/Editor/Tools/editor/menu-items.cs +1 -1
- package/unitypkg/Editor/Tools/editor/play.cs +2 -11
- package/unitypkg/Editor/Tools/editor/selection.cs +1 -1
- package/unitypkg/Editor/Tools/editor/stop.cs +2 -11
- package/unitypkg/Editor/Tools/editor/windows.cs +1 -1
- package/unitypkg/Editor/Tools/go/GameObjectToolSupport.cs +54 -4
- package/unitypkg/Editor/Tools/go/delete.cs +1 -1
- package/unitypkg/Editor/Tools/go/find.cs +167 -70
- package/unitypkg/Editor/Tools/graphics/GraphicsToolSupport.cs +25 -0
- package/unitypkg/Editor/Tools/graphics/light-probe-group.cs +9 -3
- package/unitypkg/Editor/Tools/graphics/pipeline-info.cs +1 -1
- package/unitypkg/Editor/Tools/graphics/pipeline-settings.cs +1 -1
- package/unitypkg/Editor/Tools/graphics/quality.cs +2 -2
- package/unitypkg/Editor/Tools/graphics/reflection-probe.cs +3 -3
- package/unitypkg/Editor/Tools/graphics/stats.cs +1 -1
- package/unitypkg/Editor/Tools/object/ObjectToolSupport.cs +4 -4
- package/unitypkg/Editor/Tools/object/get-data.cs +9 -7
- package/unitypkg/Editor/Tools/object/modify.cs +7 -5
- package/unitypkg/Editor/Tools/physics/raycast.cs +24 -6
- package/unitypkg/Editor/Tools/prefab/stage.cs +1 -1
- package/unitypkg/Editor/Tools/profiler/ProfilerFrameDebuggerSupport.cs +94 -21
- package/unitypkg/Editor/Tools/profiler/ProfilerMemorySnapshotSupport.cs +397 -10
- package/unitypkg/Editor/Tools/profiler/ProfilerToolSupport.cs +18 -4
- package/unitypkg/Editor/Tools/profiler/frame-debugger/enable.cs +1 -1
- package/unitypkg/Editor/Tools/profiler/frame-debugger/events.cs +88 -87
- package/unitypkg/Editor/Tools/profiler/hierarchy.cs +278 -112
- package/unitypkg/Editor/Tools/profiler/memory-snapshot/compare.cs +9 -5
- package/unitypkg/Editor/Tools/profiler/memory-snapshot/list.cs +37 -35
- package/unitypkg/Editor/Tools/profiler/memory-snapshot/take.cs +99 -97
- package/unitypkg/Editor/Tools/project/info.cs +1 -1
- package/unitypkg/Editor/Tools/project/layers.cs +1 -1
- package/unitypkg/Editor/Tools/project/tags.cs +1 -1
- package/unitypkg/Editor/Tools/reflection/method/call.cs +9 -7
- package/unitypkg/Editor/Tools/reflection/method/find.cs +27 -37
- package/unitypkg/Editor/Tools/reflection/type/schema.cs +24 -28
- package/unitypkg/Editor/Tools/scene/gameobject/component.cs +8 -5
- package/unitypkg/Editor/Tools/scene/gameobject/components.cs +10 -7
- package/unitypkg/Editor/Tools/scene/gameobject-support.cs +104 -8
- package/unitypkg/Editor/Tools/scene/gameobject.cs +37 -16
- package/unitypkg/Editor/Tools/scene/hierarchy.cs +146 -142
- package/unitypkg/Editor/Tools/screenshot/EditorElementCaptureToolSupport.cs +77 -25
- package/unitypkg/Editor/Tools/screenshot/ScreenshotToolSupport.cs +315 -95
- package/unitypkg/Editor/Tools/screenshot/editor-element.cs +7 -5
- package/unitypkg/Editor/Tools/screenshot/game-view.cs +35 -21
- package/unitypkg/Editor/Tools/screenshot/isolated-object.cs +29 -23
- package/unitypkg/Editor/Tools/screenshot/orbit.cs +37 -25
- package/unitypkg/Editor/Tools/screenshot/scene-view.cs +25 -18
- package/unitypkg/Editor/Tools/screenshot/screen.cs +177 -17
- package/unitypkg/Editor/Tools/screenshot/surround.cs +83 -79
- package/unitypkg/Editor/Tools/ui/render-preview.cs +16 -11
- package/unitypkg/Editor/UnityCliBridge.cs +97 -34
- package/unitypkg/Runtime/Infrastructure/UnityCliRuntimeBridge.cs +753 -122
- package/unitypkg/Runtime/Properties/AssemblyInfo.cs +5 -0
- package/unitypkg/Runtime/UnityCli.Runtime.asmdef +1 -1
- package/unitypkg/Shared/AssemblyInfo.cs +4 -0
- package/unitypkg/Shared/UnityCliAdmissionPool.cs +265 -75
- package/unitypkg/Shared/UnityCliBridgeQueuePolicy.cs +410 -0
- package/unitypkg/Shared/UnityCliBridgeWorkItemState.cs +47 -0
- package/unitypkg/Shared/UnityCliExceptionProjection.cs +151 -0
- package/unitypkg/Shared/UnityCliQueuePublication.cs +30 -0
- package/unitypkg/Shared/UnityCliRequestBudget.cs +352 -0
- package/unitypkg/Shared/UnityCliRuntimeRequestPublication.cs +107 -0
- package/unitypkg/Tests/Editor/UnityCli.Editor.Tests.asmdef +2 -2
- package/unitypkg/Tests/Editor/UnityCliAdmissionCoordinatorIntegrationTests.cs +1329 -0
- package/unitypkg/Tests/Editor/UnityCliAdmissionPoolTests.cs +311 -114
- package/unitypkg/Tests/Editor/UnityCliAdmissionRepairStateTests.cs +94 -0
- package/unitypkg/Tests/Editor/UnityCliBridgeAdmissionIntegrationTests.cs +1229 -0
- package/unitypkg/Tests/Editor/UnityCliBridgeQueuePolicyTests.cs +412 -0
- package/unitypkg/Tests/Editor/UnityCliContinuationIntegrationTests.cs +292 -0
- package/unitypkg/Tests/Editor/UnityCliDiagnosticBoundaryTests.cs +120 -0
- package/unitypkg/Tests/Editor/UnityCliDurableStatusTests.cs +84 -0
- package/unitypkg/Tests/Editor/UnityCliExceptionProjectionTests.cs +72 -0
- package/unitypkg/Tests/Editor/UnityCliInstancePublicationRetryTests.cs +180 -97
- package/unitypkg/Tests/Editor/UnityCliMemoryReflectionIntegrationTests.cs +434 -0
- package/unitypkg/Tests/Editor/UnityCliRequestBudgetTests.cs +615 -0
- package/unitypkg/Tests/Editor/UnityCliRuntimeBridgeIntegrationTests.cs +520 -0
- package/unitypkg/Tests/Editor/UnityCliToolCatalogTests.cs +562 -0
- package/unitypkg/Tests/Runtime/UnityCli.Runtime.Tests.asmdef +23 -0
- package/unitypkg/Tests/Runtime/UnityCliRuntimeCatalogValidationTests.cs +29 -0
- package/unitypkg/package.json +1 -1
- package/contracts/static-capability-catalog.json +0 -48226
- package/dist/bridge/domains/diagnose.d.ts +0 -2
- package/dist/bridge/domains/diagnose.js +0 -11
- package/dist/bridge/domains/diagnose.js.map +0 -1
- package/dist/bridge/domains/extension.d.ts +0 -8
- package/dist/bridge/domains/extension.js +0 -20
- package/dist/bridge/domains/extension.js.map +0 -1
- package/dist/capabilities.d.ts +0 -5
- package/dist/capabilities.js +0 -84
- package/dist/capabilities.js.map +0 -1
- package/dist/static-capability-catalog.d.ts +0 -13
- package/dist/static-capability-catalog.js +0 -41
- package/dist/static-capability-catalog.js.map +0 -1
- package/dist/tools/diagnose/capabilities.d.ts +0 -13
- package/dist/tools/diagnose/capabilities.js +0 -34
- package/dist/tools/diagnose/capabilities.js.map +0 -1
- package/dist/tools/package/info.d.ts +0 -19
- package/dist/tools/package/info.js +0 -27
- package/dist/tools/package/info.js.map +0 -1
- package/dist/tools/package/list.d.ts +0 -27
- package/dist/tools/package/list.js +0 -21
- package/dist/tools/package/list.js.map +0 -1
- package/dist/tools/package/registry-get.d.ts +0 -10
- package/dist/tools/package/registry-get.js +0 -22
- package/dist/tools/package/registry-get.js.map +0 -1
- package/dist/tools/package/scoped-registry-list.d.ts +0 -14
- package/dist/tools/package/scoped-registry-list.js +0 -22
- package/dist/tools/package/scoped-registry-list.js.map +0 -1
- package/dist/tools/package/search.d.ts +0 -17
- package/dist/tools/package/search.js +0 -39
- package/dist/tools/package/search.js.map +0 -1
- package/dist/tools/package/status.d.ts +0 -21
- package/dist/tools/package/status.js +0 -37
- package/dist/tools/package/status.js.map +0 -1
- package/dist/tools/tools/describe.d.ts +0 -27
- package/dist/tools/tools/describe.js +0 -35
- package/dist/tools/tools/describe.js.map +0 -1
- package/dist/tools/tools/group-list.d.ts +0 -16
- package/dist/tools/tools/group-list.js +0 -38
- package/dist/tools/tools/group-list.js.map +0 -1
- package/dist/tools/tools/group.d.ts +0 -13
- package/dist/tools/tools/group.js +0 -34
- package/dist/tools/tools/group.js.map +0 -1
- package/dist/tools/tools/pagination.d.ts +0 -17
- package/dist/tools/tools/pagination.js +0 -28
- package/dist/tools/tools/pagination.js.map +0 -1
- package/dist/tools/tools/search.d.ts +0 -15
- package/dist/tools/tools/search.js +0 -42
- package/dist/tools/tools/search.js.map +0 -1
- package/unitypkg/Editor/Tools/diagnose/preflight.cs +0 -269
- package/unitypkg/Editor/Tools/editor/console.cs +0 -26
- package/unitypkg/Editor/Tools/extension/status.cs +0 -87
- package/unitypkg/Editor/Tools/go/inspect.cs +0 -49
- package/unitypkg/Editor/Tools/graphics/pipeline-quality.cs +0 -24
- package/unitypkg/Editor/Tools/graphics/probe-positions.cs +0 -58
- package/unitypkg/Editor/Tools/graphics/settings.cs +0 -104
- package/unitypkg/Editor/Tools/graphics/stats-counters.cs +0 -28
- package/unitypkg/Editor/Tools/graphics/stats-memory.cs +0 -21
- package/unitypkg/Editor/Tools/instances/list.cs +0 -71
- package/unitypkg/Editor/Tools/physics/raycast-all.cs +0 -67
- package/unitypkg/Editor/Tools/scene/build-settings.cs +0 -69
- package/unitypkg/Editor/Tools/scene/data.cs +0 -125
- package/unitypkg/Editor/Tools/tests/list.cs +0 -98
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
#if UNITY_EDITOR
|
|
2
2
|
using System;
|
|
3
3
|
using System.Collections.Generic;
|
|
4
|
+
using System.Diagnostics;
|
|
4
5
|
using System.Globalization;
|
|
5
6
|
using System.IO;
|
|
6
7
|
using System.Threading;
|
|
@@ -9,6 +10,35 @@ using UnityCli.Protocol;
|
|
|
9
10
|
|
|
10
11
|
namespace UnityCli
|
|
11
12
|
{
|
|
13
|
+
/// <summary>每个reload operation独占的单调tick节流;绝对业务deadline仍由UTC判定。</summary>
|
|
14
|
+
internal sealed class UnityCliReloadTickSchedule
|
|
15
|
+
{
|
|
16
|
+
private readonly Func<long> monotonicNowMs;
|
|
17
|
+
private readonly Func<DateTimeOffset> utcNow;
|
|
18
|
+
private long nextTickAtMs;
|
|
19
|
+
|
|
20
|
+
internal UnityCliReloadTickSchedule(Func<long> monotonicNowMs = null, Func<DateTimeOffset> utcNow = null)
|
|
21
|
+
{
|
|
22
|
+
this.monotonicNowMs = monotonicNowMs ?? DefaultMonotonicMilliseconds;
|
|
23
|
+
this.utcNow = utcNow ?? (() => DateTimeOffset.UtcNow);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
internal DateTimeOffset UtcNow { get { return utcNow(); } }
|
|
27
|
+
|
|
28
|
+
internal bool TryEnter()
|
|
29
|
+
{
|
|
30
|
+
var now = monotonicNowMs();
|
|
31
|
+
if (now < nextTickAtMs) return false;
|
|
32
|
+
nextTickAtMs = checked(now + 100L);
|
|
33
|
+
return true;
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
private static long DefaultMonotonicMilliseconds()
|
|
37
|
+
{
|
|
38
|
+
return checked((long)(Stopwatch.GetTimestamp() * (1000d / Stopwatch.Frequency)));
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
|
|
12
42
|
public static partial class UnityCliBridge
|
|
13
43
|
{
|
|
14
44
|
/// <summary>跨 domain reload 的 dictionary journal 操作公共协调骨架。</summary>
|
|
@@ -84,8 +114,8 @@ namespace UnityCli
|
|
|
84
114
|
|| Array.IndexOf(phases ?? new string[0], Text(root, "phase")) < 0)
|
|
85
115
|
throw new InvalidDataException("Active root common fields are invalid.");
|
|
86
116
|
}
|
|
87
|
-
/// <summary>供带有私有控制面的操作注册 start/status
|
|
88
|
-
protected virtual IEnumerable<(string name, bool destructive)> AdditionalCommands { get { yield break; } }
|
|
117
|
+
/// <summary>供带有私有控制面的操作注册 start/status 之外的命令与唯一queue分类。</summary>
|
|
118
|
+
protected virtual IEnumerable<(string name, bool destructive, UnityCliBridgeQueuePolicy.WorkClass queueClass)> AdditionalCommands { get { yield break; } }
|
|
89
119
|
protected virtual object ExecuteAdditionalCommand(BridgeRequest request)
|
|
90
120
|
{
|
|
91
121
|
throw new BridgeCommandException("E_REQUEST_NOT_FOUND", OperationDisplayName + " command was not found.");
|
|
@@ -115,6 +145,74 @@ namespace UnityCli
|
|
|
115
145
|
protected virtual TerminalCleanupDecision EvaluateTerminalCleanupRoot(Dictionary<string, object> root, string requestId, string requestDigest) { return TerminalCleanupDecision.Cleanup; }
|
|
116
146
|
/// <summary>root不可读时,业务必须仅凭独立durable terminal决定清理、重试或拒绝。</summary>
|
|
117
147
|
protected virtual TerminalCleanupDecision EvaluateUnreadableTerminalCleanup(string requestId, string requestDigest) { return TerminalCleanupDecision.Cleanup; }
|
|
148
|
+
|
|
149
|
+
/// <summary>每tick先消费scope准入marker;只有root与lease的exact状态都可证明时才推进或清理owner。</summary>
|
|
150
|
+
protected bool RetryAdmissionOwnerRecoveryMarker()
|
|
151
|
+
{
|
|
152
|
+
return RetryAdmissionOwnerRecoveryMarker(ProductionQueueState, Scope, OperationDisplayName);
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/// <summary>production与隔离测试共用同一root-missing保守终态算法,任何写入失败都保留原marker。</summary>
|
|
156
|
+
private static bool RetryAdmissionOwnerRecoveryMarker(BridgeQueueState state, string scope, string displayName)
|
|
157
|
+
{
|
|
158
|
+
var markerScope = scope + "-admission-owner";
|
|
159
|
+
if (state.OperationExists(scope + "-terminal-cleanup"))
|
|
160
|
+
{
|
|
161
|
+
try
|
|
162
|
+
{
|
|
163
|
+
if (UnityCliActiveOperation.RetryExactTerminalCleanup(scope, state)) return true;
|
|
164
|
+
}
|
|
165
|
+
catch { return true; }
|
|
166
|
+
}
|
|
167
|
+
if (!state.OperationExists(markerScope)) return false;
|
|
168
|
+
Dictionary<string, object> marker;
|
|
169
|
+
try { marker = state.LoadOperation(markerScope); }
|
|
170
|
+
catch { return true; }
|
|
171
|
+
if (marker == null) return true;
|
|
172
|
+
var requestId = Text(marker, "requestId");
|
|
173
|
+
var ownerRequestDigest = Text(marker, "admissionRequestDigest");
|
|
174
|
+
var topRequestDigest = Text(marker, "requestDigest");
|
|
175
|
+
if (!IsSafeId(requestId) || !IsSha256(ownerRequestDigest) || !IsSha256(topRequestDigest)) return true;
|
|
176
|
+
AdmissionOwnerIdentity owner;
|
|
177
|
+
try { owner = ReconcileAdmissionTransferForLiveMarker(state, markerScope, marker, requestId, ownerRequestDigest); }
|
|
178
|
+
catch { return true; }
|
|
179
|
+
if (owner == null || !string.Equals(owner.TopRequestDigest, topRequestDigest, StringComparison.Ordinal)) return true;
|
|
180
|
+
|
|
181
|
+
Dictionary<string, object> root;
|
|
182
|
+
try { root = state.LoadOperation(scope); }
|
|
183
|
+
catch { return true; }
|
|
184
|
+
if (root != null)
|
|
185
|
+
{
|
|
186
|
+
var rootMatches = string.Equals(Text(root, "editorSessionId"), EditorSessionId(), StringComparison.Ordinal)
|
|
187
|
+
&& string.Equals(Text(root, "requestId"), requestId, StringComparison.Ordinal)
|
|
188
|
+
&& string.Equals(Text(root, "requestDigest"), topRequestDigest, StringComparison.Ordinal);
|
|
189
|
+
return !rootMatches;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
bool leaseOwned;
|
|
193
|
+
if (!state.TryIsLeaseOwned(owner.RequestId, owner.RequestDigest, out leaseOwned)) return true;
|
|
194
|
+
try
|
|
195
|
+
{
|
|
196
|
+
object first;
|
|
197
|
+
if (!state.TryGetTerminal(scope, requestId, topRequestDigest, out first))
|
|
198
|
+
{
|
|
199
|
+
var terminal = ProtocolEnvelopeFactory.Error(requestId, "E_EXECUTION_TIMEOUT", displayName + (leaseOwned ? " active root disappeared while its exact lease was retained; outcome is unknown." : " active root disappeared after its exact lease was released; outcome is unknown."), null, new[] { "Inspect the affected business state before submitting another mutation." });
|
|
200
|
+
first = state.StoreTerminalFirst(scope, requestId, topRequestDigest, terminal);
|
|
201
|
+
}
|
|
202
|
+
object confirmed;
|
|
203
|
+
if (!state.TryGetTerminal(scope, requestId, topRequestDigest, out confirmed)
|
|
204
|
+
|| !string.Equals(UnityCliSerializer.Serialize(first), UnityCliSerializer.Serialize(confirmed), StringComparison.Ordinal)) return true;
|
|
205
|
+
UnityCliActiveOperation.BeginExactTerminalCleanup(scope, requestId, topRequestDigest, state);
|
|
206
|
+
}
|
|
207
|
+
catch { return true; }
|
|
208
|
+
return true;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
internal static bool RetryAdmissionOwnerRecoveryMarkerForTests(BridgeQueueState state, string scope, string displayName)
|
|
212
|
+
{
|
|
213
|
+
if (state == null || state.IsolatedExecution == null) throw new ArgumentException("Reload recovery test state must be isolated.", "state");
|
|
214
|
+
return RetryAdmissionOwnerRecoveryMarker(state, scope, displayName);
|
|
215
|
+
}
|
|
118
216
|
/// <summary>effect前放弃只能清理同identity且由业务证明从未越过effect barrier的root。</summary>
|
|
119
217
|
protected virtual bool CanCleanupAbandonedPreEffectRoot(Dictionary<string, object> root, string requestId, string requestDigest) { return false; }
|
|
120
218
|
/// <summary>root删除后、lease释放前,业务可清理同identity且未dispatch的附属status;失败必须重试。</summary>
|
|
@@ -134,7 +232,7 @@ namespace UnityCli
|
|
|
134
232
|
|
|
135
233
|
private string TerminalCleanupScope { get { return Scope + "-terminal-cleanup"; } }
|
|
136
234
|
private string PreEffectCleanupScope { get { return Scope + "-pre-effect-cleanup"; } }
|
|
137
|
-
private
|
|
235
|
+
private readonly UnityCliReloadTickSchedule tickSchedule = new UnityCliReloadTickSchedule();
|
|
138
236
|
private string lastTerminalRequestId;
|
|
139
237
|
private string lastTerminalRequestDigest;
|
|
140
238
|
private object lastTerminalEnvelope;
|
|
@@ -157,10 +255,10 @@ namespace UnityCli
|
|
|
157
255
|
}
|
|
158
256
|
internal void Register(BridgeCommandRegistry registry)
|
|
159
257
|
{
|
|
160
|
-
registry.Register<BridgeRequest>(StartCommand, "internal", true, CommandTimeoutMs, (r, c) => { throw new InvalidOperationException(OperationDisplayName + " is coordinator-owned."); });
|
|
161
|
-
registry.Register<BridgeRequest>(StatusCommand, "internal", false, CommandTimeoutMs, (r, c) => { throw new InvalidOperationException(OperationDisplayName + " is coordinator-owned."); });
|
|
258
|
+
registry.Register<BridgeRequest>(StartCommand, "internal", true, CommandTimeoutMs, (r, c) => { throw new InvalidOperationException(OperationDisplayName + " is coordinator-owned."); }, UnityCliBridgeQueuePolicy.WorkClass.Mutation);
|
|
259
|
+
registry.Register<BridgeRequest>(StatusCommand, "internal", false, CommandTimeoutMs, (r, c) => { throw new InvalidOperationException(OperationDisplayName + " is coordinator-owned."); }, UnityCliBridgeQueuePolicy.WorkClass.SafeStatus);
|
|
162
260
|
foreach (var additional in AdditionalCommands)
|
|
163
|
-
registry.Register<BridgeRequest>(additional.name, "internal", additional.destructive, CommandTimeoutMs, (r, c) => { throw new InvalidOperationException(OperationDisplayName + " is coordinator-owned."); });
|
|
261
|
+
registry.Register<BridgeRequest>(additional.name, "internal", additional.destructive, CommandTimeoutMs, (r, c) => { throw new InvalidOperationException(OperationDisplayName + " is coordinator-owned."); }, additional.queueClass);
|
|
164
262
|
}
|
|
165
263
|
|
|
166
264
|
/// <summary>HTTP 接受后建立或续接唯一 journal;lease 成功后任意异常都必须释放它。</summary>
|
|
@@ -248,15 +346,15 @@ namespace UnityCli
|
|
|
248
346
|
/// <summary>每帧只推进当前 lease owner;session/deadline 不可确认时先持久化失败终态。</summary>
|
|
249
347
|
internal virtual void Tick()
|
|
250
348
|
{
|
|
251
|
-
if (
|
|
252
|
-
|
|
349
|
+
if (RetryAdmissionOwnerRecoveryMarker()) return;
|
|
350
|
+
if (!tickSchedule.TryEnter()) return;
|
|
253
351
|
if (RetryPreEffectCleanup()) return;
|
|
254
352
|
if (RetryTerminalCleanup()) return;
|
|
255
353
|
var root = Load();
|
|
256
354
|
if (root == null || !UnityCliSessionMutationLease.IsOwnedBy(Text(root, "requestId"), Text(root, "requestDigest"))) return;
|
|
257
355
|
if (TryResumePublishedTerminal(root)) return;
|
|
258
356
|
if (!string.Equals(Text(root, "editorSessionId"), EditorSessionId(), StringComparison.Ordinal)) { Fail(root, "E_EXECUTION_TIMEOUT", SessionChangedMessage); return; }
|
|
259
|
-
if (
|
|
357
|
+
if (tickSchedule.UtcNow >= Time(root, "deadline")) { Fail(root, "E_EXECUTION_TIMEOUT", DeadlineMessage); return; }
|
|
260
358
|
OnTick(root);
|
|
261
359
|
}
|
|
262
360
|
|
|
@@ -394,15 +492,14 @@ namespace UnityCli
|
|
|
394
492
|
}
|
|
395
493
|
pendingPreEffectCleanupRequestId = requestId;
|
|
396
494
|
pendingPreEffectCleanupRequestDigest = requestDigest;
|
|
397
|
-
try { pendingPreEffectAdmissionOwner = CaptureAdmissionOwner(requestId); }
|
|
495
|
+
try { pendingPreEffectAdmissionOwner = CaptureAdmissionOwner(requestId, requestDigest); }
|
|
398
496
|
catch (Exception exception) { WriteLog(Scope + " pre-effect admission owner freeze failed: " + exception.Message); return; }
|
|
399
497
|
var marker = new Dictionary<string, object>
|
|
400
498
|
{
|
|
401
499
|
{ "requestId", requestId }, { "requestDigest", requestDigest }, { "editorSessionId", EditorSessionId() }
|
|
402
500
|
};
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
catch (Exception exception) { WriteLog(Scope + " pre-effect cleanup marker write failed: " + exception.Message); }
|
|
501
|
+
try { pendingPreEffectAdmissionOwner = PersistAdmissionOwnerTransfer(PreEffectCleanupScope, marker, pendingPreEffectAdmissionOwner, UnityCliAdmissionPool.AdmissionOwnerState.TerminalCleanup); }
|
|
502
|
+
catch (Exception exception) { WriteLog(Scope + " pre-effect cleanup owner transfer failed: " + exception.Message); return; }
|
|
406
503
|
RetryPreEffectCleanup();
|
|
407
504
|
}
|
|
408
505
|
|
|
@@ -430,7 +527,7 @@ namespace UnityCli
|
|
|
430
527
|
{ "requestDigest", pendingPreEffectCleanupRequestDigest },
|
|
431
528
|
{ "editorSessionId", EditorSessionId() }
|
|
432
529
|
};
|
|
433
|
-
AddAdmissionOwnerFields(cleanup, pendingPreEffectAdmissionOwner);
|
|
530
|
+
AddAdmissionOwnerFields(cleanup, pendingPreEffectAdmissionOwner, UnityCliAdmissionPool.AdmissionOwnerState.TerminalCleanup);
|
|
434
531
|
}
|
|
435
532
|
if (cleanup == null) return markerReadFailed;
|
|
436
533
|
if (markerReadFailed || !UnityCliActiveOperation.Exists(PreEffectCleanupScope))
|
|
@@ -447,8 +544,10 @@ namespace UnityCli
|
|
|
447
544
|
return true;
|
|
448
545
|
}
|
|
449
546
|
if (string.IsNullOrEmpty(requestId) || string.IsNullOrEmpty(requestDigest)) return true;
|
|
450
|
-
|
|
451
|
-
|
|
547
|
+
AdmissionOwnerIdentity admissionOwner;
|
|
548
|
+
try { admissionOwner = ReconcileAdmissionTransferForLiveMarker(PreEffectCleanupScope, cleanup, requestId, requestDigest); }
|
|
549
|
+
catch (Exception exception) { WriteLog(Scope + " pre-effect admission transfer retry failed: " + exception.Message); return true; }
|
|
550
|
+
if (admissionOwner == null) { ClearPendingPreEffectCleanup(requestId, requestDigest); return true; }
|
|
452
551
|
|
|
453
552
|
Dictionary<string, object> active = null;
|
|
454
553
|
if (UnityCliActiveOperation.Exists(Scope))
|
|
@@ -507,15 +606,14 @@ namespace UnityCli
|
|
|
507
606
|
}
|
|
508
607
|
pendingTerminalCleanupRequestId = requestId;
|
|
509
608
|
pendingTerminalCleanupRequestDigest = requestDigest;
|
|
510
|
-
try { pendingTerminalAdmissionOwner = CaptureAdmissionOwner(requestId); }
|
|
609
|
+
try { pendingTerminalAdmissionOwner = CaptureAdmissionOwner(requestId, requestDigest); }
|
|
511
610
|
catch (Exception exception) { WriteLog(Scope + " terminal admission owner freeze failed: " + exception.Message); return; }
|
|
512
611
|
var marker = new Dictionary<string, object>
|
|
513
612
|
{
|
|
514
613
|
{ "requestId", requestId }, { "requestDigest", requestDigest }, { "editorSessionId", EditorSessionId() }
|
|
515
614
|
};
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
catch (Exception exception) { WriteLog(Scope + " terminal cleanup marker write failed: " + exception.Message); }
|
|
615
|
+
try { pendingTerminalAdmissionOwner = PersistAdmissionOwnerTransfer(TerminalCleanupScope, marker, pendingTerminalAdmissionOwner, UnityCliAdmissionPool.AdmissionOwnerState.TerminalCleanup); }
|
|
616
|
+
catch (Exception exception) { WriteLog(Scope + " terminal cleanup owner transfer failed: " + exception.Message); return; }
|
|
519
617
|
RetryTerminalCleanup();
|
|
520
618
|
}
|
|
521
619
|
|
|
@@ -540,7 +638,7 @@ namespace UnityCli
|
|
|
540
638
|
{ "requestDigest", pendingTerminalCleanupRequestDigest },
|
|
541
639
|
{ "editorSessionId", EditorSessionId() }
|
|
542
640
|
};
|
|
543
|
-
AddAdmissionOwnerFields(cleanup, pendingTerminalAdmissionOwner);
|
|
641
|
+
AddAdmissionOwnerFields(cleanup, pendingTerminalAdmissionOwner, UnityCliAdmissionPool.AdmissionOwnerState.TerminalCleanup);
|
|
544
642
|
}
|
|
545
643
|
if (cleanup == null) return false;
|
|
546
644
|
if (!UnityCliActiveOperation.Exists(TerminalCleanupScope))
|
|
@@ -557,14 +655,11 @@ namespace UnityCli
|
|
|
557
655
|
}
|
|
558
656
|
var requestId = Text(cleanup, "requestId");
|
|
559
657
|
var requestDigest = Text(cleanup, "requestDigest");
|
|
560
|
-
if (string.IsNullOrEmpty(requestId) || string.IsNullOrEmpty(requestDigest))
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
}
|
|
566
|
-
var admissionOwner = ReadAdmissionOwnerFields(cleanup, requestId);
|
|
567
|
-
if (admissionOwner == null) return true;
|
|
658
|
+
if (string.IsNullOrEmpty(requestId) || string.IsNullOrEmpty(requestDigest)) return true;
|
|
659
|
+
AdmissionOwnerIdentity admissionOwner;
|
|
660
|
+
try { admissionOwner = ReconcileAdmissionTransferForLiveMarker(TerminalCleanupScope, cleanup, requestId, requestDigest); }
|
|
661
|
+
catch (Exception exception) { WriteLog(Scope + " terminal admission transfer retry failed: " + exception.Message); return true; }
|
|
662
|
+
if (admissionOwner == null) { ClearPendingTerminalCleanup(requestId, requestDigest); return true; }
|
|
568
663
|
|
|
569
664
|
Dictionary<string, object> active = null;
|
|
570
665
|
if (UnityCliActiveOperation.Exists(Scope))
|
|
@@ -575,18 +670,14 @@ namespace UnityCli
|
|
|
575
670
|
WriteLog(Scope + " terminal active root read failed: " + exception.Message);
|
|
576
671
|
if (!UnityCliSessionMutationLease.IsOwnedBy(requestId, requestDigest))
|
|
577
672
|
{
|
|
673
|
+
if (!CompleteAdmissionRoot(admissionOwner)) return true;
|
|
578
674
|
try { UnityCliActiveOperation.Clear(TerminalCleanupScope); } catch { return true; }
|
|
579
675
|
ClearPendingTerminalCleanup(requestId, requestDigest);
|
|
580
676
|
return true;
|
|
581
677
|
}
|
|
582
678
|
var unreadableDecision = EvaluateUnreadableTerminalCleanup(requestId, requestDigest);
|
|
583
679
|
if (unreadableDecision == TerminalCleanupDecision.Retry) return true;
|
|
584
|
-
if (unreadableDecision == TerminalCleanupDecision.Reject)
|
|
585
|
-
{
|
|
586
|
-
try { UnityCliActiveOperation.Clear(TerminalCleanupScope); } catch { return true; }
|
|
587
|
-
ClearPendingTerminalCleanup(requestId, requestDigest);
|
|
588
|
-
return true;
|
|
589
|
-
}
|
|
680
|
+
if (unreadableDecision == TerminalCleanupDecision.Reject) return true;
|
|
590
681
|
try { UnityCliActiveOperation.Clear(Scope); }
|
|
591
682
|
catch (Exception clearException) { WriteLog(Scope + " corrupt terminal root cleanup failed: " + clearException.Message); return true; }
|
|
592
683
|
if (UnityCliActiveOperation.Exists(Scope)) return true;
|
|
@@ -601,18 +692,14 @@ namespace UnityCli
|
|
|
601
692
|
if (!markerMatchesActive)
|
|
602
693
|
{
|
|
603
694
|
if (!LeaseDefinitelyNotOwned(requestId, requestDigest)) return true;
|
|
695
|
+
if (!CompleteAdmissionRoot(admissionOwner)) return true;
|
|
604
696
|
try { UnityCliActiveOperation.Clear(TerminalCleanupScope); } catch { return true; }
|
|
605
697
|
ClearPendingTerminalCleanup(requestId, requestDigest);
|
|
606
698
|
return true;
|
|
607
699
|
}
|
|
608
700
|
var cleanupDecision = EvaluateTerminalCleanupRoot(active, requestId, requestDigest);
|
|
609
701
|
if (cleanupDecision == TerminalCleanupDecision.Retry) return true;
|
|
610
|
-
if (cleanupDecision == TerminalCleanupDecision.Reject)
|
|
611
|
-
{
|
|
612
|
-
try { UnityCliActiveOperation.Clear(TerminalCleanupScope); } catch { return true; }
|
|
613
|
-
ClearPendingTerminalCleanup(requestId, requestDigest);
|
|
614
|
-
return true;
|
|
615
|
-
}
|
|
702
|
+
if (cleanupDecision == TerminalCleanupDecision.Reject) return true;
|
|
616
703
|
try { UnityCliActiveOperation.Clear(Scope); }
|
|
617
704
|
catch (Exception exception) { WriteLog(Scope + " terminal active root cleanup failed: " + exception.Message); return true; }
|
|
618
705
|
if (UnityCliActiveOperation.Exists(Scope)) return true;
|
|
@@ -5,7 +5,6 @@ using System.Collections.Generic;
|
|
|
5
5
|
using System.Globalization;
|
|
6
6
|
using System.Linq;
|
|
7
7
|
using System.Reflection;
|
|
8
|
-
using System.Text;
|
|
9
8
|
using System.Threading;
|
|
10
9
|
using System.Threading.Tasks;
|
|
11
10
|
using UnityEditor;
|
|
@@ -24,48 +23,25 @@ namespace UnityCli
|
|
|
24
23
|
// Play Mode session tracking
|
|
25
24
|
private static string currentPlayModeSessionId = null;
|
|
26
25
|
private static bool playModeReady = false;
|
|
27
|
-
private static int runtimeRegistryVersion = 0;
|
|
28
|
-
private static string runtimeToolCatalogFingerprint = null;
|
|
29
26
|
private static bool runtimeExecutorInitialized = false;
|
|
30
27
|
|
|
31
|
-
/// <summary>
|
|
32
|
-
/// Initialize the Runtime Executor: subscribe to Play Mode state change
|
|
33
|
-
/// events and compute the initial tool catalog fingerprint.
|
|
34
|
-
/// </summary>
|
|
28
|
+
/// <summary>订阅当前domain的PlayMode状态;只验证已发布catalog,不触发发现或重建。</summary>
|
|
35
29
|
private static void InitializeRuntimeExecutor()
|
|
36
30
|
{
|
|
37
31
|
if (runtimeExecutorInitialized) return;
|
|
32
|
+
ReadPublishedProjectToolCatalogSnapshot();
|
|
38
33
|
runtimeExecutorInitialized = true;
|
|
39
34
|
EditorApplication.playModeStateChanged += OnRuntimePlayModeStateChanged;
|
|
40
|
-
RefreshRuntimeToolCatalog();
|
|
41
35
|
WriteLog("runtime_executor_initialized");
|
|
42
36
|
|
|
43
|
-
// If we are already in Play Mode at initialization time (e.g. after domain reload),
|
|
44
|
-
// immediately establish the session as ready.
|
|
45
37
|
if (EditorApplication.isPlaying)
|
|
46
38
|
{
|
|
47
39
|
currentPlayModeSessionId = GeneratePlayModeSessionId();
|
|
48
40
|
playModeReady = true;
|
|
49
|
-
|
|
50
|
-
RefreshRuntimeToolCatalog();
|
|
51
|
-
WriteLog("runtime_session_ready_after_domain_reload sessionId=" + currentPlayModeSessionId + " registryVersion=" + runtimeRegistryVersion.ToString(CultureInfo.InvariantCulture) + " fingerprint=" + (runtimeToolCatalogFingerprint ?? "none"));
|
|
41
|
+
WriteLog("runtime_session_ready_after_domain_reload sessionId=" + currentPlayModeSessionId);
|
|
52
42
|
}
|
|
53
43
|
}
|
|
54
44
|
|
|
55
|
-
/// <summary>
|
|
56
|
-
/// Called after domain reload to reinitialize the Runtime Executor.
|
|
57
|
-
/// Domain reload resets all static fields, so the event subscription
|
|
58
|
-
/// and session state are lost. This method re-subscribes to Play Mode
|
|
59
|
-
/// state change events and restores the session state if already in
|
|
60
|
-
/// Play Mode.
|
|
61
|
-
/// </summary>
|
|
62
|
-
private static void ReinitializeRuntimeExecutorAfterDomainReload()
|
|
63
|
-
{
|
|
64
|
-
// Reset the guard so InitializeRuntimeExecutor runs again
|
|
65
|
-
runtimeExecutorInitialized = false;
|
|
66
|
-
InitializeRuntimeExecutor();
|
|
67
|
-
}
|
|
68
|
-
|
|
69
45
|
/// <summary>
|
|
70
46
|
/// Handle Play Mode state transitions. Generate a new session ID when
|
|
71
47
|
/// entering Play Mode, mark ready, and invalidate the session when
|
|
@@ -83,11 +59,8 @@ namespace UnityCli
|
|
|
83
59
|
break;
|
|
84
60
|
|
|
85
61
|
case PlayModeStateChange.ExitingEditMode:
|
|
86
|
-
// About to enter Play Mode: pre-generate session ID
|
|
87
62
|
currentPlayModeSessionId = GeneratePlayModeSessionId();
|
|
88
63
|
playModeReady = false;
|
|
89
|
-
runtimeRegistryVersion++;
|
|
90
|
-
RefreshRuntimeToolCatalog();
|
|
91
64
|
WriteLog("runtime_session_entering sessionId=" + currentPlayModeSessionId);
|
|
92
65
|
break;
|
|
93
66
|
|
|
@@ -96,13 +69,9 @@ namespace UnityCli
|
|
|
96
69
|
// After domain reload, currentPlayModeSessionId is reset to null.
|
|
97
70
|
// Generate a new session ID if the pre-generated one was lost.
|
|
98
71
|
if (currentPlayModeSessionId == null)
|
|
99
|
-
{
|
|
100
72
|
currentPlayModeSessionId = GeneratePlayModeSessionId();
|
|
101
|
-
runtimeRegistryVersion++;
|
|
102
|
-
RefreshRuntimeToolCatalog();
|
|
103
|
-
}
|
|
104
73
|
playModeReady = true;
|
|
105
|
-
WriteLog("runtime_session_ready sessionId=" + currentPlayModeSessionId
|
|
74
|
+
WriteLog("runtime_session_ready sessionId=" + currentPlayModeSessionId);
|
|
106
75
|
break;
|
|
107
76
|
|
|
108
77
|
case PlayModeStateChange.ExitingPlayMode:
|
|
@@ -118,44 +87,26 @@ namespace UnityCli
|
|
|
118
87
|
return "pms-" + DateTime.UtcNow.ToString("yyyyMMddHHmmss", CultureInfo.InvariantCulture) + "-" + Guid.NewGuid().ToString("N").Substring(0, 8);
|
|
119
88
|
}
|
|
120
89
|
|
|
121
|
-
private static void RefreshRuntimeToolCatalog()
|
|
122
|
-
{
|
|
123
|
-
DiscoverProjectTools();
|
|
124
|
-
var count = 0;
|
|
125
|
-
var material = new StringBuilder();
|
|
126
|
-
foreach (var pair in ProjectTools)
|
|
127
|
-
{
|
|
128
|
-
var def = pair.Value;
|
|
129
|
-
if (def.Target == "runtime" || def.Target == "both")
|
|
130
|
-
{
|
|
131
|
-
count++;
|
|
132
|
-
material.Append(def.Name).Append('\n')
|
|
133
|
-
.Append(def.Fingerprint ?? "").Append('\n');
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
runtimeToolCatalogFingerprint = Sha256Hex("unity-cli-runtime-tool-catalog-v1\ncount=" + count.ToString(CultureInfo.InvariantCulture) + "\n" + material.ToString());
|
|
137
|
-
}
|
|
138
|
-
|
|
139
90
|
/// <summary>
|
|
140
91
|
/// Runtime session readiness report, included in instance registration
|
|
141
92
|
/// and available via editor.state.
|
|
142
93
|
/// </summary>
|
|
143
94
|
private static Dictionary<string, object> RuntimeSessionData()
|
|
144
95
|
{
|
|
96
|
+
var catalog = ReadPublishedProjectToolCatalogSnapshot();
|
|
145
97
|
var availableTools = new List<object>();
|
|
146
|
-
foreach (var
|
|
98
|
+
foreach (var descriptor in catalog.Descriptors)
|
|
147
99
|
{
|
|
148
|
-
if (
|
|
100
|
+
if (descriptor.Target != "runtime" && descriptor.Target != "both") continue;
|
|
149
101
|
availableTools.Add(new Dictionary<string, object>
|
|
150
102
|
{
|
|
151
|
-
{ "name",
|
|
103
|
+
{ "name", descriptor.Name }, { "target", descriptor.Target }, { "availabilityScope", descriptor.AvailabilityScope }, { "available", playModeReady }
|
|
152
104
|
});
|
|
153
105
|
}
|
|
154
106
|
// 会话数据直接嵌入最终 response,禁止序列化后重新解析为 object。
|
|
155
107
|
return new Dictionary<string, object>
|
|
156
108
|
{
|
|
157
|
-
{ "playModeSessionId", currentPlayModeSessionId }, { "ready", playModeReady }, { "
|
|
158
|
-
{ "toolCatalogFingerprint", runtimeToolCatalogFingerprint }, { "availableRuntimeTools", availableTools }
|
|
109
|
+
{ "playModeSessionId", currentPlayModeSessionId }, { "ready", playModeReady }, { "availableRuntimeTools", availableTools }
|
|
159
110
|
};
|
|
160
111
|
}
|
|
161
112
|
|
|
@@ -165,10 +116,10 @@ namespace UnityCli
|
|
|
165
116
|
/// </summary>
|
|
166
117
|
private static object RuntimeToolList(UnityCli.Protocol.BridgeRequest request)
|
|
167
118
|
{
|
|
168
|
-
|
|
119
|
+
var catalog = ReadPublishedProjectToolCatalogSnapshot();
|
|
169
120
|
InitializeRuntimeExecutor();
|
|
170
121
|
var tools = new System.Collections.Generic.List<object>();
|
|
171
|
-
foreach (var definition in
|
|
122
|
+
foreach (var definition in catalog.Descriptors.OrderBy(tool => tool.Name, StringComparer.Ordinal))
|
|
172
123
|
{
|
|
173
124
|
if (definition.Target != "runtime" && definition.Target != "both") continue;
|
|
174
125
|
var descriptor = ProjectToolDescriptorData(definition);
|
|
@@ -192,14 +143,13 @@ namespace UnityCli
|
|
|
192
143
|
{
|
|
193
144
|
public string Name { get; set; }
|
|
194
145
|
[UnityCliAnyJson] public object Input { get; set; }
|
|
195
|
-
public string ExpectedDescriptorFingerprint { get; set; }
|
|
196
146
|
public string ArtifactDir { get; set; }
|
|
197
147
|
public string ProjectPath { get; set; }
|
|
198
148
|
}
|
|
199
149
|
|
|
200
150
|
private static async ValueTask<object> RuntimeToolRun(UnityCli.Protocol.BridgeRequest request, CancellationToken cancellationToken)
|
|
201
151
|
{
|
|
202
|
-
|
|
152
|
+
var catalog = ReadPublishedProjectToolCatalog();
|
|
203
153
|
InitializeRuntimeExecutor();
|
|
204
154
|
|
|
205
155
|
var args = request.DeserializeArgs<RuntimeToolRunArgs>();
|
|
@@ -220,13 +170,13 @@ namespace UnityCli
|
|
|
220
170
|
}
|
|
221
171
|
|
|
222
172
|
// Validate the tool exists and is a runtime tool
|
|
223
|
-
if (!
|
|
173
|
+
if (!catalog.ExecutableTools.ContainsKey(name))
|
|
224
174
|
{
|
|
225
175
|
throw new BridgeCommandException("E_TOOL_NOT_FOUND", "Tool not found: " + name,
|
|
226
176
|
"Run unitycli tools group --instance <id|projectPath|alias> or tools search <keyword> to inspect the connected instance catalog.");
|
|
227
177
|
}
|
|
228
178
|
|
|
229
|
-
var definition =
|
|
179
|
+
var definition = catalog.ExecutableTools[name];
|
|
230
180
|
if (definition.Target != "runtime" && definition.Target != "both")
|
|
231
181
|
{
|
|
232
182
|
throw new BridgeCommandException("E_RUNTIME_TOOL_TARGET_MISMATCH",
|
|
@@ -236,26 +186,6 @@ namespace UnityCli
|
|
|
236
186
|
}
|
|
237
187
|
var dryRun = request.Execution != null && request.Execution.DryRun == true;
|
|
238
188
|
|
|
239
|
-
// runtime-tool.run 是内部包装命令;门禁前刷新 live 指纹,防止跨 PlayMode/domain reload 重放旧 proof。
|
|
240
|
-
var fingerprintCheck = RefreshProjectToolFingerprint(definition);
|
|
241
|
-
if (!string.IsNullOrEmpty(args.ExpectedDescriptorFingerprint)
|
|
242
|
-
&& !string.Equals(args.ExpectedDescriptorFingerprint, definition.Fingerprint, StringComparison.Ordinal))
|
|
243
|
-
{
|
|
244
|
-
throw new BridgeCommandException(
|
|
245
|
-
"E_TOOL_DESCRIPTOR_CHANGED",
|
|
246
|
-
"The runtime Tool descriptor changed after discovery: " + name,
|
|
247
|
-
new Dictionary<string, object> { { "toolName", name }, { "expectedFingerprint", args.ExpectedDescriptorFingerprint }, { "actualFingerprint", definition.Fingerprint } },
|
|
248
|
-
new[] { "Run tools describe again in the current Play Mode generation before constructing a new request." });
|
|
249
|
-
}
|
|
250
|
-
// Fingerprint policy 使用同一次 live refresh 结果。
|
|
251
|
-
if (fingerprintCheck.Blocked)
|
|
252
|
-
{
|
|
253
|
-
WriteLog("runtime_tool_fingerprint_blocked requestId=" + request.RequestId + " name=" + name);
|
|
254
|
-
throw new BridgeCommandException("E_TOOL_FINGERPRINT_MISMATCH", fingerprintCheck.Message,
|
|
255
|
-
ProjectToolFingerprintDetails(definition),
|
|
256
|
-
ProjectToolFingerprintRePinSteps(definition));
|
|
257
|
-
}
|
|
258
|
-
|
|
259
189
|
// timeout 仅来自顶层 execution,业务 input 不参与执行策略。
|
|
260
190
|
var timeoutMs = request.ExecutionTimeoutMs(definition.DefaultTimeoutMs, definition.MaxTimeoutMs);
|
|
261
191
|
|