@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.
Files changed (425) hide show
  1. package/README.md +5 -5
  2. package/contracts/command-contract.json +109 -217
  3. package/contracts/package-files.json +374 -294
  4. package/contracts/stable-session/direct-call-semantics.json +8 -2
  5. package/contracts/tool-completion-contract.json +148 -672
  6. package/dist/bridge/admission.d.ts +17 -1
  7. package/dist/bridge/admission.js +2 -0
  8. package/dist/bridge/admission.js.map +1 -1
  9. package/dist/bridge/domains/asset.js +3 -1
  10. package/dist/bridge/domains/asset.js.map +1 -1
  11. package/dist/bridge/domains/camera.js +39 -7
  12. package/dist/bridge/domains/camera.js.map +1 -1
  13. package/dist/bridge/domains/console.js +2 -1
  14. package/dist/bridge/domains/console.js.map +1 -1
  15. package/dist/bridge/domains/doctor.d.ts +3 -0
  16. package/dist/bridge/domains/doctor.js +8 -0
  17. package/dist/bridge/domains/doctor.js.map +1 -0
  18. package/dist/bridge/domains/editor.js +0 -4
  19. package/dist/bridge/domains/editor.js.map +1 -1
  20. package/dist/bridge/domains/game-object.js +4 -12
  21. package/dist/bridge/domains/game-object.js.map +1 -1
  22. package/dist/bridge/domains/graphics.js +1 -16
  23. package/dist/bridge/domains/graphics.js.map +1 -1
  24. package/dist/bridge/domains/object.js +3 -0
  25. package/dist/bridge/domains/object.js.map +1 -1
  26. package/dist/bridge/domains/physics.js +1 -2
  27. package/dist/bridge/domains/physics.js.map +1 -1
  28. package/dist/bridge/domains/profiler.js +18 -7
  29. package/dist/bridge/domains/profiler.js.map +1 -1
  30. package/dist/bridge/domains/project-tool.js +4 -0
  31. package/dist/bridge/domains/project-tool.js.map +1 -1
  32. package/dist/bridge/domains/reflection.js +10 -2
  33. package/dist/bridge/domains/reflection.js.map +1 -1
  34. package/dist/bridge/domains/runtime-tool.js +3 -0
  35. package/dist/bridge/domains/runtime-tool.js.map +1 -1
  36. package/dist/bridge/domains/scene.js +3 -8
  37. package/dist/bridge/domains/scene.js.map +1 -1
  38. package/dist/bridge/domains/screenshot.js +30 -6
  39. package/dist/bridge/domains/screenshot.js.map +1 -1
  40. package/dist/bridge/domains/ui.js +3 -1
  41. package/dist/bridge/domains/ui.js.map +1 -1
  42. package/dist/bridge/index.d.ts +5 -5
  43. package/dist/bridge/index.js +6 -9
  44. package/dist/bridge/index.js.map +1 -1
  45. package/dist/bridge/registry.js +3 -5
  46. package/dist/bridge/registry.js.map +1 -1
  47. package/dist/bridge/session-supervisor.d.ts +6 -3
  48. package/dist/bridge/session-supervisor.js +145 -39
  49. package/dist/bridge/session-supervisor.js.map +1 -1
  50. package/dist/bridge/start-diagnostics.d.ts +19 -0
  51. package/dist/bridge/start-diagnostics.js +96 -0
  52. package/dist/bridge/start-diagnostics.js.map +1 -0
  53. package/dist/bridge/types.d.ts +6 -5
  54. package/dist/bridge/types.js +16 -2
  55. package/dist/bridge/types.js.map +1 -1
  56. package/dist/catalog-protocol.d.ts +64 -0
  57. package/dist/catalog-protocol.js +460 -0
  58. package/dist/catalog-protocol.js.map +1 -0
  59. package/dist/cli-commands/command.js +84 -61
  60. package/dist/cli-commands/command.js.map +1 -1
  61. package/dist/cli-commands/extensions.js +70 -50
  62. package/dist/cli-commands/extensions.js.map +1 -1
  63. package/dist/cli-commands/instances.js +1 -1
  64. package/dist/cli-commands/instances.js.map +1 -1
  65. package/dist/cli-commands/package.js +10 -2
  66. package/dist/cli-commands/package.js.map +1 -1
  67. package/dist/cli-process-owners.d.ts +6 -0
  68. package/dist/cli-process-owners.js +27 -0
  69. package/dist/cli-process-owners.js.map +1 -0
  70. package/dist/cli.d.ts +1 -1
  71. package/dist/cli.js +20 -5
  72. package/dist/cli.js.map +1 -1
  73. package/dist/contracts/command-contract.js +14 -4
  74. package/dist/contracts/command-contract.js.map +1 -1
  75. package/dist/doctor.d.ts +4 -6
  76. package/dist/doctor.js +451 -398
  77. package/dist/doctor.js.map +1 -1
  78. package/dist/editor-blocker-observer.d.ts +2 -1
  79. package/dist/editor-blocker-observer.js +40 -13
  80. package/dist/editor-blocker-observer.js.map +1 -1
  81. package/dist/extension-availability.d.ts +27 -9
  82. package/dist/extension-availability.js +96 -56
  83. package/dist/extension-availability.js.map +1 -1
  84. package/dist/extensions/descriptor-loader.d.ts +2 -2
  85. package/dist/extensions/descriptor-loader.js +3 -4
  86. package/dist/extensions/descriptor-loader.js.map +1 -1
  87. package/dist/extensions/index.d.ts +1 -1
  88. package/dist/extensions/index.js +1 -1
  89. package/dist/extensions/index.js.map +1 -1
  90. package/dist/extensions/installer.d.ts +57 -5
  91. package/dist/extensions/installer.js +263 -64
  92. package/dist/extensions/installer.js.map +1 -1
  93. package/dist/extensions/registry.js +3 -5
  94. package/dist/extensions/registry.js.map +1 -1
  95. package/dist/extensions/state-contract.d.ts +11 -0
  96. package/dist/extensions/state-contract.js +50 -0
  97. package/dist/extensions/state-contract.js.map +1 -0
  98. package/dist/instances.d.ts +19 -1
  99. package/dist/instances.js +39 -0
  100. package/dist/instances.js.map +1 -1
  101. package/dist/package-manager.d.ts +0 -24
  102. package/dist/package-manager.js +5 -58
  103. package/dist/package-manager.js.map +1 -1
  104. package/dist/project-tool-discovery.d.ts +5 -2
  105. package/dist/project-tool-discovery.js +22 -18
  106. package/dist/project-tool-discovery.js.map +1 -1
  107. package/dist/runtime-code.js +1 -1
  108. package/dist/runtime-code.js.map +1 -1
  109. package/dist/tool-name.d.ts +4 -0
  110. package/dist/tool-name.js +15 -0
  111. package/dist/tool-name.js.map +1 -0
  112. package/dist/tools/.generated-completion-registry.d.ts +2 -0
  113. package/dist/tools/.generated-completion-registry.js +763 -325
  114. package/dist/tools/.generated-completion-registry.js.map +1 -1
  115. package/dist/tools/.generated-registry.d.ts +6 -11
  116. package/dist/tools/.generated-registry.js +6 -11
  117. package/dist/tools/.generated-registry.js.map +1 -1
  118. package/dist/tools/.generated-schemas.js +11 -16
  119. package/dist/tools/.generated-schemas.js.map +1 -1
  120. package/dist/tools/asset/refresh-status.d.ts +3 -0
  121. package/dist/tools/asset/refresh-status.js +12 -0
  122. package/dist/tools/asset/refresh-status.js.map +1 -0
  123. package/dist/tools/asset/refresh.js +7 -3
  124. package/dist/tools/asset/refresh.js.map +1 -1
  125. package/dist/tools/build/player-status.d.ts +3 -0
  126. package/dist/tools/build/player-status.js +12 -0
  127. package/dist/tools/build/player-status.js.map +1 -0
  128. package/dist/tools/build/run.js +1 -1
  129. package/dist/tools/build/run.js.map +1 -1
  130. package/dist/tools/catalog-control.d.ts +22 -0
  131. package/dist/tools/catalog-control.js +335 -0
  132. package/dist/tools/catalog-control.js.map +1 -0
  133. package/dist/tools/catalog.d.ts +7 -9
  134. package/dist/tools/catalog.js +66 -45
  135. package/dist/tools/catalog.js.map +1 -1
  136. package/dist/tools/commands.d.ts +1 -1
  137. package/dist/tools/commands.js +44 -11
  138. package/dist/tools/commands.js.map +1 -1
  139. package/dist/tools/define.js +3 -2
  140. package/dist/tools/define.js.map +1 -1
  141. package/dist/tools/dispatcher.d.ts +53 -6
  142. package/dist/tools/dispatcher.js +277 -108
  143. package/dist/tools/dispatcher.js.map +1 -1
  144. package/dist/tools/editor/compile.js +1 -1
  145. package/dist/tools/editor/compile.js.map +1 -1
  146. package/dist/tools/editor/play-mode-status.d.ts +3 -0
  147. package/dist/tools/editor/play-mode-status.js +12 -0
  148. package/dist/tools/editor/play-mode-status.js.map +1 -0
  149. package/dist/tools/editor/readiness.d.ts +0 -1
  150. package/dist/tools/editor/readiness.js +0 -1
  151. package/dist/tools/editor/readiness.js.map +1 -1
  152. package/dist/tools/editor/refresh.d.ts +7 -3
  153. package/dist/tools/editor/refresh.js +20 -15
  154. package/dist/tools/editor/refresh.js.map +1 -1
  155. package/dist/tools/editor/state.d.ts +2 -2
  156. package/dist/tools/editor/state.js +13 -12
  157. package/dist/tools/editor/state.js.map +1 -1
  158. package/dist/tools/metadata/derived.js +1 -7
  159. package/dist/tools/metadata/derived.js.map +1 -1
  160. package/dist/tools/metadata/status.js +1 -12
  161. package/dist/tools/metadata/status.js.map +1 -1
  162. package/dist/tools/metadata/types.d.ts +0 -2
  163. package/dist/tools/navmesh/live.js +1 -1
  164. package/dist/tools/navmesh/live.js.map +1 -1
  165. package/dist/tools/occlusion/live.js +1 -1
  166. package/dist/tools/occlusion/live.js.map +1 -1
  167. package/dist/tools/package/deploy.js +2 -2
  168. package/dist/tools/package/deploy.js.map +1 -1
  169. package/dist/tools/package/embed.js +1 -1
  170. package/dist/tools/package/embed.js.map +1 -1
  171. package/dist/tools/package/install-status.d.ts +3 -0
  172. package/dist/tools/package/install-status.js +12 -0
  173. package/dist/tools/package/install-status.js.map +1 -0
  174. package/dist/tools/package/install.js +3 -3
  175. package/dist/tools/package/install.js.map +1 -1
  176. package/dist/tools/package/live-resolve.js +45 -12
  177. package/dist/tools/package/live-resolve.js.map +1 -1
  178. package/dist/tools/package/registry-clear.js.map +1 -1
  179. package/dist/tools/package/registry-set.js.map +1 -1
  180. package/dist/tools/package/remove-status.d.ts +3 -0
  181. package/dist/tools/package/remove-status.js +12 -0
  182. package/dist/tools/package/remove-status.js.map +1 -0
  183. package/dist/tools/package/remove.js +3 -3
  184. package/dist/tools/package/remove.js.map +1 -1
  185. package/dist/tools/package/resolve.js +3 -3
  186. package/dist/tools/package/resolve.js.map +1 -1
  187. package/dist/tools/package/restore.js +2 -2
  188. package/dist/tools/package/restore.js.map +1 -1
  189. package/dist/tools/package/scoped-registry-add.js.map +1 -1
  190. package/dist/tools/status/support.d.ts +13 -0
  191. package/dist/tools/status/support.js +28 -0
  192. package/dist/tools/status/support.js.map +1 -0
  193. package/dist/tools/test/cancel.js +2 -2
  194. package/dist/tools/test/cancel.js.map +1 -1
  195. package/dist/tools/test/run-status.d.ts +3 -0
  196. package/dist/tools/test/run-status.js +12 -0
  197. package/dist/tools/test/run-status.js.map +1 -0
  198. package/dist/tools/test/run.js +7 -4
  199. package/dist/tools/test/run.js.map +1 -1
  200. package/dist/tools/tools/group-summaries.js +10 -14
  201. package/dist/tools/tools/group-summaries.js.map +1 -1
  202. package/docs/architecture.md +4 -4
  203. package/docs/availability-differences.md +4 -4
  204. package/docs/command-execution.md +4 -3
  205. package/docs/error-codes.md +13 -5
  206. package/docs/extensions.md +1 -7
  207. package/docs/risk-and-side-effects.md +4 -3
  208. package/docs/safety-boundaries.md +3 -1
  209. package/docs/target-and-instance.md +1 -1
  210. package/docs/tool-discovery.md +17 -10
  211. package/docs/tool-execution.md +18 -7
  212. package/extensions/cinemachine/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  213. package/extensions/hdrp/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  214. package/extensions/probuilder/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  215. package/extensions/urp/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  216. package/extensions/vfx-graph/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  217. package/package.json +2 -4
  218. package/skills/unitycli/SKILL.md +11 -2
  219. package/skills/unitycli/manifest.json +1 -1
  220. package/skills/unitycli/references/operation-protocol.md +3 -3
  221. package/unitypkg/Editor/AssemblyInfo.cs +5 -0
  222. package/unitypkg/Editor/Bridge/BridgeCommandRegistry.cs +49 -14
  223. package/unitypkg/Editor/Bridge/BridgeHttpServer.cs +9 -35
  224. package/unitypkg/Editor/Bridge/BridgeQueueState.cs +672 -0
  225. package/unitypkg/Editor/Bridge/BridgeWorkQueue.cs +970 -120
  226. package/unitypkg/Editor/BridgeStartupStateMachine.cs +59 -1
  227. package/unitypkg/Editor/Commands/ProjectToolCommands.cs +4 -0
  228. package/unitypkg/Editor/Commands/RuntimeToolCommands.cs +3 -0
  229. package/unitypkg/Editor/Generated/UnityCliToolCompletionRegistry.g.cs +379 -14
  230. package/unitypkg/Editor/Infrastructure/CodeExecSupport.cs +28 -13
  231. package/unitypkg/Editor/Infrastructure/RegistryOwnershipResolver.cs +132 -105
  232. package/unitypkg/Editor/Infrastructure/UnityCliActiveOperation.cs +138 -29
  233. package/unitypkg/Editor/Infrastructure/UnityCliAdmission.cs +1856 -237
  234. package/unitypkg/Editor/Infrastructure/UnityCliDoctorDiagnostics.cs +220 -0
  235. package/unitypkg/Editor/Infrastructure/UnityCliDurableStatusCoordinator.cs +118 -0
  236. package/unitypkg/Editor/Infrastructure/UnityCliEditorStateSnapshot.cs +2 -1
  237. package/unitypkg/Editor/Infrastructure/UnityCliHierarchyPager.cs +203 -0
  238. package/unitypkg/Editor/Infrastructure/UnityCliInstanceCleanup.cs +2 -1
  239. package/unitypkg/Editor/Infrastructure/UnityCliInstanceRegistry.cs +201 -63
  240. package/unitypkg/Editor/Infrastructure/UnityCliJson.cs +2 -3
  241. package/unitypkg/Editor/Infrastructure/UnityCliLiveBuildCoordinator.cs +289 -46
  242. package/unitypkg/Editor/Infrastructure/UnityCliLiveRefreshCoordinator.cs +87 -53
  243. package/unitypkg/Editor/Infrastructure/UnityCliNavMeshBakeCoordinator.cs +4 -4
  244. package/unitypkg/Editor/Infrastructure/UnityCliObjectRef.cs +128 -25
  245. package/unitypkg/Editor/Infrastructure/UnityCliObjectSerializer.cs +435 -327
  246. package/unitypkg/Editor/Infrastructure/UnityCliOcclusionBakeCoordinator.cs +4 -4
  247. package/unitypkg/Editor/Infrastructure/UnityCliOperationCoordinator.cs +351 -53
  248. package/unitypkg/Editor/Infrastructure/UnityCliPackageResolveCoordinator.cs +118 -18
  249. package/unitypkg/Editor/Infrastructure/UnityCliPackageResolveState.cs +20 -1
  250. package/unitypkg/Editor/Infrastructure/UnityCliReadGeneration.cs +97 -0
  251. package/unitypkg/Editor/Infrastructure/UnityCliReflection.cs +644 -133
  252. package/unitypkg/Editor/Infrastructure/UnityCliReloadOperation.cs +128 -41
  253. package/unitypkg/Editor/Infrastructure/UnityCliRuntimeExecutor.cs +14 -84
  254. package/unitypkg/Editor/Infrastructure/UnityCliSerializer.cs +220 -0
  255. package/unitypkg/Editor/Infrastructure/UnityCliSessionMutationLease.cs +69 -29
  256. package/unitypkg/Editor/Infrastructure/UnityCliTestRunCoordinator.cs +440 -54
  257. package/unitypkg/Editor/Infrastructure/UnityCliWaiter.cs +128 -35
  258. package/unitypkg/Editor/ProjectTools/IUnityCliTool.cs +9 -1
  259. package/unitypkg/Editor/ProjectTools/OfficialAttributeToolRegistry.cs +32 -31
  260. package/unitypkg/Editor/ProjectTools/ProjectToolRegistry.cs +607 -458
  261. package/unitypkg/Editor/ProjectTools/ProjectToolSchemaValidator.cs +35 -7
  262. package/unitypkg/Editor/ProjectTools/RegisteredTool.cs +501 -60
  263. package/unitypkg/Editor/ProjectTools/UnityCliProjectToolContext.cs +21 -0
  264. package/unitypkg/Editor/ProjectTools/UnityCliSchemaDeriver.cs +36 -7
  265. package/unitypkg/Editor/ProjectTools/UnityCliToolName.cs +30 -0
  266. package/unitypkg/Editor/Properties/AssemblyInfo.cs +3 -0
  267. package/unitypkg/Editor/Tools/asset/get-data.cs +16 -7
  268. package/unitypkg/Editor/Tools/build/BuildSceneStateTool.cs +23 -3
  269. package/unitypkg/Editor/Tools/build/BuildToolDtos.cs +2 -1
  270. package/unitypkg/Editor/Tools/build/scene/add.cs +6 -3
  271. package/unitypkg/Editor/Tools/build/scene/disable.cs +1 -1
  272. package/unitypkg/Editor/Tools/build/scene/enable.cs +1 -1
  273. package/unitypkg/Editor/Tools/build/scene/list.cs +1 -1
  274. package/unitypkg/Editor/Tools/build/scene/remove.cs +13 -3
  275. package/unitypkg/Editor/Tools/camera/CameraToolSupport.cs +38 -38
  276. package/unitypkg/Editor/Tools/camera/multiview.cs +13 -6
  277. package/unitypkg/Editor/Tools/camera/screenshot.cs +14 -7
  278. package/unitypkg/Editor/Tools/component/get.cs +16 -9
  279. package/unitypkg/Editor/Tools/component/modify.cs +6 -4
  280. package/unitypkg/Editor/Tools/console/clear.cs +7 -6
  281. package/unitypkg/Editor/Tools/console/get.cs +48 -16
  282. package/unitypkg/Editor/Tools/editor/EditorToolSupport.cs +143 -28
  283. package/unitypkg/Editor/Tools/editor/menu-items.cs +1 -1
  284. package/unitypkg/Editor/Tools/editor/play.cs +2 -11
  285. package/unitypkg/Editor/Tools/editor/selection.cs +1 -1
  286. package/unitypkg/Editor/Tools/editor/stop.cs +2 -11
  287. package/unitypkg/Editor/Tools/editor/windows.cs +1 -1
  288. package/unitypkg/Editor/Tools/go/GameObjectToolSupport.cs +54 -4
  289. package/unitypkg/Editor/Tools/go/delete.cs +1 -1
  290. package/unitypkg/Editor/Tools/go/find.cs +167 -70
  291. package/unitypkg/Editor/Tools/graphics/GraphicsToolSupport.cs +25 -0
  292. package/unitypkg/Editor/Tools/graphics/light-probe-group.cs +9 -3
  293. package/unitypkg/Editor/Tools/graphics/pipeline-info.cs +1 -1
  294. package/unitypkg/Editor/Tools/graphics/pipeline-settings.cs +1 -1
  295. package/unitypkg/Editor/Tools/graphics/quality.cs +2 -2
  296. package/unitypkg/Editor/Tools/graphics/reflection-probe.cs +3 -3
  297. package/unitypkg/Editor/Tools/graphics/stats.cs +1 -1
  298. package/unitypkg/Editor/Tools/object/ObjectToolSupport.cs +4 -4
  299. package/unitypkg/Editor/Tools/object/get-data.cs +9 -7
  300. package/unitypkg/Editor/Tools/object/modify.cs +7 -5
  301. package/unitypkg/Editor/Tools/physics/raycast.cs +24 -6
  302. package/unitypkg/Editor/Tools/prefab/stage.cs +1 -1
  303. package/unitypkg/Editor/Tools/profiler/ProfilerFrameDebuggerSupport.cs +94 -21
  304. package/unitypkg/Editor/Tools/profiler/ProfilerMemorySnapshotSupport.cs +397 -10
  305. package/unitypkg/Editor/Tools/profiler/ProfilerToolSupport.cs +18 -4
  306. package/unitypkg/Editor/Tools/profiler/frame-debugger/enable.cs +1 -1
  307. package/unitypkg/Editor/Tools/profiler/frame-debugger/events.cs +88 -87
  308. package/unitypkg/Editor/Tools/profiler/hierarchy.cs +278 -112
  309. package/unitypkg/Editor/Tools/profiler/memory-snapshot/compare.cs +9 -5
  310. package/unitypkg/Editor/Tools/profiler/memory-snapshot/list.cs +37 -35
  311. package/unitypkg/Editor/Tools/profiler/memory-snapshot/take.cs +99 -97
  312. package/unitypkg/Editor/Tools/project/info.cs +1 -1
  313. package/unitypkg/Editor/Tools/project/layers.cs +1 -1
  314. package/unitypkg/Editor/Tools/project/tags.cs +1 -1
  315. package/unitypkg/Editor/Tools/reflection/method/call.cs +9 -7
  316. package/unitypkg/Editor/Tools/reflection/method/find.cs +27 -37
  317. package/unitypkg/Editor/Tools/reflection/type/schema.cs +24 -28
  318. package/unitypkg/Editor/Tools/scene/gameobject/component.cs +8 -5
  319. package/unitypkg/Editor/Tools/scene/gameobject/components.cs +10 -7
  320. package/unitypkg/Editor/Tools/scene/gameobject-support.cs +104 -8
  321. package/unitypkg/Editor/Tools/scene/gameobject.cs +37 -16
  322. package/unitypkg/Editor/Tools/scene/hierarchy.cs +146 -142
  323. package/unitypkg/Editor/Tools/screenshot/EditorElementCaptureToolSupport.cs +77 -25
  324. package/unitypkg/Editor/Tools/screenshot/ScreenshotToolSupport.cs +315 -95
  325. package/unitypkg/Editor/Tools/screenshot/editor-element.cs +7 -5
  326. package/unitypkg/Editor/Tools/screenshot/game-view.cs +35 -21
  327. package/unitypkg/Editor/Tools/screenshot/isolated-object.cs +29 -23
  328. package/unitypkg/Editor/Tools/screenshot/orbit.cs +37 -25
  329. package/unitypkg/Editor/Tools/screenshot/scene-view.cs +25 -18
  330. package/unitypkg/Editor/Tools/screenshot/screen.cs +177 -17
  331. package/unitypkg/Editor/Tools/screenshot/surround.cs +83 -79
  332. package/unitypkg/Editor/Tools/ui/render-preview.cs +16 -11
  333. package/unitypkg/Editor/UnityCliBridge.cs +97 -34
  334. package/unitypkg/Runtime/Infrastructure/UnityCliRuntimeBridge.cs +753 -122
  335. package/unitypkg/Runtime/Properties/AssemblyInfo.cs +5 -0
  336. package/unitypkg/Runtime/UnityCli.Runtime.asmdef +1 -1
  337. package/unitypkg/Shared/AssemblyInfo.cs +4 -0
  338. package/unitypkg/Shared/UnityCliAdmissionPool.cs +265 -75
  339. package/unitypkg/Shared/UnityCliBridgeQueuePolicy.cs +410 -0
  340. package/unitypkg/Shared/UnityCliBridgeWorkItemState.cs +47 -0
  341. package/unitypkg/Shared/UnityCliExceptionProjection.cs +151 -0
  342. package/unitypkg/Shared/UnityCliQueuePublication.cs +30 -0
  343. package/unitypkg/Shared/UnityCliRequestBudget.cs +352 -0
  344. package/unitypkg/Shared/UnityCliRuntimeRequestPublication.cs +107 -0
  345. package/unitypkg/Tests/Editor/UnityCli.Editor.Tests.asmdef +2 -2
  346. package/unitypkg/Tests/Editor/UnityCliAdmissionCoordinatorIntegrationTests.cs +1329 -0
  347. package/unitypkg/Tests/Editor/UnityCliAdmissionPoolTests.cs +311 -114
  348. package/unitypkg/Tests/Editor/UnityCliAdmissionRepairStateTests.cs +94 -0
  349. package/unitypkg/Tests/Editor/UnityCliBridgeAdmissionIntegrationTests.cs +1229 -0
  350. package/unitypkg/Tests/Editor/UnityCliBridgeQueuePolicyTests.cs +412 -0
  351. package/unitypkg/Tests/Editor/UnityCliContinuationIntegrationTests.cs +292 -0
  352. package/unitypkg/Tests/Editor/UnityCliDiagnosticBoundaryTests.cs +120 -0
  353. package/unitypkg/Tests/Editor/UnityCliDurableStatusTests.cs +84 -0
  354. package/unitypkg/Tests/Editor/UnityCliExceptionProjectionTests.cs +72 -0
  355. package/unitypkg/Tests/Editor/UnityCliInstancePublicationRetryTests.cs +180 -97
  356. package/unitypkg/Tests/Editor/UnityCliMemoryReflectionIntegrationTests.cs +434 -0
  357. package/unitypkg/Tests/Editor/UnityCliRequestBudgetTests.cs +615 -0
  358. package/unitypkg/Tests/Editor/UnityCliRuntimeBridgeIntegrationTests.cs +520 -0
  359. package/unitypkg/Tests/Editor/UnityCliToolCatalogTests.cs +562 -0
  360. package/unitypkg/Tests/Runtime/UnityCli.Runtime.Tests.asmdef +23 -0
  361. package/unitypkg/Tests/Runtime/UnityCliRuntimeCatalogValidationTests.cs +29 -0
  362. package/unitypkg/package.json +1 -1
  363. package/contracts/static-capability-catalog.json +0 -48226
  364. package/dist/bridge/domains/diagnose.d.ts +0 -2
  365. package/dist/bridge/domains/diagnose.js +0 -11
  366. package/dist/bridge/domains/diagnose.js.map +0 -1
  367. package/dist/bridge/domains/extension.d.ts +0 -8
  368. package/dist/bridge/domains/extension.js +0 -20
  369. package/dist/bridge/domains/extension.js.map +0 -1
  370. package/dist/capabilities.d.ts +0 -5
  371. package/dist/capabilities.js +0 -84
  372. package/dist/capabilities.js.map +0 -1
  373. package/dist/static-capability-catalog.d.ts +0 -13
  374. package/dist/static-capability-catalog.js +0 -41
  375. package/dist/static-capability-catalog.js.map +0 -1
  376. package/dist/tools/diagnose/capabilities.d.ts +0 -13
  377. package/dist/tools/diagnose/capabilities.js +0 -34
  378. package/dist/tools/diagnose/capabilities.js.map +0 -1
  379. package/dist/tools/package/info.d.ts +0 -19
  380. package/dist/tools/package/info.js +0 -27
  381. package/dist/tools/package/info.js.map +0 -1
  382. package/dist/tools/package/list.d.ts +0 -27
  383. package/dist/tools/package/list.js +0 -21
  384. package/dist/tools/package/list.js.map +0 -1
  385. package/dist/tools/package/registry-get.d.ts +0 -10
  386. package/dist/tools/package/registry-get.js +0 -22
  387. package/dist/tools/package/registry-get.js.map +0 -1
  388. package/dist/tools/package/scoped-registry-list.d.ts +0 -14
  389. package/dist/tools/package/scoped-registry-list.js +0 -22
  390. package/dist/tools/package/scoped-registry-list.js.map +0 -1
  391. package/dist/tools/package/search.d.ts +0 -17
  392. package/dist/tools/package/search.js +0 -39
  393. package/dist/tools/package/search.js.map +0 -1
  394. package/dist/tools/package/status.d.ts +0 -21
  395. package/dist/tools/package/status.js +0 -37
  396. package/dist/tools/package/status.js.map +0 -1
  397. package/dist/tools/tools/describe.d.ts +0 -27
  398. package/dist/tools/tools/describe.js +0 -35
  399. package/dist/tools/tools/describe.js.map +0 -1
  400. package/dist/tools/tools/group-list.d.ts +0 -16
  401. package/dist/tools/tools/group-list.js +0 -38
  402. package/dist/tools/tools/group-list.js.map +0 -1
  403. package/dist/tools/tools/group.d.ts +0 -13
  404. package/dist/tools/tools/group.js +0 -34
  405. package/dist/tools/tools/group.js.map +0 -1
  406. package/dist/tools/tools/pagination.d.ts +0 -17
  407. package/dist/tools/tools/pagination.js +0 -28
  408. package/dist/tools/tools/pagination.js.map +0 -1
  409. package/dist/tools/tools/search.d.ts +0 -15
  410. package/dist/tools/tools/search.js +0 -42
  411. package/dist/tools/tools/search.js.map +0 -1
  412. package/unitypkg/Editor/Tools/diagnose/preflight.cs +0 -269
  413. package/unitypkg/Editor/Tools/editor/console.cs +0 -26
  414. package/unitypkg/Editor/Tools/extension/status.cs +0 -87
  415. package/unitypkg/Editor/Tools/go/inspect.cs +0 -49
  416. package/unitypkg/Editor/Tools/graphics/pipeline-quality.cs +0 -24
  417. package/unitypkg/Editor/Tools/graphics/probe-positions.cs +0 -58
  418. package/unitypkg/Editor/Tools/graphics/settings.cs +0 -104
  419. package/unitypkg/Editor/Tools/graphics/stats-counters.cs +0 -28
  420. package/unitypkg/Editor/Tools/graphics/stats-memory.cs +0 -21
  421. package/unitypkg/Editor/Tools/instances/list.cs +0 -71
  422. package/unitypkg/Editor/Tools/physics/raycast-all.cs +0 -67
  423. package/unitypkg/Editor/Tools/scene/build-settings.cs +0 -69
  424. package/unitypkg/Editor/Tools/scene/data.cs +0 -125
  425. package/unitypkg/Editor/Tools/tests/list.cs +0 -98
