@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,10 +1,7 @@
|
|
|
1
1
|
#if UNITY_EDITOR
|
|
2
2
|
using System;
|
|
3
3
|
using System.Collections.Generic;
|
|
4
|
-
using System.Globalization;
|
|
5
4
|
using System.IO;
|
|
6
|
-
using System.Linq;
|
|
7
|
-
using System.Text;
|
|
8
5
|
using System.Threading;
|
|
9
6
|
using System.Threading.Tasks;
|
|
10
7
|
using UnityEditor;
|
|
@@ -14,7 +11,7 @@ namespace UnityCli
|
|
|
14
11
|
{
|
|
15
12
|
public static partial class UnityCliBridge
|
|
16
13
|
{
|
|
17
|
-
/// <summary>editor.refresh 的单 scope
|
|
14
|
+
/// <summary>editor.refresh 的单 scope durable operation;proof 只使用 Unity-owned artifact generations。</summary>
|
|
18
15
|
internal static class UnityCliLiveRefreshCoordinator
|
|
19
16
|
{
|
|
20
17
|
private static readonly Coordinator Instance = new Coordinator();
|
|
@@ -24,7 +21,7 @@ namespace UnityCli
|
|
|
24
21
|
internal static Task<string> Execute(BridgeRequest request, byte[] raw, Func<bool> accept, CancellationToken ct) { return Instance.Execute(request, raw, accept, ct); }
|
|
25
22
|
internal static void Initialize() { }
|
|
26
23
|
internal static void Shutdown() { }
|
|
27
|
-
internal static void BeforeReload() { Instance.Update(
|
|
24
|
+
internal static void BeforeReload() { Instance.Update(root => root["reloadObserved"] = true); }
|
|
28
25
|
internal static void Tick() { Instance.Tick(); }
|
|
29
26
|
|
|
30
27
|
private sealed class Coordinator : UnityCliReloadOperation
|
|
@@ -34,9 +31,10 @@ namespace UnityCli
|
|
|
34
31
|
protected override string StatusCommand { get { return "internal.editor.refresh.status"; } }
|
|
35
32
|
protected override string OperationDisplayName { get { return "Refresh"; } }
|
|
36
33
|
protected override bool IncludeAcceptedInStatus { get { return true; } }
|
|
37
|
-
protected override string SessionChangedMessage { get { return "Refresh result cannot be confirmed after the Editor session changed;
|
|
38
|
-
protected override string DeadlineMessage { get { return "Refresh did not reach a confirmed terminal state before the deadline;
|
|
34
|
+
protected override string SessionChangedMessage { get { return "Refresh result cannot be confirmed after the Editor session changed; inspect editor.state and asset state."; } }
|
|
35
|
+
protected override string DeadlineMessage { get { return "Refresh did not reach a confirmed terminal state before the shared deadline; inspect editor.state and asset state."; } }
|
|
39
36
|
protected override object DeserializeStartArgs(BridgeRequest request) { return request.DeserializeArgs<Args>(); }
|
|
37
|
+
|
|
40
38
|
protected override void ValidateStart(object value)
|
|
41
39
|
{
|
|
42
40
|
var args = (Args)value;
|
|
@@ -44,37 +42,39 @@ namespace UnityCli
|
|
|
44
42
|
if (!string.Equals(args.ExpectedEditorSessionId, EditorSessionId(), StringComparison.Ordinal)) throw new BridgeCommandException("E_EDITOR_SESSION_REPLACED", "The selected Editor session changed before refresh execution.");
|
|
45
43
|
if (EditorApplication.isPlaying || IsPlayModeChanging()) throw new BridgeCommandException("E_TOOL_PLAYMODE_UNAVAILABLE", "editor.refresh is editor-only and requires stable Edit Mode.");
|
|
46
44
|
}
|
|
45
|
+
|
|
47
46
|
protected override void ValidateLoadedRoot(Dictionary<string, object> root)
|
|
48
47
|
{
|
|
49
|
-
ValidateRootContract(root, new[]
|
|
50
|
-
|
|
48
|
+
ValidateRootContract(root, new[]
|
|
49
|
+
{
|
|
50
|
+
"compile", "compilationRequested", "compilationObserved", "compilePhase", "compileDispatchSequence", "compileStartedSequence", "compileFinishedSequence", "compileStartedCycle",
|
|
51
|
+
"compileDiagnostics", "compileErrorCount", "compileWarningCount", "compileInfoCount", "compileDiagnosticsTruncated", "stableFrames",
|
|
52
|
+
"beforeDependencyGeneration", "beforeProcessedGeneration", "importObserved", "reloadObserved", "rootContractDigest"
|
|
53
|
+
}, "queued", "prepared", "dispatching", "refresh_returned", "waiting_stable");
|
|
51
54
|
object compile; object requested; object observed; object diagnostics; object errorCount; object warningCount; object infoCount; object truncated; object stableFrames;
|
|
52
55
|
if (!root.TryGetValue("compile", out compile) || !(compile is bool)
|
|
53
56
|
|| !root.TryGetValue("compilationRequested", out requested) || !(requested is bool)
|
|
54
57
|
|| !root.TryGetValue("compilationObserved", out observed) || !(observed is bool)
|
|
55
58
|
|| !root.TryGetValue("compileDiagnostics", out diagnostics) || !(diagnostics is List<object>)
|
|
56
|
-
|| !root.TryGetValue("compileErrorCount", out errorCount) || !(errorCount is long) || (long)errorCount <
|
|
57
|
-
|| !root.TryGetValue("compileWarningCount", out warningCount) || !(warningCount is long) || (long)warningCount <
|
|
58
|
-
|| !root.TryGetValue("compileInfoCount", out infoCount) || !(infoCount is long) || (long)infoCount <
|
|
59
|
-
|| !root.TryGetValue("compileDiagnosticsTruncated", out truncated) || !(truncated is long) || (long)truncated <
|
|
60
|
-
|| !root.TryGetValue("stableFrames", out stableFrames) || !(stableFrames is long) || (long)stableFrames <
|
|
61
|
-
|| !
|
|
59
|
+
|| !root.TryGetValue("compileErrorCount", out errorCount) || !(errorCount is long) || (long)errorCount < 0L || (long)errorCount > 1000000L
|
|
60
|
+
|| !root.TryGetValue("compileWarningCount", out warningCount) || !(warningCount is long) || (long)warningCount < 0L || (long)warningCount > 1000000L
|
|
61
|
+
|| !root.TryGetValue("compileInfoCount", out infoCount) || !(infoCount is long) || (long)infoCount < 0L || (long)infoCount > 1000000L
|
|
62
|
+
|| !root.TryGetValue("compileDiagnosticsTruncated", out truncated) || !(truncated is long) || (long)truncated < 0L || (long)truncated > 1000000L
|
|
63
|
+
|| !root.TryGetValue("stableFrames", out stableFrames) || !(stableFrames is long) || (long)stableFrames < 0L
|
|
64
|
+
|| !(root["beforeDependencyGeneration"] is long) || (long)root["beforeDependencyGeneration"] < 0L
|
|
65
|
+
|| !(root["beforeProcessedGeneration"] is long) || (long)root["beforeProcessedGeneration"] < 0L
|
|
66
|
+
|| !(root["importObserved"] is bool))
|
|
62
67
|
throw new InvalidDataException("Refresh active root fields are invalid.");
|
|
63
|
-
if (!string.Equals(Text(root, "rootContractDigest"), RefreshRootContractDigest(root), StringComparison.Ordinal))
|
|
64
|
-
throw new InvalidDataException("Refresh immutable root contract changed.");
|
|
68
|
+
if (!string.Equals(Text(root, "rootContractDigest"), RefreshRootContractDigest(root), StringComparison.Ordinal)) throw new InvalidDataException("Refresh immutable root contract changed.");
|
|
65
69
|
UnityCliCompileCoordinator.ValidateBoundedDiagnostics(root, "compileDiagnostics", "compileErrorCount", "compileWarningCount", "compileInfoCount", "compileDiagnosticsTruncated", true);
|
|
66
70
|
var compilePhase = Text(root, "compilePhase");
|
|
67
|
-
if (Array.IndexOf(new[] { "idle", "dispatching", "awaiting_started", "compiling", "cycle_finished" }, compilePhase) < 0)
|
|
68
|
-
throw new InvalidDataException("Refresh compile phase is invalid.");
|
|
71
|
+
if (Array.IndexOf(new[] { "idle", "dispatching", "awaiting_started", "compiling", "cycle_finished" }, compilePhase) < 0) throw new InvalidDataException("Refresh compile phase is invalid.");
|
|
69
72
|
var refreshFenced = HasExactEffectFence("refresh", root, "refresh-dispatch");
|
|
70
73
|
var phase = Text(root, "phase");
|
|
71
|
-
if ((phase == "queued" || phase == "prepared") == refreshFenced)
|
|
72
|
-
throw new InvalidDataException("Refresh effect fence is inconsistent with phase.");
|
|
74
|
+
if ((phase == "queued" || phase == "prepared") == refreshFenced) throw new InvalidDataException("Refresh effect fence is inconsistent with phase.");
|
|
73
75
|
var compileFenced = HasExactEffectFence("refresh", root, "compile-dispatch");
|
|
74
|
-
if ((compilePhase == "idle") == compileFenced)
|
|
75
|
-
|
|
76
|
-
if (Bool(root, "compilationObserved")
|
|
77
|
-
&& (Long(root, "compileStartedCycle") <= 0 || Long(root, "compileStartedSequence") <= Long(root, "compileDispatchSequence")))
|
|
76
|
+
if ((compilePhase == "idle") == compileFenced) throw new InvalidDataException("Refresh compile fence is inconsistent with phase.");
|
|
77
|
+
if (Bool(root, "compilationObserved") && (Long(root, "compileStartedCycle") <= 0L || Long(root, "compileStartedSequence") <= Long(root, "compileDispatchSequence")))
|
|
78
78
|
throw new InvalidDataException("Refresh compile attribution is invalid.");
|
|
79
79
|
}
|
|
80
80
|
|
|
@@ -82,7 +82,7 @@ namespace UnityCli
|
|
|
82
82
|
{
|
|
83
83
|
return UnityCliSerializer.Sha256Canonical(new Dictionary<string, object>
|
|
84
84
|
{
|
|
85
|
-
{ "compile", root["compile"] }, { "
|
|
85
|
+
{ "compile", root["compile"] }, { "beforeDependencyGeneration", root["beforeDependencyGeneration"] }, { "beforeProcessedGeneration", root["beforeProcessedGeneration"] }
|
|
86
86
|
});
|
|
87
87
|
}
|
|
88
88
|
|
|
@@ -93,69 +93,103 @@ namespace UnityCli
|
|
|
93
93
|
if (args.Compile) effects.Add(new Dictionary<string, object> { { "type", "script-compile" } });
|
|
94
94
|
return new Dictionary<string, object> { { "dryRun", true }, { "plannedEffects", effects } };
|
|
95
95
|
}
|
|
96
|
+
|
|
96
97
|
protected override Dictionary<string, object> CreateRoot(BridgeRequest request, string digest, object value)
|
|
97
98
|
{
|
|
98
99
|
var args = (Args)value;
|
|
99
100
|
var before = CaptureProof();
|
|
100
|
-
var root = new Dictionary<string, object>
|
|
101
|
+
var root = new Dictionary<string, object>
|
|
102
|
+
{
|
|
103
|
+
{ "requestId", request.RequestId }, { "editorSessionId", EditorSessionId() }, { "requestDigest", digest }, { "deadline", request.Execution.AbsoluteDeadlineUtc },
|
|
104
|
+
{ "phase", "queued" }, { "compile", args.Compile }, { "compilationRequested", false }, { "compilationObserved", false }, { "compilePhase", "idle" },
|
|
105
|
+
{ "compileDispatchSequence", 0L }, { "compileStartedSequence", 0L }, { "compileFinishedSequence", 0L }, { "compileStartedCycle", 0L },
|
|
106
|
+
{ "compileDiagnostics", new List<object>() }, { "compileErrorCount", 0L }, { "compileWarningCount", 0L }, { "compileInfoCount", 0L }, { "compileDiagnosticsTruncated", 0L },
|
|
107
|
+
{ "stableFrames", 0L }, { "beforeDependencyGeneration", before.DependencyGeneration }, { "beforeProcessedGeneration", before.ProcessedGeneration },
|
|
108
|
+
{ "importObserved", false }, { "reloadObserved", false }
|
|
109
|
+
};
|
|
101
110
|
root["rootContractDigest"] = RefreshRootContractDigest(root);
|
|
102
111
|
return root;
|
|
103
112
|
}
|
|
113
|
+
|
|
104
114
|
protected override void OnTick(Dictionary<string, object> root)
|
|
105
115
|
{
|
|
106
116
|
if (UnityCliCompilationEventBroker.SequenceCorrupt && Bool(root, "compile")) { Fail(root, "E_EXECUTION_TIMEOUT", "Refresh compilation event sequence is corrupt; attributed outcome is unknown."); return; }
|
|
107
117
|
var phase = Text(root, "phase");
|
|
108
|
-
if (phase
|
|
109
|
-
if (phase == "
|
|
118
|
+
if (phase != "queued" && phase != "prepared") ObserveImport(root);
|
|
119
|
+
if (phase == "queued") { if (BusyEditor()) return; Update(value => value["phase"] = "prepared"); return; }
|
|
120
|
+
if (phase == "prepared")
|
|
121
|
+
{
|
|
122
|
+
root = CrossEffectFence(root, "refresh-dispatch", "dispatching");
|
|
123
|
+
try { AssetDatabase.Refresh(); Update(value => value["phase"] = "refresh_returned"); }
|
|
124
|
+
catch (Exception exception) { Fail(root, "E_EXECUTION_TIMEOUT", "Refresh result cannot be confirmed: " + exception.Message + "; inspect asset state."); }
|
|
125
|
+
return;
|
|
126
|
+
}
|
|
110
127
|
if (phase == "refresh_returned")
|
|
111
128
|
{
|
|
112
|
-
if (Bool(root, "compile") && !Bool(root, "compilationObserved") && !Bool(root, "compilationRequested"))
|
|
113
|
-
|
|
129
|
+
if (Bool(root, "compile") && !Bool(root, "compilationObserved") && !Bool(root, "compilationRequested"))
|
|
130
|
+
{
|
|
131
|
+
if (BusyEditor()) return;
|
|
132
|
+
UnityCliCompileCoordinator.RequestRefreshCompilation(Text(root, "requestId"), Text(root, "requestDigest"));
|
|
133
|
+
return;
|
|
134
|
+
}
|
|
135
|
+
Update(value => value["phase"] = "waiting_stable");
|
|
136
|
+
return;
|
|
114
137
|
}
|
|
115
138
|
if (phase != "waiting_stable" || BusyEditor()) return;
|
|
116
|
-
if (Bool(root, "compile") && (!Bool(root, "compilationObserved") || Text(root, "compilePhase") != "cycle_finished"))
|
|
117
|
-
|
|
139
|
+
if (Bool(root, "compile") && (!Bool(root, "compilationObserved") || Text(root, "compilePhase") != "cycle_finished"))
|
|
140
|
+
{
|
|
141
|
+
Fail(root, "E_EXECUTION_TIMEOUT", "Refresh compilation result cannot be confirmed; inspect editor.state and compile diagnostics.");
|
|
142
|
+
return;
|
|
143
|
+
}
|
|
144
|
+
if (Long(root, "compileErrorCount") > 0L)
|
|
118
145
|
{
|
|
119
146
|
var details = new Dictionary<string, object>
|
|
120
147
|
{
|
|
121
148
|
{ "compile", new Dictionary<string, object> { { "completed", true }, { "errorCount", Long(root, "compileErrorCount") }, { "warningCount", Long(root, "compileWarningCount") }, { "status", "errors" }, { "diagnosticsTruncated", Long(root, "compileDiagnosticsTruncated") } } },
|
|
122
149
|
{ "diagnostics", root["compileDiagnostics"] }
|
|
123
150
|
};
|
|
124
|
-
Fail(root, "E_UNITY_COMPILE_FAILED", "Refresh compilation reported compiler errors.", details, new[] { "Fix the listed compiler diagnostics before retrying refresh." });
|
|
151
|
+
Fail(root, "E_UNITY_COMPILE_FAILED", "Refresh compilation reported compiler errors.", details, new[] { "Fix the listed compiler diagnostics before retrying refresh." });
|
|
152
|
+
return;
|
|
125
153
|
}
|
|
126
|
-
var frames = Long(root, "stableFrames") +
|
|
154
|
+
var frames = Long(root, "stableFrames") + 1L;
|
|
155
|
+
Update(value => value["stableFrames"] = frames);
|
|
156
|
+
if (frames >= 3L) Succeed(root);
|
|
127
157
|
}
|
|
158
|
+
|
|
128
159
|
protected override object BuildSuccessData(Dictionary<string, object> root)
|
|
129
160
|
{
|
|
130
161
|
var after = CaptureProof();
|
|
131
|
-
var changed =
|
|
162
|
+
var changed = Long(root, "beforeDependencyGeneration") != after.DependencyGeneration || Long(root, "beforeProcessedGeneration") != after.ProcessedGeneration;
|
|
132
163
|
return new Dictionary<string, object>
|
|
133
164
|
{
|
|
134
|
-
{ "changed", changed }, { "compilationTriggered", Bool(root, "compilationObserved") },
|
|
135
|
-
{ "
|
|
165
|
+
{ "changed", changed }, { "importObserved", Bool(root, "importObserved") || changed }, { "compilationTriggered", Bool(root, "compilationObserved") },
|
|
166
|
+
{ "generation", new Dictionary<string, object> { { "dependencyBefore", Long(root, "beforeDependencyGeneration") }, { "dependencyAfter", after.DependencyGeneration }, { "processedBefore", Long(root, "beforeProcessedGeneration") }, { "processedAfter", after.ProcessedGeneration } } },
|
|
136
167
|
{ "editorState", new Dictionary<string, object> { { "status", "ready" }, { "compile", false }, { "import", false } } }
|
|
137
168
|
};
|
|
138
169
|
}
|
|
139
|
-
|
|
140
|
-
|
|
170
|
+
|
|
171
|
+
private void ObserveImport(Dictionary<string, object> root)
|
|
172
|
+
{
|
|
173
|
+
if (Bool(root, "importObserved")) return;
|
|
174
|
+
var current = CaptureProof();
|
|
175
|
+
if (!EditorApplication.isUpdating && Long(root, "beforeDependencyGeneration") == current.DependencyGeneration && Long(root, "beforeProcessedGeneration") == current.ProcessedGeneration) return;
|
|
176
|
+
root["importObserved"] = true;
|
|
177
|
+
Update(value => value["importObserved"] = true);
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
private sealed class Proof { internal long DependencyGeneration; internal long ProcessedGeneration; }
|
|
181
|
+
|
|
182
|
+
/// <summary>O(1) Unity-owned generation proof;不读取 Assets 文件,不计算 per-file dependency hash。</summary>
|
|
141
183
|
private static Proof CaptureProof()
|
|
142
184
|
{
|
|
143
|
-
|
|
144
|
-
var files = Directory.Exists(rootPath) ? Directory.GetFiles(rootPath, "*", SearchOption.AllDirectories).OrderBy(path => path, StringComparer.Ordinal).ToArray() : new string[0];
|
|
145
|
-
var lines = new List<string>(); var paths = new List<string>(); var dependencies = new List<string>();
|
|
146
|
-
foreach (var file in files)
|
|
185
|
+
return new Proof
|
|
147
186
|
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
lines.Add(relative + "\0" + info.Length.ToString(CultureInfo.InvariantCulture) + "\0" + info.LastWriteTimeUtc.Ticks.ToString(CultureInfo.InvariantCulture) + "\0" + HashFile(file));
|
|
152
|
-
if (!relative.EndsWith(".meta", StringComparison.OrdinalIgnoreCase)) dependencies.Add(relative + "\0" + AssetDatabase.GetAssetDependencyHash(relative).ToString());
|
|
153
|
-
}
|
|
154
|
-
return new Proof { Paths = paths, SourceFingerprint = Sha256Hex(Encoding.UTF8.GetBytes(string.Join("\n", lines))), DependencyVersion = Sha256Hex(Encoding.UTF8.GetBytes(string.Join("\n", dependencies))) };
|
|
187
|
+
DependencyGeneration = Math.Max(0L, (long)AssetDatabase.GlobalArtifactDependencyVersion),
|
|
188
|
+
ProcessedGeneration = Math.Max(0L, (long)AssetDatabase.GlobalArtifactProcessedVersion)
|
|
189
|
+
};
|
|
155
190
|
}
|
|
156
|
-
|
|
191
|
+
|
|
157
192
|
private static bool BusyEditor() { return EditorApplication.isUpdating || EditorApplication.isCompiling || BuildPipeline.isBuildingPlayer || IsPlayModeChanging(); }
|
|
158
|
-
private static bool Same(string left, string right) { return !string.IsNullOrEmpty(left) && string.Equals(left, right, StringComparison.Ordinal); }
|
|
159
193
|
private sealed class Args { public bool Compile { get; set; } public string ExpectedEditorSessionId { get; set; } }
|
|
160
194
|
}
|
|
161
195
|
}
|
|
@@ -77,13 +77,13 @@ namespace UnityCli
|
|
|
77
77
|
protected override string OperationDisplayName { get { return "NavMesh bake"; } }
|
|
78
78
|
protected override int CommandTimeoutMs { get { return 600000; } }
|
|
79
79
|
protected override bool IncludeAcceptedInStatus { get { return true; } }
|
|
80
|
-
protected override IEnumerable<(string name, bool destructive)> AdditionalCommands
|
|
80
|
+
protected override IEnumerable<(string name, bool destructive, UnityCliBridgeQueuePolicy.WorkClass queueClass)> AdditionalCommands
|
|
81
81
|
{
|
|
82
82
|
get
|
|
83
83
|
{
|
|
84
|
-
yield return (PlanCommand, false);
|
|
85
|
-
yield return (SnapshotCommand, false);
|
|
86
|
-
yield return (CancelCommand, true);
|
|
84
|
+
yield return (PlanCommand, false, UnityCliBridgeQueuePolicy.WorkClass.Mutation);
|
|
85
|
+
yield return (SnapshotCommand, false, UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead);
|
|
86
|
+
yield return (CancelCommand, true, UnityCliBridgeQueuePolicy.WorkClass.Control);
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
89
|
|
|
@@ -2,8 +2,6 @@
|
|
|
2
2
|
using System;
|
|
3
3
|
using System.Collections.Generic;
|
|
4
4
|
using System.Globalization;
|
|
5
|
-
using System.Linq;
|
|
6
|
-
using System.Reflection;
|
|
7
5
|
using UnityEditor;
|
|
8
6
|
using UnityEngine;
|
|
9
7
|
using UnityEngine.SceneManagement;
|
|
@@ -34,6 +32,7 @@ namespace UnityCli
|
|
|
34
32
|
List<string> Paths { get; }
|
|
35
33
|
object ViewQuery { get; }
|
|
36
34
|
string NamePattern { get; }
|
|
35
|
+
UnityCliReadBudgetInput Budget { get; }
|
|
37
36
|
}
|
|
38
37
|
|
|
39
38
|
public static partial class UnityCliBridge
|
|
@@ -45,13 +44,21 @@ namespace UnityCli
|
|
|
45
44
|
/// </summary>
|
|
46
45
|
internal static class ObjectRefResolver
|
|
47
46
|
{
|
|
47
|
+
internal const int AbsoluteMaxBatchItems = 4096;
|
|
48
|
+
private const int MaximumRootSnapshotItems = AbsoluteMaxBatchItems;
|
|
49
|
+
private const int MaximumComponentSnapshotItems = AbsoluteMaxBatchItems;
|
|
50
|
+
private const int MaximumRootSnapshotGenerations = 64;
|
|
51
|
+
private static readonly Dictionary<string, GameObject[]> RootSnapshots = new Dictionary<string, GameObject[]>(StringComparer.Ordinal);
|
|
52
|
+
|
|
48
53
|
/// <summary>解析任意 UnityEngine.Object 引用。</summary>
|
|
49
|
-
public static UnityEngine.Object ResolveObject(IUnityCliObjectReferenceInput request)
|
|
54
|
+
public static UnityEngine.Object ResolveObject(IUnityCliObjectReferenceInput request, UnityCliRequestBudget budget)
|
|
50
55
|
{
|
|
51
|
-
|
|
56
|
+
if (budget == null) throw new ArgumentNullException("budget");
|
|
57
|
+
// 优先级:instanceId > assetPath/guid > exact hierarchy path/name
|
|
52
58
|
var instanceId = request.InstanceId;
|
|
53
59
|
if (instanceId.HasValue && instanceId.Value != 0)
|
|
54
60
|
{
|
|
61
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
55
62
|
var obj = EditorUtility.InstanceIDToObject(instanceId.Value);
|
|
56
63
|
if (obj == null)
|
|
57
64
|
{
|
|
@@ -66,11 +73,13 @@ namespace UnityCli
|
|
|
66
73
|
var guid = request.Guid;
|
|
67
74
|
if (!string.IsNullOrEmpty(guid))
|
|
68
75
|
{
|
|
76
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
69
77
|
var pathByGuid = AssetDatabase.GUIDToAssetPath(guid);
|
|
70
78
|
if (!string.IsNullOrEmpty(pathByGuid)) assetPath = pathByGuid;
|
|
71
79
|
}
|
|
72
80
|
if (!string.IsNullOrEmpty(assetPath))
|
|
73
81
|
{
|
|
82
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
74
83
|
var asset = AssetDatabase.LoadMainAssetAtPath(assetPath);
|
|
75
84
|
if (asset == null)
|
|
76
85
|
{
|
|
@@ -81,19 +90,11 @@ namespace UnityCli
|
|
|
81
90
|
return asset;
|
|
82
91
|
}
|
|
83
92
|
|
|
84
|
-
// 名称/路径解析:优先在活动场景中找 GameObject,再回退资产
|
|
85
93
|
var path = request.Path ?? request.Name ?? request.Target;
|
|
86
94
|
if (!string.IsNullOrEmpty(path))
|
|
87
95
|
{
|
|
88
|
-
var
|
|
89
|
-
if (
|
|
90
|
-
|
|
91
|
-
var assetByName = AssetDatabase.FindAssets(path);
|
|
92
|
-
if (assetByName != null && assetByName.Length > 0)
|
|
93
|
-
{
|
|
94
|
-
var resolved = AssetDatabase.LoadMainAssetAtPath(AssetDatabase.GUIDToAssetPath(assetByName[0]));
|
|
95
|
-
if (resolved != null) return resolved;
|
|
96
|
-
}
|
|
96
|
+
var gameObject = FindGameObjectByExactPath(path, budget);
|
|
97
|
+
if (gameObject != null) return gameObject;
|
|
97
98
|
}
|
|
98
99
|
|
|
99
100
|
throw new BridgeCommandException("E_OBJECTREF_REQUIRED",
|
|
@@ -102,11 +103,13 @@ namespace UnityCli
|
|
|
102
103
|
}
|
|
103
104
|
|
|
104
105
|
/// <summary>解析 GameObject 引用。</summary>
|
|
105
|
-
public static GameObject ResolveGameObject(IUnityCliObjectReferenceInput request)
|
|
106
|
+
public static GameObject ResolveGameObject(IUnityCliObjectReferenceInput request, UnityCliRequestBudget budget)
|
|
106
107
|
{
|
|
108
|
+
if (budget == null) throw new ArgumentNullException("budget");
|
|
107
109
|
var instanceId = request.InstanceId;
|
|
108
110
|
if (instanceId.HasValue && instanceId.Value != 0)
|
|
109
111
|
{
|
|
112
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
110
113
|
var obj = EditorUtility.InstanceIDToObject(instanceId.Value) as GameObject;
|
|
111
114
|
if (obj == null)
|
|
112
115
|
{
|
|
@@ -120,7 +123,7 @@ namespace UnityCli
|
|
|
120
123
|
var path = request.Path ?? request.Target ?? request.Name;
|
|
121
124
|
if (!string.IsNullOrEmpty(path))
|
|
122
125
|
{
|
|
123
|
-
var go =
|
|
126
|
+
var go = FindGameObjectByExactPath(path, budget);
|
|
124
127
|
if (go != null) return go;
|
|
125
128
|
throw new BridgeCommandException("E_OBJECTREF_GAMEOBJECT_REQUIRED",
|
|
126
129
|
"No GameObject matched path/name '" + path + "' in any loaded scene.",
|
|
@@ -138,11 +141,13 @@ namespace UnityCli
|
|
|
138
141
|
/// 2) GameObject + component index
|
|
139
142
|
/// 3) GameObject + component typeName
|
|
140
143
|
/// </summary>
|
|
141
|
-
public static Component ResolveComponent(IUnityCliObjectReferenceInput request)
|
|
144
|
+
public static Component ResolveComponent(IUnityCliObjectReferenceInput request, UnityCliRequestBudget budget)
|
|
142
145
|
{
|
|
146
|
+
if (budget == null) throw new ArgumentNullException("budget");
|
|
143
147
|
var componentInstanceId = request.ComponentInstanceId;
|
|
144
148
|
if (componentInstanceId.HasValue && componentInstanceId.Value != 0)
|
|
145
149
|
{
|
|
150
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
146
151
|
var obj = EditorUtility.InstanceIDToObject(componentInstanceId.Value) as Component;
|
|
147
152
|
if (obj == null)
|
|
148
153
|
{
|
|
@@ -153,11 +158,11 @@ namespace UnityCli
|
|
|
153
158
|
return obj;
|
|
154
159
|
}
|
|
155
160
|
|
|
156
|
-
var gameObject = ResolveGameObject(request);
|
|
161
|
+
var gameObject = ResolveGameObject(request, budget);
|
|
157
162
|
var componentIndex = request.ComponentIndex;
|
|
158
163
|
if (componentIndex.HasValue)
|
|
159
164
|
{
|
|
160
|
-
var components = gameObject
|
|
165
|
+
var components = BoundedComponents(gameObject, budget);
|
|
161
166
|
if (componentIndex.Value < 0 || componentIndex.Value >= components.Length)
|
|
162
167
|
{
|
|
163
168
|
throw new BridgeCommandException("E_OBJECTREF_COMPONENT_INDEX_OUT_OF_RANGE",
|
|
@@ -170,7 +175,8 @@ namespace UnityCli
|
|
|
170
175
|
var componentType = request.Component ?? request.ComponentType;
|
|
171
176
|
if (!string.IsNullOrEmpty(componentType))
|
|
172
177
|
{
|
|
173
|
-
var type = ResolveComponentType(componentType);
|
|
178
|
+
var type = GameObjectToolSupport.ResolveComponentType(componentType, budget);
|
|
179
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
174
180
|
var component = gameObject.GetComponent(type);
|
|
175
181
|
if (component == null)
|
|
176
182
|
{
|
|
@@ -186,6 +192,99 @@ namespace UnityCli
|
|
|
186
192
|
"Run component.get --input '{\"instanceId\":123,\"component\":\"Transform\"}'.");
|
|
187
193
|
}
|
|
188
194
|
|
|
195
|
+
/// <summary>按完整大小写敏感路径直接逐段解析;不会在失败时扫描整棵层级树。</summary>
|
|
196
|
+
public static GameObject FindGameObjectByExactPath(string path, UnityCliRequestBudget budget)
|
|
197
|
+
{
|
|
198
|
+
if (string.IsNullOrEmpty(path)) return null;
|
|
199
|
+
if (budget == null) throw new ArgumentNullException("budget");
|
|
200
|
+
if (path.Length > 8192) throw new BridgeCommandException("E_OBJECTREF_PATH_INVALID", "Exact hierarchy paths are limited to 8192 characters.", "Pass a shorter full case-sensitive hierarchy path or an instance id.");
|
|
201
|
+
var segments = path.Split(new[] { '/' }, StringSplitOptions.RemoveEmptyEntries);
|
|
202
|
+
if (segments.Length == 0) return null;
|
|
203
|
+
if (segments.Length > 256) throw new BridgeCommandException("E_OBJECTREF_PATH_INVALID", "Exact hierarchy paths are limited to 256 segments.", "Pass an instance id for deeper objects.");
|
|
204
|
+
GameObject match = null;
|
|
205
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
206
|
+
var sceneCount = SceneManager.sceneCount;
|
|
207
|
+
for (var sceneIndex = 0; sceneIndex < sceneCount; sceneIndex++)
|
|
208
|
+
{
|
|
209
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
210
|
+
var scene = SceneManager.GetSceneAt(sceneIndex);
|
|
211
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
212
|
+
if (!scene.isLoaded) continue;
|
|
213
|
+
foreach (var root in BoundedSceneRoots(scene, budget))
|
|
214
|
+
{
|
|
215
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
216
|
+
if (!string.Equals(root.name, segments[0], StringComparison.Ordinal)) continue;
|
|
217
|
+
var current = root.transform;
|
|
218
|
+
var resolved = true;
|
|
219
|
+
for (var segmentIndex = 1; segmentIndex < segments.Length; segmentIndex++)
|
|
220
|
+
{
|
|
221
|
+
Transform childMatch = null;
|
|
222
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
223
|
+
var childCount = current.childCount;
|
|
224
|
+
for (var childIndex = 0; childIndex < childCount; childIndex++)
|
|
225
|
+
{
|
|
226
|
+
if (!budget.TryConsumeScannedRecord() || !budget.TryConsumeGetter() || !budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
227
|
+
var child = current.GetChild(childIndex);
|
|
228
|
+
if (!string.Equals(child.name, segments[segmentIndex], StringComparison.Ordinal)) continue;
|
|
229
|
+
if (childMatch != null) ThrowExactAmbiguousPath(path, childMatch.gameObject, child.gameObject, budget);
|
|
230
|
+
childMatch = child;
|
|
231
|
+
}
|
|
232
|
+
if (childMatch == null) { resolved = false; break; }
|
|
233
|
+
current = childMatch;
|
|
234
|
+
}
|
|
235
|
+
if (!resolved) continue;
|
|
236
|
+
if (match != null) ThrowExactAmbiguousPath(path, match, current.gameObject, budget);
|
|
237
|
+
match = current.gameObject;
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
return match;
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
/// <summary>批量根对象 getter 只在已验证 cardinality 后调用,并在同一层级 generation 复用有限快照。</summary>
|
|
244
|
+
internal static GameObject[] BoundedSceneRoots(Scene scene, UnityCliRequestBudget budget)
|
|
245
|
+
{
|
|
246
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
247
|
+
var rootCount = scene.rootCount;
|
|
248
|
+
if (rootCount < 0 || rootCount > MaximumRootSnapshotItems || !budget.TryConsumeScannedRecords(rootCount))
|
|
249
|
+
throw new UnityCliRequestBudgetExceededException(rootCount > MaximumRootSnapshotItems ? "rootSnapshotItems" : budget.ExhaustedDimension);
|
|
250
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
251
|
+
var generation = UnityCliReadGeneration.Hierarchy(scene);
|
|
252
|
+
GameObject[] cached;
|
|
253
|
+
if (RootSnapshots.TryGetValue(generation, out cached))
|
|
254
|
+
{
|
|
255
|
+
if (cached.Length != rootCount) throw new BridgeCommandException("E_READ_GENERATION_CHANGED", "Scene roots changed while resolving the exact path.", "Retry the read from the beginning.");
|
|
256
|
+
return cached;
|
|
257
|
+
}
|
|
258
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
259
|
+
var roots = scene.GetRootGameObjects();
|
|
260
|
+
if (roots.Length != rootCount) throw new BridgeCommandException("E_READ_GENERATION_CHANGED", "Scene roots changed while building the bounded snapshot.", "Retry the read from the beginning.");
|
|
261
|
+
if (RootSnapshots.Count >= MaximumRootSnapshotGenerations) RootSnapshots.Clear();
|
|
262
|
+
RootSnapshots[generation] = roots;
|
|
263
|
+
return roots;
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
/// <summary>组件数组在 materialize 前验证数量并一次性占用扫描预算。</summary>
|
|
267
|
+
internal static Component[] BoundedComponents(GameObject gameObject, UnityCliRequestBudget budget)
|
|
268
|
+
{
|
|
269
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
270
|
+
var componentCount = gameObject.GetComponentCount();
|
|
271
|
+
if (componentCount < 0 || componentCount > MaximumComponentSnapshotItems || !budget.TryConsumeScannedRecords(componentCount))
|
|
272
|
+
throw new UnityCliRequestBudgetExceededException(componentCount > MaximumComponentSnapshotItems ? "componentSnapshotItems" : budget.ExhaustedDimension);
|
|
273
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
274
|
+
var components = gameObject.GetComponents<Component>();
|
|
275
|
+
if (components.Length != componentCount) throw new BridgeCommandException("E_READ_GENERATION_CHANGED", "GameObject components changed while building the bounded snapshot.", "Retry the read from the beginning.");
|
|
276
|
+
return components;
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
private static void ThrowExactAmbiguousPath(string path, GameObject first, GameObject second, UnityCliRequestBudget budget)
|
|
280
|
+
{
|
|
281
|
+
var firstPath = UnityCliHierarchyPager.Path(first, budget);
|
|
282
|
+
var secondPath = UnityCliHierarchyPager.Path(second, budget);
|
|
283
|
+
throw new BridgeCommandException("E_OBJECTREF_AMBIGUOUS",
|
|
284
|
+
"Path '" + path + "' matches multiple GameObjects: " + firstPath + ", " + secondPath,
|
|
285
|
+
"Pass the instanceId from go.find to disambiguate objects in different loaded scenes.");
|
|
286
|
+
}
|
|
287
|
+
|
|
189
288
|
/// <summary>
|
|
190
289
|
/// 按路径或名称查找 GameObject,分层匹配:
|
|
191
290
|
/// 层1 精确匹配(从场景顶层起、大小写敏感)→ 层2 放宽匹配(任意层级起点、路径后缀、忽略大小写)。
|
|
@@ -263,11 +362,15 @@ namespace UnityCli
|
|
|
263
362
|
// 多命中时抛歧义错误,列候选完整路径(从顶层起),不静默取错。
|
|
264
363
|
private static void ThrowAmbiguousPath(string path, List<GameObject> matches)
|
|
265
364
|
{
|
|
266
|
-
var candidates =
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
.
|
|
365
|
+
var candidates = new List<string>();
|
|
366
|
+
var seen = new HashSet<string>(StringComparer.Ordinal);
|
|
367
|
+
foreach (var match in matches)
|
|
368
|
+
{
|
|
369
|
+
var candidate = FullPath(match.transform);
|
|
370
|
+
if (!seen.Add(candidate)) continue;
|
|
371
|
+
candidates.Add(candidate);
|
|
372
|
+
if (candidates.Count == 10) break;
|
|
373
|
+
}
|
|
271
374
|
throw new BridgeCommandException("E_OBJECTREF_AMBIGUOUS",
|
|
272
375
|
"Path '" + path + "' matches " + matches.Count + " GameObjects: " + string.Join(", ", candidates),
|
|
273
376
|
"Pass the full hierarchy path from a scene root, or use go.find to obtain the instanceId.");
|