@alpsckr/unitycli 0.4.3 → 0.4.5
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 +145 -39
- package/dist/bridge/session-supervisor.js.map +1 -1
- package/dist/bridge/start-diagnostics.d.ts +19 -0
- package/dist/bridge/start-diagnostics.js +96 -0
- package/dist/bridge/start-diagnostics.js.map +1 -0
- 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-commands/package.js +10 -2
- package/dist/cli-commands/package.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 +451 -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 +57 -5
- package/dist/extensions/installer.js +263 -64
- 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 +19 -1
- package/dist/instances.js +39 -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 +11 -2
- 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,42 +1,39 @@
|
|
|
1
1
|
#if UNITY_EDITOR
|
|
2
2
|
using System;
|
|
3
3
|
using System.Collections.Generic;
|
|
4
|
-
using System.
|
|
4
|
+
using System.Globalization;
|
|
5
|
+
using UnityEditor;
|
|
5
6
|
using UnityEngine;
|
|
6
7
|
using UnityEngine.SceneManagement;
|
|
7
8
|
|
|
8
9
|
namespace UnityCli
|
|
9
10
|
{
|
|
10
|
-
/// <summary>
|
|
11
|
-
/// scene.hierarchy — 读取激活场景的轻量分页层级:parent/深度/名称过滤/组件预览。
|
|
12
|
-
/// </summary>
|
|
11
|
+
/// <summary>scene.hierarchy — 以 next raw GameObject 为游标的有界前序层级读取。</summary>
|
|
13
12
|
public class SceneHierarchyTool : IUnityCliTool<SceneHierarchyTool.Request, SceneHierarchyTool.Result>
|
|
14
13
|
{
|
|
15
14
|
public sealed class Request
|
|
16
15
|
{
|
|
17
|
-
public int? PageSize { get; set; }
|
|
18
|
-
public
|
|
16
|
+
[UnityCliRange(1L, 500L)] public int? PageSize { get; set; }
|
|
17
|
+
public string Cursor { get; set; }
|
|
19
18
|
public string Parent { get; set; }
|
|
20
|
-
public int? MaxDepth { get; set; }
|
|
19
|
+
[UnityCliRange(0L, 16L)] public int? MaxDepth { get; set; }
|
|
21
20
|
public string Query { get; set; }
|
|
22
21
|
public string NameFilter { get; set; }
|
|
23
22
|
public string ComponentType { get; set; }
|
|
24
23
|
public bool IncludeComponents { get; set; }
|
|
25
24
|
public bool IncludeInactive { get; set; }
|
|
25
|
+
public UnityCliReadBudgetInput Budget { get; set; }
|
|
26
26
|
}
|
|
27
27
|
|
|
28
28
|
public sealed class Result
|
|
29
29
|
{
|
|
30
30
|
public SceneSummary Scene { get; set; }
|
|
31
|
-
public List<HierarchyItem> Items { get; set; }
|
|
31
|
+
[UnityCliItemsRange(0, 500)] public List<HierarchyItem> Items { get; set; }
|
|
32
32
|
public PageInfo PageInfo { get; set; }
|
|
33
|
+
public UnityCliRequestBudgetUsage Budget { get; set; }
|
|
33
34
|
}
|
|
34
35
|
|
|
35
|
-
public sealed class SceneSummary
|
|
36
|
-
{
|
|
37
|
-
public string Name { get; set; }
|
|
38
|
-
public string Path { get; set; }
|
|
39
|
-
}
|
|
36
|
+
public sealed class SceneSummary { public string Name { get; set; } public string Path { get; set; } }
|
|
40
37
|
|
|
41
38
|
public sealed class HierarchyItem
|
|
42
39
|
{
|
|
@@ -50,28 +47,28 @@ namespace UnityCli
|
|
|
50
47
|
public long Layer { get; set; }
|
|
51
48
|
public long ChildCount { get; set; }
|
|
52
49
|
public bool ChildrenTruncated { get; set; }
|
|
53
|
-
public long ComponentCount { get; set; }
|
|
54
|
-
public List<string> ComponentTypes { get; set; }
|
|
55
|
-
public List<string> Components { get; set; }
|
|
50
|
+
public long? ComponentCount { get; set; }
|
|
51
|
+
[UnityCliItemsRange(0, UnityCliBridge.ObjectRefResolver.AbsoluteMaxBatchItems)] public List<string> ComponentTypes { get; set; }
|
|
52
|
+
[UnityCliItemsRange(0, UnityCliBridge.ObjectRefResolver.AbsoluteMaxBatchItems)] public List<string> Components { get; set; }
|
|
56
53
|
}
|
|
57
54
|
|
|
58
55
|
public sealed class PageInfo
|
|
59
56
|
{
|
|
60
|
-
public long Total { get; set; }
|
|
61
|
-
public long TotalCount { get; set; }
|
|
62
57
|
public long ReturnedCount { get; set; }
|
|
63
58
|
public long PageSize { get; set; }
|
|
64
|
-
public
|
|
65
|
-
public
|
|
59
|
+
public string Cursor { get; set; }
|
|
60
|
+
public string NextCursor { get; set; }
|
|
66
61
|
public bool HasMore { get; set; }
|
|
62
|
+
public bool Complete { get; set; }
|
|
67
63
|
public bool Truncated { get; set; }
|
|
64
|
+
public string Generation { get; set; }
|
|
68
65
|
}
|
|
69
66
|
|
|
70
67
|
public ToolDescriptor Describe() => new()
|
|
71
68
|
{
|
|
72
69
|
Name = "scene.hierarchy",
|
|
73
|
-
Summary = "Read a lightweight, paged hierarchy
|
|
74
|
-
Description = "Read a lightweight
|
|
70
|
+
Summary = "Read a lightweight, paged active scene hierarchy from stable raw GameObject positions.",
|
|
71
|
+
Description = "Read a lightweight active-scene hierarchy in Edit or Play mode. Use parent for one subtree, maxDepth to limit recursion, query/name/component filters to narrow results, and includeComponents only when component previews are needed. Read one selected object with scene.gameobject; use object.get-data or component.get for deep fields. pageSize is 1..500 (default 50), maxDepth is 0..16 (default 1), each page scans only forward from nextCursor, pageInfo never fabricates a filtered total, and old generations return E_CONTINUATION_STALE. All pages share scan/node/getter/reflection/time/UTF-8 budgets.",
|
|
75
72
|
Group = "scene",
|
|
76
73
|
DestructiveHint = false,
|
|
77
74
|
Target = "editor",
|
|
@@ -80,169 +77,176 @@ namespace UnityCli
|
|
|
80
77
|
MaxTimeoutMs = 600000,
|
|
81
78
|
Examples = new[]
|
|
82
79
|
{
|
|
83
|
-
new ToolExample { Description = "List
|
|
80
|
+
new ToolExample { Description = "List one hierarchy page", Input = new Request { PageSize = 25, MaxDepth = 1 } },
|
|
84
81
|
new ToolExample { Description = "Find camera nodes by component type", Input = new Request { ComponentType = "Camera", PageSize = 10 } }
|
|
85
82
|
}
|
|
86
83
|
};
|
|
87
84
|
|
|
88
85
|
public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
|
|
89
86
|
{
|
|
87
|
+
request = request ?? new Request();
|
|
88
|
+
var budget = ctx.UseReadBudget(request.Budget);
|
|
89
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
90
90
|
var scene = SceneManager.GetActiveScene();
|
|
91
|
-
|
|
92
|
-
var
|
|
93
|
-
var
|
|
94
|
-
|
|
95
|
-
var
|
|
96
|
-
|
|
97
|
-
var cursor = Math.Max(0, request.Cursor ?? 0);
|
|
98
|
-
var pageSize = Math.Max(1, Math.Min(request.PageSize ?? 50, 500));
|
|
99
|
-
|
|
100
|
-
var roots = new List<GameObject>();
|
|
101
|
-
if (!string.IsNullOrEmpty(parent))
|
|
91
|
+
if (!budget.TryConsumeGetter() || !budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
92
|
+
var sceneName = scene.name;
|
|
93
|
+
var scenePath = scene.path;
|
|
94
|
+
if (!budget.TryReserveSerializedUtf8(sceneName) || !budget.TryReserveSerializedUtf8(scenePath)) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
95
|
+
var parent = ResolveParent(request.Parent, budget);
|
|
96
|
+
if (parent != null)
|
|
102
97
|
{
|
|
103
|
-
|
|
104
|
-
if (
|
|
105
|
-
|
|
106
|
-
throw new UnityCliBridge.BridgeCommandException("E_SCENE_HIERARCHY_PARENT_NOT_FOUND", "Parent GameObject not found: " + parent, "Run go.find or scene.hierarchy without parent, then pass a stable hierarchy path or instance id.");
|
|
107
|
-
}
|
|
108
|
-
for (var i = 0; i < parentObject.transform.childCount; i++)
|
|
109
|
-
{
|
|
110
|
-
roots.Add(parentObject.transform.GetChild(i).gameObject);
|
|
111
|
-
}
|
|
98
|
+
if (!budget.TryConsumeGetters(2)) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
99
|
+
if (parent.scene.handle != scene.handle)
|
|
100
|
+
throw new UnityCliBridge.BridgeCommandException("E_SCENE_HIERARCHY_PARENT_NOT_FOUND", "Parent is not in the active scene: " + request.Parent, "Pass an exact active-scene hierarchy path or instance id.");
|
|
112
101
|
}
|
|
102
|
+
var maxDepth = request.MaxDepth ?? 1;
|
|
103
|
+
var pageSize = request.PageSize ?? 50;
|
|
104
|
+
var query = request.Query ?? request.NameFilter;
|
|
105
|
+
if (parent != null && !budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
106
|
+
var selector = (parent == null ? "root" : parent.GetInstanceID().ToString(CultureInfo.InvariantCulture)) + "\0" + maxDepth.ToString(CultureInfo.InvariantCulture)
|
|
107
|
+
+ "\0" + query + "\0" + request.ComponentType + "\0" + request.IncludeInactive + "\0" + request.IncludeComponents;
|
|
108
|
+
var generation = UnityCliContinuationToken.Fingerprint(UnityCliReadGeneration.Hierarchy(scene) + "\0" + selector);
|
|
109
|
+
var traversal = new UnityCliHierarchyPager.Traversal(scene, parent, maxDepth, budget);
|
|
110
|
+
GameObject current;
|
|
111
|
+
if (string.IsNullOrEmpty(request.Cursor)) current = traversal.First(budget);
|
|
113
112
|
else
|
|
114
113
|
{
|
|
115
|
-
|
|
114
|
+
current = UnityCliHierarchyPager.ResolveCursor(request.Cursor, "scene.hierarchy", generation, budget, out var phase);
|
|
115
|
+
if (!budget.TryConsumeGetters(parent == null ? 2 : 3)) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
116
|
+
if (phase != "scene" || current.scene.handle != scene.handle || !WithinBoundary(current.transform, parent == null ? null : parent.transform, maxDepth, budget))
|
|
117
|
+
throw UnityCliHierarchyPager.Stale();
|
|
116
118
|
}
|
|
117
119
|
|
|
118
|
-
var
|
|
119
|
-
|
|
120
|
+
var items = new List<HierarchyItem>();
|
|
121
|
+
while (current != null && items.Count < pageSize)
|
|
120
122
|
{
|
|
121
|
-
|
|
123
|
+
var candidate = current;
|
|
124
|
+
if (!budget.TryConsumeScannedRecord()) break;
|
|
125
|
+
try
|
|
126
|
+
{
|
|
127
|
+
var next = traversal.Next(candidate, budget);
|
|
128
|
+
if (Matches(candidate, query, request.ComponentType, request.IncludeInactive, budget))
|
|
129
|
+
items.Add(BuildItem(candidate.transform, parent, request.IncludeComponents, budget));
|
|
130
|
+
current = next;
|
|
131
|
+
}
|
|
132
|
+
catch (UnityCliRequestBudgetExceededException)
|
|
133
|
+
{
|
|
134
|
+
current = candidate;
|
|
135
|
+
break;
|
|
136
|
+
}
|
|
122
137
|
}
|
|
123
138
|
|
|
124
|
-
|
|
125
|
-
var
|
|
139
|
+
if (items.Count == 0 && current != null) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension ?? "scannedRecords");
|
|
140
|
+
var nextCursor = UnityCliHierarchyPager.Cursor("scene.hierarchy", generation, "scene", current, budget);
|
|
126
141
|
return new System.Threading.Tasks.ValueTask<Result>(new Result
|
|
127
142
|
{
|
|
128
|
-
Scene = new SceneSummary { Name =
|
|
129
|
-
Items =
|
|
130
|
-
PageInfo =
|
|
143
|
+
Scene = new SceneSummary { Name = sceneName, Path = scenePath },
|
|
144
|
+
Items = items,
|
|
145
|
+
PageInfo = new PageInfo
|
|
146
|
+
{
|
|
147
|
+
ReturnedCount = items.Count,
|
|
148
|
+
PageSize = pageSize,
|
|
149
|
+
Cursor = request.Cursor,
|
|
150
|
+
NextCursor = nextCursor,
|
|
151
|
+
HasMore = nextCursor != null,
|
|
152
|
+
Complete = nextCursor == null,
|
|
153
|
+
Truncated = nextCursor != null,
|
|
154
|
+
Generation = generation
|
|
155
|
+
},
|
|
156
|
+
Budget = budget.Usage()
|
|
131
157
|
});
|
|
132
158
|
}
|
|
133
159
|
|
|
134
|
-
|
|
135
|
-
private static void CollectHierarchy(Transform transform, List<HierarchyItem> items, int depth, int maxDepth, string query, bool includeInactive, bool includeComponents, string componentType)
|
|
160
|
+
private static GameObject ResolveParent(string parent, UnityCliRequestBudget budget)
|
|
136
161
|
{
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
{
|
|
142
|
-
items.Add(BuildHierarchyItem(transform, depth, includeComponents));
|
|
143
|
-
}
|
|
144
|
-
}
|
|
145
|
-
if (depth >= maxDepth)
|
|
146
|
-
{
|
|
147
|
-
return;
|
|
148
|
-
}
|
|
149
|
-
foreach (Transform child in transform)
|
|
162
|
+
if (string.IsNullOrEmpty(parent)) return null;
|
|
163
|
+
int instanceId;
|
|
164
|
+
GameObject value = null;
|
|
165
|
+
if (int.TryParse(parent, NumberStyles.Integer, CultureInfo.InvariantCulture, out instanceId))
|
|
150
166
|
{
|
|
151
|
-
|
|
167
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
168
|
+
value = EditorUtility.InstanceIDToObject(instanceId) as GameObject;
|
|
152
169
|
}
|
|
170
|
+
else value = UnityCliBridge.ObjectRefResolver.FindGameObjectByExactPath(parent, budget);
|
|
171
|
+
if (value == null) throw new UnityCliBridge.BridgeCommandException("E_SCENE_HIERARCHY_PARENT_NOT_FOUND", "Parent GameObject not found: " + parent, "Pass an exact hierarchy path or instance id from a fresh scene.hierarchy page.");
|
|
172
|
+
return value;
|
|
153
173
|
}
|
|
154
174
|
|
|
155
|
-
|
|
156
|
-
private static HierarchyItem BuildHierarchyItem(Transform transform, int depth, bool includeComponents)
|
|
175
|
+
private static bool WithinBoundary(Transform value, Transform boundary, int maxDepth, UnityCliRequestBudget budget)
|
|
157
176
|
{
|
|
158
|
-
|
|
159
|
-
|
|
177
|
+
if (value == null) return false;
|
|
178
|
+
var current = value;
|
|
179
|
+
var depth = 0;
|
|
180
|
+
while (current != null && current != boundary)
|
|
160
181
|
{
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
{
|
|
166
|
-
Id = gameObject.GetInstanceID(),
|
|
167
|
-
Name = gameObject.name,
|
|
168
|
-
Path = HierarchyPath(gameObject),
|
|
169
|
-
Depth = depth,
|
|
170
|
-
Active = gameObject.activeSelf,
|
|
171
|
-
ActiveInHierarchy = gameObject.activeInHierarchy,
|
|
172
|
-
Tag = gameObject.tag,
|
|
173
|
-
Layer = gameObject.layer,
|
|
174
|
-
ChildCount = transform.childCount,
|
|
175
|
-
ChildrenTruncated = transform.childCount > 0,
|
|
176
|
-
ComponentCount = componentNames.Count,
|
|
177
|
-
ComponentTypes = componentNames
|
|
178
|
-
};
|
|
179
|
-
if (includeComponents)
|
|
180
|
-
{
|
|
181
|
-
item.Components = componentNames;
|
|
182
|
+
if (depth > maxDepth) return false;
|
|
183
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
184
|
+
current = current.parent;
|
|
185
|
+
depth++;
|
|
182
186
|
}
|
|
183
|
-
return
|
|
187
|
+
return (boundary == null || current == boundary) && depth - 1 <= maxDepth;
|
|
184
188
|
}
|
|
185
189
|
|
|
186
|
-
private static
|
|
190
|
+
private static bool Matches(GameObject gameObject, string query, string componentType, bool includeInactive, UnityCliRequestBudget budget)
|
|
187
191
|
{
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
192
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
193
|
+
if (!includeInactive && !gameObject.activeInHierarchy) return false;
|
|
194
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
195
|
+
var name = gameObject.name;
|
|
196
|
+
if (!string.IsNullOrEmpty(query))
|
|
191
197
|
{
|
|
192
|
-
|
|
193
|
-
|
|
198
|
+
var path = UnityCliHierarchyPager.Path(gameObject, budget);
|
|
199
|
+
if (name.IndexOf(query, StringComparison.OrdinalIgnoreCase) < 0 && path.IndexOf(query, StringComparison.OrdinalIgnoreCase) < 0) return false;
|
|
194
200
|
}
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
// 通用文本筛选;query 为空时视为匹配。
|
|
199
|
-
private static bool TextMatches(string query, params string[] values)
|
|
200
|
-
{
|
|
201
|
-
if (string.IsNullOrEmpty(query)) return true;
|
|
202
|
-
foreach (var value in values ?? new string[0])
|
|
201
|
+
if (string.IsNullOrEmpty(componentType)) return true;
|
|
202
|
+
foreach (var component in UnityCliBridge.ObjectRefResolver.BoundedComponents(gameObject, budget))
|
|
203
203
|
{
|
|
204
|
-
if (
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
204
|
+
if (component == null && string.Equals(componentType, "MissingScript", StringComparison.OrdinalIgnoreCase)) return true;
|
|
205
|
+
if (component == null) continue;
|
|
206
|
+
if (!budget.TryConsumeReflectionCall()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
207
|
+
var type = component.GetType();
|
|
208
|
+
if (string.Equals(type.Name, componentType, StringComparison.OrdinalIgnoreCase)
|
|
209
|
+
|| string.Equals(type.FullName, componentType, StringComparison.OrdinalIgnoreCase)) return true;
|
|
208
210
|
}
|
|
209
211
|
return false;
|
|
210
212
|
}
|
|
211
213
|
|
|
212
|
-
|
|
213
|
-
private static bool ComponentMatches(GameObject gameObject, string componentType)
|
|
214
|
+
private static HierarchyItem BuildItem(Transform transform, GameObject parent, bool includeComponents, UnityCliRequestBudget budget)
|
|
214
215
|
{
|
|
215
|
-
if (
|
|
216
|
-
|
|
216
|
+
if (!budget.TryConsumeNode() || !budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
217
|
+
var gameObject = transform.gameObject;
|
|
218
|
+
var path = UnityCliHierarchyPager.Path(gameObject, budget);
|
|
219
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
220
|
+
var name = gameObject.name;
|
|
221
|
+
if (!budget.TryReserveSerializedUtf8(name) || !budget.TryReserveSerializedUtf8(path)) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
222
|
+
List<string> componentNames = null;
|
|
223
|
+
if (includeComponents)
|
|
217
224
|
{
|
|
218
|
-
|
|
225
|
+
componentNames = new List<string>();
|
|
226
|
+
foreach (var component in UnityCliBridge.ObjectRefResolver.BoundedComponents(gameObject, budget))
|
|
227
|
+
{
|
|
228
|
+
if (!budget.TryConsumeReflectionCall()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
229
|
+
var componentName = component == null ? "MissingScript" : component.GetType().FullName;
|
|
230
|
+
if (!budget.TryReserveSerializedUtf8(componentName)) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
231
|
+
componentNames.Add(componentName);
|
|
232
|
+
}
|
|
219
233
|
}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (
|
|
226
|
-
|
|
227
|
-
var type = component.GetType();
|
|
228
|
-
return string.Equals(type.Name, componentType, StringComparison.OrdinalIgnoreCase)
|
|
229
|
-
|| string.Equals(type.FullName, componentType, StringComparison.OrdinalIgnoreCase)
|
|
230
|
-
|| type.FullName.IndexOf(componentType, StringComparison.OrdinalIgnoreCase) >= 0;
|
|
231
|
-
}
|
|
232
|
-
|
|
233
|
-
private static PageInfo BuildPageInfo(int pageSize, int cursor, int totalCount, int returnedCount)
|
|
234
|
-
{
|
|
235
|
-
long? next = cursor + returnedCount < totalCount ? (long?)(cursor + returnedCount) : null;
|
|
236
|
-
return new PageInfo
|
|
234
|
+
if (!budget.TryConsumeGetter() || !budget.TryConsumeGetter() || !budget.TryConsumeGetter()
|
|
235
|
+
|| !budget.TryConsumeGetter() || !budget.TryConsumeGetter() || !budget.TryConsumeGetter())
|
|
236
|
+
throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
237
|
+
var childCount = transform.childCount;
|
|
238
|
+
var tag = gameObject.tag;
|
|
239
|
+
if (!budget.TryReserveSerializedUtf8(tag)) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
240
|
+
return new HierarchyItem
|
|
237
241
|
{
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
242
|
+
Id = gameObject.GetInstanceID(), Name = name, Path = path,
|
|
243
|
+
Depth = UnityCliHierarchyPager.Depth(transform, parent == null ? null : parent.transform, budget),
|
|
244
|
+
Active = gameObject.activeSelf, ActiveInHierarchy = gameObject.activeInHierarchy,
|
|
245
|
+
Tag = tag, Layer = gameObject.layer, ChildCount = childCount,
|
|
246
|
+
ChildrenTruncated = childCount > 0,
|
|
247
|
+
ComponentCount = componentNames == null ? (long?)null : componentNames.Count,
|
|
248
|
+
ComponentTypes = componentNames,
|
|
249
|
+
Components = componentNames
|
|
246
250
|
};
|
|
247
251
|
}
|
|
248
252
|
}
|
|
@@ -2,7 +2,6 @@
|
|
|
2
2
|
using System;
|
|
3
3
|
using System.Collections.Generic;
|
|
4
4
|
using System.IO;
|
|
5
|
-
using System.Linq;
|
|
6
5
|
using UnityEditor;
|
|
7
6
|
using UnityEngine;
|
|
8
7
|
#if UNITY_6000_7_OR_NEWER
|
|
@@ -26,9 +25,10 @@ namespace UnityCli
|
|
|
26
25
|
internal List<string> ElementClasses;
|
|
27
26
|
internal long WindowInstanceId, MaxBytes;
|
|
28
27
|
internal int Width, Height;
|
|
28
|
+
internal ScreenshotCaptureBudget CaptureBudget;
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
-
internal static Plan Prepare(EditorElementCaptureRequest request)
|
|
31
|
+
internal static Plan Prepare(EditorElementCaptureRequest request, UnityCliRequestBudget requestBudget)
|
|
32
32
|
{
|
|
33
33
|
#if !UNITY_6000_7_OR_NEWER
|
|
34
34
|
throw Unavailable();
|
|
@@ -41,20 +41,29 @@ namespace UnityCli
|
|
|
41
41
|
var maxBytes = request.MaxBytes ?? (8L * 1024L * 1024L);
|
|
42
42
|
if (maxWidth < 1 || maxWidth > MaxDimension || maxHeight < 1 || maxHeight > MaxDimension || maxBytes < 1024 || maxBytes > MaxArtifactBytes)
|
|
43
43
|
throw Error("E_EDITOR_ELEMENT_LIMIT_INVALID", "maxWidth/maxHeight must be 1..4096 and maxBytes must be 1024..33554432.");
|
|
44
|
-
var candidates =
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
44
|
+
var candidates = new List<EditorWindow>();
|
|
45
|
+
foreach (var value in Resources.FindObjectsOfTypeAll<EditorWindow>())
|
|
46
|
+
{
|
|
47
|
+
if (!requestBudget.TryConsumeScannedRecord()) throw new UnityCliRequestBudgetExceededException(requestBudget.ExhaustedDimension);
|
|
48
|
+
if (value == null || value.rootVisualElement == null || value.rootVisualElement.panel == null) continue;
|
|
49
|
+
if (!string.Equals(value.GetType().Name, request.Window, StringComparison.Ordinal)
|
|
50
|
+
&& !string.Equals(value.titleContent == null ? null : value.titleContent.text, request.Window, StringComparison.Ordinal)) continue;
|
|
51
|
+
candidates.Add(value);
|
|
52
|
+
if (candidates.Count > 256) break;
|
|
53
|
+
}
|
|
54
|
+
candidates.Sort((left, right) => left.GetInstanceID().CompareTo(right.GetInstanceID()));
|
|
48
55
|
if (candidates.Count == 0) throw Error("E_EDITOR_ELEMENT_WINDOW_NOT_FOUND", "No attached EditorWindow exactly matches '" + request.Window + "'.");
|
|
49
56
|
if (candidates.Count > 256) throw Error("E_EDITOR_ELEMENT_LIMIT_EXCEEDED", "More than 256 EditorWindow candidates matched the bounded scan.");
|
|
50
57
|
var window = candidates[0];
|
|
51
|
-
var element = Resolve(window.rootVisualElement, request.Selector);
|
|
58
|
+
var element = Resolve(window.rootVisualElement, request.Selector, requestBudget);
|
|
52
59
|
if (element == null) throw Error("E_EDITOR_ELEMENT_NOT_FOUND", "No UI Toolkit element matched selector '" + request.Selector + "'.");
|
|
53
60
|
var width = Mathf.CeilToInt(element.worldBound.width);
|
|
54
61
|
var height = Mathf.CeilToInt(element.worldBound.height);
|
|
55
62
|
if (width < 1 || height < 1 || width > maxWidth || height > maxHeight || (long)width * height > 16777216L)
|
|
56
63
|
throw Error("E_EDITOR_ELEMENT_LIMIT_EXCEEDED", "Resolved element dimensions " + width + "x" + height + " exceed the requested capture bounds.");
|
|
57
|
-
|
|
64
|
+
var limits = new ScreenshotBudgetInput { MaxArtifactBytes = maxBytes };
|
|
65
|
+
var captureBudget = ScreenshotToolSupport.PrepareCaptureBudget(width, height, 1, false, limits, requestBudget);
|
|
66
|
+
return new Plan { Element = element, WindowType = window.GetType().Name, WindowTitle = window.titleContent == null ? null : window.titleContent.text, WindowInstanceId = window.GetInstanceID(), Selector = request.Selector, ElementType = element.GetType().Name, ElementName = element.name, ElementClasses = BoundClasses(element, requestBudget), Width = width, Height = height, MaxBytes = maxBytes, CaptureBudget = captureBudget };
|
|
58
67
|
#endif
|
|
59
68
|
}
|
|
60
69
|
|
|
@@ -65,6 +74,7 @@ namespace UnityCli
|
|
|
65
74
|
throw Unavailable();
|
|
66
75
|
#else
|
|
67
76
|
if (plan == null || plan.Element == null || plan.Element.panel == null) throw Error("E_EDITOR_ELEMENT_TARGET_CHANGED", "The frozen UI Toolkit element is no longer attached.");
|
|
77
|
+
plan.CaptureBudget.BeginCapture(plan.Width, plan.Height);
|
|
68
78
|
RenderTexture texture = null;
|
|
69
79
|
Texture2D readable = null;
|
|
70
80
|
var previous = RenderTexture.active;
|
|
@@ -91,7 +101,7 @@ namespace UnityCli
|
|
|
91
101
|
if (string.IsNullOrWhiteSpace(ctx.ArtifactDir)) throw Error("E_EDITOR_ELEMENT_ARTIFACT_UNAVAILABLE", "The request artifact directory is unavailable.");
|
|
92
102
|
Directory.CreateDirectory(ctx.ArtifactDir);
|
|
93
103
|
var output = Path.Combine(ctx.ArtifactDir, "editor-element.png");
|
|
94
|
-
var artifact = ScreenshotToolSupport.WriteScreenshotBytes(output, png);
|
|
104
|
+
var artifact = ScreenshotToolSupport.WriteScreenshotBytes(output, png, plan.CaptureBudget);
|
|
95
105
|
if (artifact.SizeBytes > plan.MaxBytes || artifact.SizeBytes != png.LongLength)
|
|
96
106
|
{
|
|
97
107
|
try { File.Delete(output); } catch { }
|
|
@@ -105,15 +115,16 @@ namespace UnityCli
|
|
|
105
115
|
|
|
106
116
|
private static EditorElementCaptureResult Result(Plan plan, bool dryRun, ScreenshotArtifactProof artifact)
|
|
107
117
|
{
|
|
108
|
-
return new EditorElementCaptureResult { Available = true, Element = new EditorElementIdentity { Selector = plan.Selector, Type = plan.ElementType, Name = plan.ElementName, Classes = plan.ElementClasses }, Width = plan.Width, Height = plan.Height, Artifact = artifact, DryRun = dryRun, PlannedEffects = new List<EditorElementCapturePlannedEffect> { new EditorElementCapturePlannedEffect { Type = "screenshot.editor-element", WindowInstanceId = plan.WindowInstanceId, Width = plan.Width, Height = plan.Height, MaxBytes = plan.MaxBytes } } };
|
|
118
|
+
return new EditorElementCaptureResult { Available = true, Element = new EditorElementIdentity { Selector = plan.Selector, Type = plan.ElementType, Name = plan.ElementName, Classes = plan.ElementClasses }, Width = plan.Width, Height = plan.Height, Artifact = artifact, DryRun = dryRun, PlannedEffects = new List<EditorElementCapturePlannedEffect> { new EditorElementCapturePlannedEffect { Type = "screenshot.editor-element", WindowInstanceId = plan.WindowInstanceId, Width = plan.Width, Height = plan.Height, MaxBytes = plan.MaxBytes, CapturePlan = plan.CaptureBudget.Plan } } };
|
|
109
119
|
}
|
|
110
120
|
|
|
111
121
|
#if UNITY_6000_7_OR_NEWER
|
|
112
122
|
/// <summary>实现type/#id/.class与descendant/child链;全查询最多16段、10000候选。</summary>
|
|
113
|
-
private static VisualElement Resolve(VisualElement root, string selector)
|
|
123
|
+
private static VisualElement Resolve(VisualElement root, string selector, UnityCliRequestBudget budget)
|
|
114
124
|
{
|
|
115
125
|
var tokens = selector.Replace(">", " > ").Split(new[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
|
|
116
|
-
var segments =
|
|
126
|
+
var segments = 0;
|
|
127
|
+
foreach (var token in tokens) if (token != ">") segments++;
|
|
117
128
|
if (segments < 1 || segments > 16) throw Error("E_EDITOR_ELEMENT_SELECTOR_INVALID", "selector must contain 1..16 simple segments.");
|
|
118
129
|
var current = new List<VisualElement> { root };
|
|
119
130
|
var direct = false;
|
|
@@ -124,11 +135,10 @@ namespace UnityCli
|
|
|
124
135
|
var next = new List<VisualElement>();
|
|
125
136
|
foreach (var parent in current)
|
|
126
137
|
{
|
|
127
|
-
var
|
|
128
|
-
foreach (var value in values)
|
|
138
|
+
foreach (var value in TraverseChildren(parent, !direct, budget))
|
|
129
139
|
{
|
|
130
140
|
if (++visited > 10000) throw Error("E_EDITOR_ELEMENT_LIMIT_EXCEEDED", "selector scan exceeded 10000 UI elements.");
|
|
131
|
-
if (Matches(value, token)) next.Add(value);
|
|
141
|
+
if (Matches(value, token, budget)) next.Add(value);
|
|
132
142
|
if (next.Count > 256) throw Error("E_EDITOR_ELEMENT_LIMIT_EXCEEDED", "selector produced more than 256 intermediate matches.");
|
|
133
143
|
}
|
|
134
144
|
}
|
|
@@ -136,27 +146,55 @@ namespace UnityCli
|
|
|
136
146
|
direct = false;
|
|
137
147
|
if (current.Count == 0) return null;
|
|
138
148
|
}
|
|
139
|
-
return current.
|
|
149
|
+
return current.Count == 0 ? null : current[0];
|
|
140
150
|
}
|
|
141
151
|
|
|
142
|
-
private static
|
|
152
|
+
private static List<string> BoundClasses(VisualElement element, UnityCliRequestBudget budget)
|
|
143
153
|
{
|
|
144
|
-
var result = new List<
|
|
145
|
-
var
|
|
146
|
-
while (stack.Count > 0)
|
|
154
|
+
var result = new List<string>();
|
|
155
|
+
foreach (var value in element.GetClasses())
|
|
147
156
|
{
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
157
|
+
if (result.Count >= 128) break;
|
|
158
|
+
if (!budget.TryConsumeScannedRecord()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
159
|
+
var bounded = Bound(value);
|
|
160
|
+
if (!budget.TryReserveSerializedUtf8(bounded)) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
161
|
+
result.Add(bounded);
|
|
152
162
|
}
|
|
153
163
|
return result;
|
|
154
164
|
}
|
|
155
165
|
|
|
156
|
-
|
|
166
|
+
/// <summary>用(parent,nextChildIndex)逐子节点DFS,任何childCount和索引读取前先消费同一请求预算。</summary>
|
|
167
|
+
private static IEnumerable<VisualElement> TraverseChildren(VisualElement root, bool recursive, UnityCliRequestBudget budget)
|
|
168
|
+
{
|
|
169
|
+
var stack = new Stack<VisualElementTraversalFrame>();
|
|
170
|
+
stack.Push(CreateTraversalFrame(root, budget));
|
|
171
|
+
while (stack.Count > 0)
|
|
172
|
+
{
|
|
173
|
+
var frame = stack.Peek();
|
|
174
|
+
if (frame.NextChildIndex >= frame.ChildCount)
|
|
175
|
+
{
|
|
176
|
+
stack.Pop();
|
|
177
|
+
continue;
|
|
178
|
+
}
|
|
179
|
+
if (!budget.TryCheckpoint() || !budget.TryConsumeScannedRecord() || !budget.TryConsumeNode() || !budget.TryConsumeGetter())
|
|
180
|
+
throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
181
|
+
var value = frame.Parent[frame.NextChildIndex++];
|
|
182
|
+
yield return value;
|
|
183
|
+
if (recursive) stack.Push(CreateTraversalFrame(value, budget));
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
private static VisualElementTraversalFrame CreateTraversalFrame(VisualElement parent, UnityCliRequestBudget budget)
|
|
188
|
+
{
|
|
189
|
+
if (!budget.TryCheckpoint() || !budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
190
|
+
return new VisualElementTraversalFrame(parent, parent.childCount);
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
private static bool Matches(VisualElement value, string simple, UnityCliRequestBudget budget)
|
|
157
194
|
{
|
|
158
195
|
var typeEnd = simple.IndexOfAny(new[] { '#', '.' });
|
|
159
196
|
var type = typeEnd < 0 ? simple : simple.Substring(0, typeEnd);
|
|
197
|
+
if (!budget.TryConsumeReflectionCall()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
160
198
|
if (!string.IsNullOrEmpty(type) && type != "*" && !string.Equals(value.GetType().Name, type, StringComparison.Ordinal)) return false;
|
|
161
199
|
var position = Math.Max(0, typeEnd);
|
|
162
200
|
while (position < simple.Length)
|
|
@@ -165,12 +203,26 @@ namespace UnityCli
|
|
|
165
203
|
var next = simple.IndexOfAny(new[] { '#', '.' }, position);
|
|
166
204
|
var name = simple.Substring(position, (next < 0 ? simple.Length : next) - position);
|
|
167
205
|
if (string.IsNullOrEmpty(name)) return false;
|
|
206
|
+
if (!budget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
|
|
168
207
|
if (marker == '#' && !string.Equals(value.name, name, StringComparison.Ordinal)) return false;
|
|
169
208
|
if (marker == '.' && !value.ClassListContains(name)) return false;
|
|
170
209
|
position = next < 0 ? simple.Length : next;
|
|
171
210
|
}
|
|
172
211
|
return true;
|
|
173
212
|
}
|
|
213
|
+
|
|
214
|
+
private sealed class VisualElementTraversalFrame
|
|
215
|
+
{
|
|
216
|
+
internal readonly VisualElement Parent;
|
|
217
|
+
internal readonly int ChildCount;
|
|
218
|
+
internal int NextChildIndex;
|
|
219
|
+
|
|
220
|
+
internal VisualElementTraversalFrame(VisualElement parent, int childCount)
|
|
221
|
+
{
|
|
222
|
+
Parent = parent;
|
|
223
|
+
ChildCount = childCount;
|
|
224
|
+
}
|
|
225
|
+
}
|
|
174
226
|
#endif
|
|
175
227
|
|
|
176
228
|
private static string Bound(string value) => value == null || value.Length <= 1024 ? value : value.Substring(0, 1024);
|