@@ -14,10 +14,12 @@ namespace UnityCli
14
14
  public sealed class Request
15
15
  {
16
16
  [UnityCliRequired] public string Path { get; set; }
17
- public int? Width { get; set; }
18
- public int? Height { get; set; }
17
+ [UnityCliRange(1L, 8192L)] public int? Width { get; set; }
18
+ [UnityCliRange(1L, 8192L)] public int? Height { get; set; }
19
19
  public bool Overwrite { get; set; }
20
20
  public bool InlineBase64 { get; set; }
21
+ public ScreenshotBudgetInput Limits { get; set; }
22
+ public UnityCliReadBudgetInput Budget { get; set; }
21
23
  }
22
24
 
23
25
  public sealed class Result
@@ -34,13 +36,14 @@ namespace UnityCli
34
36
  public string ImageMimeType { get; set; }
35
37
  public long SizeBytes { get; set; }
36
38
  public string Sha256 { get; set; }
39
+ public ScreenshotCapturePlan CapturePlan { get; set; }
37
40
  }
38
41
 
39
42
  public ToolDescriptor Describe() => new()
40
43
  {
41
44
  Name = "screenshot.game-view",
42
45
  Summary = "Capture a Game View screenshot by rendering all active cameras to a PNG/JPG file.",
43
- Description = "Capture a Game View screenshot by rendering all active cameras to a temporary RenderTexture and saving to a PNG/JPG file. Renders camera content only and does not include screen-space UI; use screenshot.screen for the final composited frame. Defaults to 1280x720.",
46
+ Description = "Render active Cameras to one camera-only PNG/JPG (screen-space overlay UI is excluded). Dimensions default to 1280x720, each is 1..8192, and per-image pixels cannot exceed 16777216. Before the first effect, the plan must fit default ceilings of 33554432 total pixels, 128 MiB temporary memory and 64 MiB artifacts; public maxima are 67108864, 256 MiB and 256 MiB. Available in Edit and Play Mode.",
44
47
  Group = "screenshot",
45
48
  DestructiveHint = true,
46
49
  SideEffects = new[] { "asset-write" },
@@ -56,56 +59,67 @@ namespace UnityCli
56
59
  var outputPath = ScreenshotToolSupport.ResolveScreenshotOutputPath(request.Path);
57
60
  if (File.Exists(outputPath) && !request.Overwrite)
58
61
  throw new UnityCliBridge.BridgeCommandException("E_OUTPUT_EXISTS", "Screenshot output already exists: " + outputPath, "Pass overwrite=true or choose a different output path.");
62
+ var width = request.Width ?? 1280;
63
+ var height = request.Height ?? 720;
64
+ var format = ScreenshotToolSupport.NormalizeFormat(null, outputPath);
65
+ var requestBudget = ctx.UseReadBudget(request.Budget);
66
+ if (!requestBudget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(requestBudget.ExhaustedDimension);
67
+ var cameraCount = Camera.allCamerasCount;
68
+ if (cameraCount > ScreenshotToolSupport.MaxCaptureCount)
69
+ throw new UnityCliBridge.BridgeCommandException("E_SCREENSHOT_LIMIT_INVALID", "screenshot.game-view found more than 36 active Cameras.", "Disable unrelated Cameras or capture one Camera explicitly.");
70
+ var cameras = cameraCount > 0 ? Camera.allCameras : new Camera[0];
71
+ foreach (var camera in cameras)
72
+ if (!requestBudget.TryConsumeScannedRecord() || !requestBudget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(requestBudget.ExhaustedDimension);
73
+ var captureBudget = ScreenshotToolSupport.PrepareCaptureBudget(width, height, Math.Max(1, cameraCount), false, request.Limits, requestBudget);
59
74
  ctx.CommitEffect();
60
75
  ScreenshotToolSupport.CreateScreenshotDirectory(outputPath);
61
- var width = Math.Max(1, request.Width ?? 1280);
62
- var height = Math.Max(1, request.Height ?? 720);
63
- var format = outputPath.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) ? "jpg" : "png";
64
76
 
65
- var rt = new RenderTexture(width, height, 24);
66
- var texture = new Texture2D(width, height, TextureFormat.RGB24, false);
77
+ RenderTexture renderTexture = null;
78
+ Texture2D texture = null;
67
79
  byte[] bytes;
80
+ ScreenshotArtifactProof artifact;
68
81
  var previousActive = RenderTexture.active;
69
82
  try
70
83
  {
71
- RenderTexture.active = rt;
72
- var cameras = Camera.allCamerasCount > 0 ? Camera.allCameras : new Camera[0];
84
+ captureBudget.BeginCapture(width, height);
85
+ renderTexture = new RenderTexture(width, height, 24);
86
+ texture = new Texture2D(width, height, TextureFormat.RGB24, false);
87
+ RenderTexture.active = renderTexture;
73
88
  foreach (var cam in cameras)
74
89
  {
75
90
  if (!cam.gameObject.activeInHierarchy) continue;
76
91
  var prevTarget = cam.targetTexture;
77
- try { cam.targetTexture = rt; cam.Render(); }
92
+ try { cam.targetTexture = renderTexture; cam.Render(); }
78
93
  finally { cam.targetTexture = prevTarget; }
79
94
  }
80
95
  texture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
81
96
  texture.Apply();
82
97
  bytes = format == "jpg" ? texture.EncodeToJPG(95) : texture.EncodeToPNG();
83
- ScreenshotToolSupport.WriteScreenshotBytes(outputPath, bytes);
98
+ artifact = ScreenshotToolSupport.WriteScreenshotBytes(outputPath, bytes, captureBudget);
84
99
  }
85
100
  finally
86
101
  {
87
102
  RenderTexture.active = previousActive;
88
- UnityEngine.Object.DestroyImmediate(texture);
89
- rt.Release();
90
- UnityEngine.Object.DestroyImmediate(rt);
103
+ if (texture != null) UnityEngine.Object.DestroyImmediate(texture);
104
+ if (renderTexture != null) { renderTexture.Release(); UnityEngine.Object.DestroyImmediate(renderTexture); }
91
105
  }
92
106
 
93
- var artifact = ScreenshotToolSupport.VerifyScreenshotArtifact(outputPath, format);
94
107
  var result = new Result
95
108
  {
96
109
  ScreenshotPath = outputPath, ArtifactPath = outputPath, Format = format,
97
110
  Quality = 95, Source = "game-view", Target = "Camera.main/allCameras",
98
- SizeBytes = artifact.SizeBytes, Sha256 = artifact.Sha256
111
+ SizeBytes = artifact.SizeBytes, Sha256 = artifact.Sha256, CapturePlan = captureBudget.Plan
99
112
  };
100
- MaybeAppendInline(result, bytes, width, height, format == "jpg" ? "image/jpeg" : "image/png", request.InlineBase64);
113
+ MaybeAppendInline(result, bytes, width, height, format == "jpg" ? "image/jpeg" : "image/png", request.InlineBase64, captureBudget);
101
114
  return new System.Threading.Tasks.ValueTask<Result>(result);
102
115
  }
103
116
 
104
- private static void MaybeAppendInline(Result result, byte[] bytes, int width, int height, string mimeType, bool inlineBase64)
117
+ private static void MaybeAppendInline(Result result, byte[] bytes, int width, int height, string mimeType, bool inlineBase64, ScreenshotCaptureBudget budget)
105
118
  {
106
- if (inlineBase64 && bytes != null && bytes.Length <= 512 * 1024)
119
+ string encoded;
120
+ if (inlineBase64 && bytes != null && bytes.Length <= 512 * 1024 && budget.TryCreateInlineBase64(bytes, out encoded))
107
121
  {
108
- result.ImageBase64 = Convert.ToBase64String(bytes);
122
+ result.ImageBase64 = encoded;
109
123
  result.ImageWidth = width;
110
124
  result.ImageHeight = height;
111
125
  result.ImageMimeType = mimeType;
@@ -14,12 +14,14 @@ namespace UnityCli
14
14
  {
15
15
  [UnityCliRequired] public string Target { get; set; }
16
16
  [UnityCliRequired] public string Path { get; set; }
17
- public int? Width { get; set; }
18
- public int? Height { get; set; }
17
+ [UnityCliRange(1L, 8192L)] public int? Width { get; set; }
18
+ [UnityCliRange(1L, 8192L)] public int? Height { get; set; }
19
19
  public bool Orthographic { get; set; } = true;
20
20
  public float? Size { get; set; }
21
21
  public bool Overwrite { get; set; }
22
22
  public bool InlineBase64 { get; set; }
23
+ public ScreenshotBudgetInput Limits { get; set; }
24
+ public UnityCliReadBudgetInput Budget { get; set; }
23
25
  }
24
26
 
25
27
  public sealed class Result : ScreenshotCaptureResult { }
@@ -28,7 +30,7 @@ namespace UnityCli
28
30
  {
29
31
  Name = "screenshot.isolated-object",
30
32
  Summary = "Render a single GameObject in isolation with a temporary camera to a PNG/JPG file.",
31
- Description = "Render a single GameObject in isolation using a temporary camera with a solid background. Resolves the target by hierarchy path/name. Editor-only (creates a temporary Camera).",
33
+ Description = "Render one GameObject with a temporary Camera. Dimensions are 1..8192 with at most 16777216 pixels. Before creating the Camera or textures, the request must fit default ceilings of 33554432 total pixels, 128 MiB temporary memory and 64 MiB artifacts (public maxima 67108864, 256 MiB and 256 MiB). The temporary Camera and texture are released in finally. Editor-only because it creates a temporary scene object.",
32
34
  Group = "screenshot",
33
35
  DestructiveHint = true,
34
36
  SideEffects = new[] { "asset-write" },
@@ -41,51 +43,55 @@ namespace UnityCli
41
43
 
42
44
  public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
43
45
  {
44
- var go = UnityCliBridge.ObjectRefResolver.FindGameObjectByPath(request.Target);
46
+ var requestBudget = ctx.UseReadBudget(request.Budget);
47
+ var go = UnityCliBridge.ObjectRefResolver.FindGameObjectByExactPath(request.Target, requestBudget);
45
48
  if (go == null)
46
49
  throw new UnityCliBridge.BridgeCommandException("E_TARGET_NOT_FOUND", "screenshot.isolated-object requires a target GameObject.", "Pass --target <path>.");
47
50
  var outputPath = ScreenshotToolSupport.ResolveScreenshotOutputPath(request.Path);
48
51
  if (File.Exists(outputPath) && !request.Overwrite)
49
52
  throw new UnityCliBridge.BridgeCommandException("E_OUTPUT_EXISTS", "Output exists: " + outputPath);
53
+ var width = request.Width ?? 512;
54
+ var height = request.Height ?? 512;
55
+ if (request.Size.HasValue && (float.IsNaN(request.Size.Value) || float.IsInfinity(request.Size.Value) || request.Size.Value <= 0f))
56
+ throw new UnityCliBridge.BridgeCommandException("E_SCREENSHOT_LIMIT_INVALID", "size must be finite and greater than zero.", "Pass a positive finite orthographic size.");
57
+ var captureBudget = ScreenshotToolSupport.PrepareCaptureBudget(width, height, 1, false, request.Limits, requestBudget);
58
+ var format = ScreenshotToolSupport.NormalizeFormat(null, outputPath);
59
+ var bounds = ScreenshotToolSupport.TargetRenderBounds(go, requestBudget);
50
60
  ctx.CommitEffect();
51
61
  ScreenshotToolSupport.CreateScreenshotDirectory(outputPath);
52
- var width = Math.Max(1, request.Width ?? 512);
53
- var height = Math.Max(1, request.Height ?? 512);
54
- var format = outputPath.EndsWith(".jpg", StringComparison.OrdinalIgnoreCase) ? "jpg" : "png";
55
-
56
- var tempGo = new GameObject("__unitycli_isolated_cam__");
57
- var cam = tempGo.AddComponent<Camera>();
58
- cam.clearFlags = CameraClearFlags.SolidColor;
59
- cam.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 1f);
60
- cam.orthographic = request.Orthographic;
61
- cam.orthographicSize = request.Size ?? 2f;
62
- var bounds = go.GetComponent<Renderer>() != null ? go.GetComponent<Renderer>().bounds : new Bounds(go.transform.position, Vector3.one);
63
- tempGo.transform.position = bounds.center + new Vector3(0, 0, -5);
64
- tempGo.transform.LookAt(bounds.center);
65
62
 
63
+ GameObject temporaryCameraObject = null;
66
64
  byte[] bytes;
65
+ ScreenshotArtifactProof artifact;
67
66
  try
68
67
  {
69
- var texture = ScreenshotToolSupport.RenderScreenshotTexture(cam, width, height);
68
+ temporaryCameraObject = new GameObject("__unitycli_isolated_cam__");
69
+ var camera = temporaryCameraObject.AddComponent<Camera>();
70
+ camera.clearFlags = CameraClearFlags.SolidColor;
71
+ camera.backgroundColor = new Color(0.2f, 0.2f, 0.2f, 1f);
72
+ camera.orthographic = request.Orthographic;
73
+ camera.orthographicSize = request.Size ?? 2f;
74
+ temporaryCameraObject.transform.position = bounds.center + new Vector3(0, 0, -5);
75
+ temporaryCameraObject.transform.LookAt(bounds.center);
76
+ var texture = ScreenshotToolSupport.RenderScreenshotTexture(camera, width, height, captureBudget);
70
77
  try
71
78
  {
72
79
  bytes = format == "jpg" ? texture.EncodeToJPG(95) : texture.EncodeToPNG();
73
- ScreenshotToolSupport.WriteScreenshotBytes(outputPath, bytes);
80
+ artifact = ScreenshotToolSupport.WriteScreenshotBytes(outputPath, bytes, captureBudget);
74
81
  }
75
82
  finally { UnityEngine.Object.DestroyImmediate(texture); }
76
83
  }
77
84
  finally
78
85
  {
79
- UnityEngine.Object.DestroyImmediate(tempGo);
86
+ if (temporaryCameraObject != null) UnityEngine.Object.DestroyImmediate(temporaryCameraObject);
80
87
  }
81
88
 
82
- var artifact = ScreenshotToolSupport.VerifyScreenshotArtifact(outputPath, format);
83
89
  var result = new Result
84
90
  {
85
91
  ScreenshotPath = outputPath, ArtifactPath = outputPath, Source = "isolated-object",
86
- SizeBytes = artifact.SizeBytes, Sha256 = artifact.Sha256
92
+ SizeBytes = artifact.SizeBytes, Sha256 = artifact.Sha256, CapturePlan = captureBudget.Plan
87
93
  };
88
- ScreenshotToolSupport.MaybeAppendInline(result, bytes, width, height, format == "jpg" ? "image/jpeg" : "image/png", request.InlineBase64);
94
+ ScreenshotToolSupport.MaybeAppendInline(result, bytes, width, height, format == "jpg" ? "image/jpeg" : "image/png", request.InlineBase64, captureBudget);
89
95
  return new System.Threading.Tasks.ValueTask<Result>(result);
90
96
  }
91
97
  }
@@ -16,23 +16,26 @@ namespace UnityCli
16
16
  {
17
17
  [UnityCliRequired] public string Target { get; set; }
18
18
  public string OutputDir { get; set; } = "Assets/Screenshots";
19
- public int? Count { get; set; }
19
+ [UnityCliRange(2L, 36L)] public int? Count { get; set; }
20
20
  public float? Radius { get; set; }
21
- public int? Width { get; set; }
22
- public int? Height { get; set; }
21
+ [UnityCliRange(1L, 8192L)] public int? Width { get; set; }
22
+ [UnityCliRange(1L, 8192L)] public int? Height { get; set; }
23
23
  public bool Overwrite { get; set; }
24
+ public ScreenshotBudgetInput Limits { get; set; }
25
+ public UnityCliReadBudgetInput Budget { get; set; }
24
26
  }
25
27
 
26
28
  public sealed class Result
27
29
  {
28
30
  public List<ScreenshotArtifactEntry> Artifacts { get; set; }
31
+ public ScreenshotCapturePlan CapturePlan { get; set; }
29
32
  }
30
33
 
31
34
  public ToolDescriptor Describe() => new()
32
35
  {
33
36
  Name = "screenshot.orbit",
34
37
  Summary = "Capture N orbital screenshots around a GameObject at evenly spaced angles.",
35
- Description = "Capture N orbital screenshots (default 8, max 36) around a target GameObject at evenly spaced angles. Saves individual PNGs to an output directory. Editor-only.",
38
+ Description = "Capture 2..36 orbital PNGs (default 8). Dimensions are 1..8192 and each image is at most 16777216 pixels. Before the first effect, the complete orbit must fit default ceilings of 33554432 total pixels, 128 MiB peak temporary memory and 64 MiB artifacts; public maxima are 67108864, 256 MiB and 256 MiB. Each texture is encoded, written and released before the next capture. radius must be finite and positive. Editor-only because a temporary Camera may be created.",
36
39
  Group = "screenshot",
37
40
  DestructiveHint = true,
38
41
  SideEffects = new[] { "asset-write" },
@@ -45,14 +48,18 @@ namespace UnityCli
45
48
 
46
49
  public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
47
50
  {
48
- var go = UnityCliBridge.ObjectRefResolver.FindGameObjectByPath(request.Target);
51
+ var requestBudget = ctx.UseReadBudget(request.Budget);
52
+ var go = UnityCliBridge.ObjectRefResolver.FindGameObjectByExactPath(request.Target, requestBudget);
49
53
  if (go == null)
50
54
  throw new UnityCliBridge.BridgeCommandException("E_TARGET_NOT_FOUND", "screenshot.orbit requires a target GameObject.", "Pass --target <path>.");
51
55
  var outputDir = request.OutputDir ?? "Assets/Screenshots";
52
- var angleCount = Math.Max(2, Math.Min(request.Count ?? 8, 36));
56
+ var angleCount = request.Count ?? 8;
53
57
  var radius = request.Radius ?? 5f;
54
- var width = Math.Max(1, request.Width ?? 512);
55
- var height = Math.Max(1, request.Height ?? 512);
58
+ if (float.IsNaN(radius) || float.IsInfinity(radius) || radius <= 0f)
59
+ throw new UnityCliBridge.BridgeCommandException("E_SCREENSHOT_LIMIT_INVALID", "radius must be finite and greater than zero.", "Pass a positive finite orbit radius.");
60
+ var width = request.Width ?? 512;
61
+ var height = request.Height ?? 512;
62
+ var captureBudget = ScreenshotToolSupport.PrepareCaptureBudget(width, height, angleCount, false, request.Limits, requestBudget);
56
63
  var center = go.transform.position;
57
64
  var artifacts = new List<ScreenshotArtifactEntry>();
58
65
  for (var i = 0; i < angleCount; i++)
@@ -63,40 +70,45 @@ namespace UnityCli
63
70
  }
64
71
 
65
72
  ctx.CommitEffect();
66
- var cam = Camera.main;
67
- var tempCreated = false;
68
- if (cam == null)
69
- {
70
- var tempGo = new GameObject("__unitycli_orbit_cam__");
71
- cam = tempGo.AddComponent<Camera>();
72
- tempCreated = true;
73
- }
74
- var previousPosition = cam.transform.position;
75
- var previousRotation = cam.transform.rotation;
73
+ Camera camera = null;
74
+ GameObject temporaryCameraObject = null;
75
+ var previousPosition = Vector3.zero;
76
+ var previousRotation = Quaternion.identity;
76
77
  try
77
78
  {
79
+ camera = Camera.main;
80
+ if (camera == null)
81
+ {
82
+ temporaryCameraObject = new GameObject("__unitycli_orbit_cam__");
83
+ camera = temporaryCameraObject.AddComponent<Camera>();
84
+ }
85
+ else
86
+ {
87
+ previousPosition = camera.transform.position;
88
+ previousRotation = camera.transform.rotation;
89
+ }
78
90
  for (var i = 0; i < angleCount; i++)
79
91
  {
80
92
  var angle = (360f / angleCount) * i;
81
93
  var rad = angle * Mathf.Deg2Rad;
82
- cam.transform.position = center + new Vector3(Mathf.Cos(rad) * radius, 0, Mathf.Sin(rad) * radius);
83
- cam.transform.LookAt(center);
94
+ camera.transform.position = center + new Vector3(Mathf.Cos(rad) * radius, 0, Mathf.Sin(rad) * radius);
95
+ camera.transform.LookAt(center);
84
96
  var path = Path.Combine(ScreenshotToolSupport.AssetFullPath(outputDir), "orbit_" + i.ToString("00", CultureInfo.InvariantCulture) + ".png");
85
97
  ScreenshotToolSupport.CreateScreenshotDirectory(path);
86
- var texture = ScreenshotToolSupport.RenderScreenshotTexture(cam, width, height);
98
+ var texture = ScreenshotToolSupport.RenderScreenshotTexture(camera, width, height, captureBudget);
87
99
  ScreenshotArtifactProof proof;
88
- try { proof = ScreenshotToolSupport.WriteScreenshotBytes(path, texture.EncodeToPNG()); }
100
+ try { proof = ScreenshotToolSupport.WriteScreenshotBytes(path, texture.EncodeToPNG(), captureBudget); }
89
101
  finally { UnityEngine.Object.DestroyImmediate(texture); }
90
102
  artifacts.Add(new ScreenshotArtifactEntry { Source = "orbit", Path = path, Camera = "orbit:" + angle.ToString("F0", CultureInfo.InvariantCulture), Width = width, Height = height, Format = "png", SizeBytes = proof.SizeBytes, Sha256 = proof.Sha256 });
91
103
  }
92
104
  }
93
105
  finally
94
106
  {
95
- if (tempCreated) UnityEngine.Object.DestroyImmediate(cam.gameObject);
96
- else { cam.transform.position = previousPosition; cam.transform.rotation = previousRotation; }
107
+ if (temporaryCameraObject != null) UnityEngine.Object.DestroyImmediate(temporaryCameraObject);
108
+ else if (camera != null) { camera.transform.position = previousPosition; camera.transform.rotation = previousRotation; }
97
109
  }
98
110
 
99
- return new System.Threading.Tasks.ValueTask<Result>(new Result { Artifacts = artifacts });
111
+ return new System.Threading.Tasks.ValueTask<Result>(new Result { Artifacts = artifacts, CapturePlan = captureBudget.Plan });
100
112
  }
101
113
  }
102
114
  }
@@ -14,12 +14,14 @@ namespace UnityCli
14
14
  public sealed class Request
15
15
  {
16
16
  [UnityCliRequired] public string Path { get; set; }
17
- public int? Width { get; set; }
18
- public int? Height { get; set; }
17
+ [UnityCliRange(1L, 8192L)] public int? Width { get; set; }
18
+ [UnityCliRange(1L, 8192L)] public int? Height { get; set; }
19
19
  public bool Transparent { get; set; }
20
- public int? Quality { get; set; }
20
+ [UnityCliRange(1L, 100L)] public int? Quality { get; set; }
21
21
  public bool Overwrite { get; set; }
22
22
  public bool InlineBase64 { get; set; }
23
+ public ScreenshotBudgetInput Limits { get; set; }
24
+ public UnityCliReadBudgetInput Budget { get; set; }
23
25
  }
24
26
 
25
27
  public sealed class Result : ScreenshotCaptureResult { }
@@ -28,7 +30,7 @@ namespace UnityCli
28
30
  {
29
31
  Name = "screenshot.scene-view",
30
32
  Summary = "Capture the active SceneView camera to a PNG/JPG file.",
31
- Description = "Capture the active SceneView camera to a PNG/JPG file. Returns E_SCENE_VIEW_NOT_AVAILABLE when no SceneView is open.",
33
+ Description = "Capture the active SceneView camera to PNG/JPG. Dimensions are 1..8192 with at most 16777216 pixels; quality is 1..100. Before the first effect, the request must fit default ceilings of 33554432 total pixels, 128 MiB temporary memory and 64 MiB artifacts (public maxima 67108864, 256 MiB and 256 MiB). Returns E_SCENE_VIEW_NOT_AVAILABLE when no SceneView is open. Read state is restored after capture; available in Edit and Play Mode.",
32
34
  Group = "screenshot",
33
35
  DestructiveHint = true,
34
36
  SideEffects = new[] { "asset-write" },
@@ -41,18 +43,21 @@ namespace UnityCli
41
43
 
42
44
  public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
43
45
  {
46
+ var requestBudget = ctx.UseReadBudget(request.Budget);
47
+ if (!requestBudget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(requestBudget.ExhaustedDimension);
44
48
  var sceneView = SceneView.lastActiveSceneView;
45
49
  if (sceneView == null || sceneView.camera == null)
46
50
  throw new UnityCliBridge.BridgeCommandException("E_SCENE_VIEW_NOT_AVAILABLE", "No active SceneView camera.", "Open a SceneView window.");
47
51
  var camera = sceneView.camera;
48
52
  var outputPath = ScreenshotToolSupport.ResolveScreenshotOutputPath(request.Path);
49
53
  var format = ScreenshotToolSupport.NormalizeFormat(null, outputPath);
50
- var width = Math.Max(1, request.Width ?? (camera.pixelWidth > 0 ? camera.pixelWidth : 1280));
51
- var height = Math.Max(1, request.Height ?? (camera.pixelHeight > 0 ? camera.pixelHeight : 720));
52
- var quality = Mathf.Clamp(request.Quality ?? 95, 1, 100);
54
+ var width = request.Width ?? (camera.pixelWidth > 0 ? camera.pixelWidth : 1280);
55
+ var height = request.Height ?? (camera.pixelHeight > 0 ? camera.pixelHeight : 720);
56
+ var quality = request.Quality ?? 95;
53
57
 
54
58
  if (File.Exists(outputPath) && !request.Overwrite)
55
59
  throw new UnityCliBridge.BridgeCommandException("E_OUTPUT_EXISTS", "Screenshot output already exists: " + outputPath, "Pass overwrite=true or choose a different output path.");
60
+ var captureBudget = ScreenshotToolSupport.PrepareCaptureBudget(width, height, 1, false, request.Limits, requestBudget);
56
61
  ctx.CommitEffect();
57
62
  ScreenshotToolSupport.CreateScreenshotDirectory(outputPath);
58
63
 
@@ -60,19 +65,23 @@ namespace UnityCli
60
65
  var prevActive = RenderTexture.active;
61
66
  var prevClear = camera.clearFlags;
62
67
  var prevBg = camera.backgroundColor;
63
- var rt = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32);
64
- var texture = new Texture2D(width, height, request.Transparent ? TextureFormat.ARGB32 : TextureFormat.RGB24, false);
68
+ RenderTexture renderTexture = null;
69
+ Texture2D texture = null;
65
70
  byte[] bytes;
71
+ ScreenshotArtifactProof artifact;
66
72
  try
67
73
  {
68
- camera.targetTexture = rt;
74
+ captureBudget.BeginCapture(width, height);
75
+ renderTexture = new RenderTexture(width, height, 24, RenderTextureFormat.ARGB32);
76
+ texture = new Texture2D(width, height, request.Transparent ? TextureFormat.ARGB32 : TextureFormat.RGB24, false);
77
+ camera.targetTexture = renderTexture;
69
78
  if (request.Transparent) { camera.clearFlags = CameraClearFlags.SolidColor; camera.backgroundColor = new Color(0, 0, 0, 0); }
70
79
  camera.Render();
71
- RenderTexture.active = rt;
80
+ RenderTexture.active = renderTexture;
72
81
  texture.ReadPixels(new Rect(0, 0, width, height), 0, 0);
73
82
  texture.Apply();
74
83
  bytes = format == "jpg" ? texture.EncodeToJPG(quality) : texture.EncodeToPNG();
75
- ScreenshotToolSupport.WriteScreenshotBytes(outputPath, bytes);
84
+ artifact = ScreenshotToolSupport.WriteScreenshotBytes(outputPath, bytes, captureBudget);
76
85
  }
77
86
  finally
78
87
  {
@@ -80,18 +89,16 @@ namespace UnityCli
80
89
  camera.targetTexture = prevTarget;
81
90
  camera.clearFlags = prevClear;
82
91
  camera.backgroundColor = prevBg;
83
- UnityEngine.Object.DestroyImmediate(texture);
84
- rt.Release();
85
- UnityEngine.Object.DestroyImmediate(rt);
92
+ if (texture != null) UnityEngine.Object.DestroyImmediate(texture);
93
+ if (renderTexture != null) { renderTexture.Release(); UnityEngine.Object.DestroyImmediate(renderTexture); }
86
94
  }
87
95
 
88
- var artifact = ScreenshotToolSupport.VerifyScreenshotArtifact(outputPath, format);
89
96
  var result = new Result
90
97
  {
91
98
  ScreenshotPath = outputPath, ArtifactPath = outputPath, Source = "scene-view",
92
- SizeBytes = artifact.SizeBytes, Sha256 = artifact.Sha256
99
+ SizeBytes = artifact.SizeBytes, Sha256 = artifact.Sha256, CapturePlan = captureBudget.Plan
93
100
  };
94
- ScreenshotToolSupport.MaybeAppendInline(result, bytes, width, height, format == "jpg" ? "image/jpeg" : "image/png", request.InlineBase64);
101
+ ScreenshotToolSupport.MaybeAppendInline(result, bytes, width, height, format == "jpg" ? "image/jpeg" : "image/png", request.InlineBase64, captureBudget);
95
102
  return new System.Threading.Tasks.ValueTask<Result>(result);
96
103
  }
97
104
  }