@alpsckr/unitycli 0.4.3 → 0.4.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (420) 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 +122 -34
  49. package/dist/bridge/session-supervisor.js.map +1 -1
  50. package/dist/bridge/types.d.ts +6 -5
  51. package/dist/bridge/types.js +16 -2
  52. package/dist/bridge/types.js.map +1 -1
  53. package/dist/catalog-protocol.d.ts +64 -0
  54. package/dist/catalog-protocol.js +460 -0
  55. package/dist/catalog-protocol.js.map +1 -0
  56. package/dist/cli-commands/command.js +84 -61
  57. package/dist/cli-commands/command.js.map +1 -1
  58. package/dist/cli-commands/extensions.js +70 -50
  59. package/dist/cli-commands/extensions.js.map +1 -1
  60. package/dist/cli-commands/instances.js +1 -1
  61. package/dist/cli-commands/instances.js.map +1 -1
  62. package/dist/cli-process-owners.d.ts +6 -0
  63. package/dist/cli-process-owners.js +27 -0
  64. package/dist/cli-process-owners.js.map +1 -0
  65. package/dist/cli.d.ts +1 -1
  66. package/dist/cli.js +20 -5
  67. package/dist/cli.js.map +1 -1
  68. package/dist/contracts/command-contract.js +14 -4
  69. package/dist/contracts/command-contract.js.map +1 -1
  70. package/dist/doctor.d.ts +4 -6
  71. package/dist/doctor.js +429 -398
  72. package/dist/doctor.js.map +1 -1
  73. package/dist/editor-blocker-observer.d.ts +2 -1
  74. package/dist/editor-blocker-observer.js +40 -13
  75. package/dist/editor-blocker-observer.js.map +1 -1
  76. package/dist/extension-availability.d.ts +27 -9
  77. package/dist/extension-availability.js +96 -56
  78. package/dist/extension-availability.js.map +1 -1
  79. package/dist/extensions/descriptor-loader.d.ts +2 -2
  80. package/dist/extensions/descriptor-loader.js +3 -4
  81. package/dist/extensions/descriptor-loader.js.map +1 -1
  82. package/dist/extensions/index.d.ts +1 -1
  83. package/dist/extensions/index.js +1 -1
  84. package/dist/extensions/index.js.map +1 -1
  85. package/dist/extensions/installer.d.ts +24 -7
  86. package/dist/extensions/installer.js +142 -66
  87. package/dist/extensions/installer.js.map +1 -1
  88. package/dist/extensions/registry.js +3 -5
  89. package/dist/extensions/registry.js.map +1 -1
  90. package/dist/extensions/state-contract.d.ts +11 -0
  91. package/dist/extensions/state-contract.js +50 -0
  92. package/dist/extensions/state-contract.js.map +1 -0
  93. package/dist/instances.d.ts +13 -1
  94. package/dist/instances.js +26 -0
  95. package/dist/instances.js.map +1 -1
  96. package/dist/package-manager.d.ts +0 -24
  97. package/dist/package-manager.js +5 -58
  98. package/dist/package-manager.js.map +1 -1
  99. package/dist/project-tool-discovery.d.ts +5 -2
  100. package/dist/project-tool-discovery.js +22 -18
  101. package/dist/project-tool-discovery.js.map +1 -1
  102. package/dist/runtime-code.js +1 -1
  103. package/dist/runtime-code.js.map +1 -1
  104. package/dist/tool-name.d.ts +4 -0
  105. package/dist/tool-name.js +15 -0
  106. package/dist/tool-name.js.map +1 -0
  107. package/dist/tools/.generated-completion-registry.d.ts +2 -0
  108. package/dist/tools/.generated-completion-registry.js +763 -325
  109. package/dist/tools/.generated-completion-registry.js.map +1 -1
  110. package/dist/tools/.generated-registry.d.ts +6 -11
  111. package/dist/tools/.generated-registry.js +6 -11
  112. package/dist/tools/.generated-registry.js.map +1 -1
  113. package/dist/tools/.generated-schemas.js +11 -16
  114. package/dist/tools/.generated-schemas.js.map +1 -1
  115. package/dist/tools/asset/refresh-status.d.ts +3 -0
  116. package/dist/tools/asset/refresh-status.js +12 -0
  117. package/dist/tools/asset/refresh-status.js.map +1 -0
  118. package/dist/tools/asset/refresh.js +7 -3
  119. package/dist/tools/asset/refresh.js.map +1 -1
  120. package/dist/tools/build/player-status.d.ts +3 -0
  121. package/dist/tools/build/player-status.js +12 -0
  122. package/dist/tools/build/player-status.js.map +1 -0
  123. package/dist/tools/build/run.js +1 -1
  124. package/dist/tools/build/run.js.map +1 -1
  125. package/dist/tools/catalog-control.d.ts +22 -0
  126. package/dist/tools/catalog-control.js +335 -0
  127. package/dist/tools/catalog-control.js.map +1 -0
  128. package/dist/tools/catalog.d.ts +7 -9
  129. package/dist/tools/catalog.js +66 -45
  130. package/dist/tools/catalog.js.map +1 -1
  131. package/dist/tools/commands.d.ts +1 -1
  132. package/dist/tools/commands.js +44 -11
  133. package/dist/tools/commands.js.map +1 -1
  134. package/dist/tools/define.js +3 -2
  135. package/dist/tools/define.js.map +1 -1
  136. package/dist/tools/dispatcher.d.ts +53 -6
  137. package/dist/tools/dispatcher.js +277 -108
  138. package/dist/tools/dispatcher.js.map +1 -1
  139. package/dist/tools/editor/compile.js +1 -1
  140. package/dist/tools/editor/compile.js.map +1 -1
  141. package/dist/tools/editor/play-mode-status.d.ts +3 -0
  142. package/dist/tools/editor/play-mode-status.js +12 -0
  143. package/dist/tools/editor/play-mode-status.js.map +1 -0
  144. package/dist/tools/editor/readiness.d.ts +0 -1
  145. package/dist/tools/editor/readiness.js +0 -1
  146. package/dist/tools/editor/readiness.js.map +1 -1
  147. package/dist/tools/editor/refresh.d.ts +7 -3
  148. package/dist/tools/editor/refresh.js +20 -15
  149. package/dist/tools/editor/refresh.js.map +1 -1
  150. package/dist/tools/editor/state.d.ts +2 -2
  151. package/dist/tools/editor/state.js +13 -12
  152. package/dist/tools/editor/state.js.map +1 -1
  153. package/dist/tools/metadata/derived.js +1 -7
  154. package/dist/tools/metadata/derived.js.map +1 -1
  155. package/dist/tools/metadata/status.js +1 -12
  156. package/dist/tools/metadata/status.js.map +1 -1
  157. package/dist/tools/metadata/types.d.ts +0 -2
  158. package/dist/tools/navmesh/live.js +1 -1
  159. package/dist/tools/navmesh/live.js.map +1 -1
  160. package/dist/tools/occlusion/live.js +1 -1
  161. package/dist/tools/occlusion/live.js.map +1 -1
  162. package/dist/tools/package/deploy.js +2 -2
  163. package/dist/tools/package/deploy.js.map +1 -1
  164. package/dist/tools/package/embed.js +1 -1
  165. package/dist/tools/package/embed.js.map +1 -1
  166. package/dist/tools/package/install-status.d.ts +3 -0
  167. package/dist/tools/package/install-status.js +12 -0
  168. package/dist/tools/package/install-status.js.map +1 -0
  169. package/dist/tools/package/install.js +3 -3
  170. package/dist/tools/package/install.js.map +1 -1
  171. package/dist/tools/package/live-resolve.js +45 -12
  172. package/dist/tools/package/live-resolve.js.map +1 -1
  173. package/dist/tools/package/registry-clear.js.map +1 -1
  174. package/dist/tools/package/registry-set.js.map +1 -1
  175. package/dist/tools/package/remove-status.d.ts +3 -0
  176. package/dist/tools/package/remove-status.js +12 -0
  177. package/dist/tools/package/remove-status.js.map +1 -0
  178. package/dist/tools/package/remove.js +3 -3
  179. package/dist/tools/package/remove.js.map +1 -1
  180. package/dist/tools/package/resolve.js +3 -3
  181. package/dist/tools/package/resolve.js.map +1 -1
  182. package/dist/tools/package/restore.js +2 -2
  183. package/dist/tools/package/restore.js.map +1 -1
  184. package/dist/tools/package/scoped-registry-add.js.map +1 -1
  185. package/dist/tools/status/support.d.ts +13 -0
  186. package/dist/tools/status/support.js +28 -0
  187. package/dist/tools/status/support.js.map +1 -0
  188. package/dist/tools/test/cancel.js +2 -2
  189. package/dist/tools/test/cancel.js.map +1 -1
  190. package/dist/tools/test/run-status.d.ts +3 -0
  191. package/dist/tools/test/run-status.js +12 -0
  192. package/dist/tools/test/run-status.js.map +1 -0
  193. package/dist/tools/test/run.js +7 -4
  194. package/dist/tools/test/run.js.map +1 -1
  195. package/dist/tools/tools/group-summaries.js +10 -14
  196. package/dist/tools/tools/group-summaries.js.map +1 -1
  197. package/docs/architecture.md +4 -4
  198. package/docs/availability-differences.md +4 -4
  199. package/docs/command-execution.md +4 -3
  200. package/docs/error-codes.md +13 -5
  201. package/docs/extensions.md +1 -7
  202. package/docs/risk-and-side-effects.md +4 -3
  203. package/docs/safety-boundaries.md +3 -1
  204. package/docs/target-and-instance.md +1 -1
  205. package/docs/tool-discovery.md +17 -10
  206. package/docs/tool-execution.md +18 -7
  207. package/extensions/cinemachine/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  208. package/extensions/hdrp/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  209. package/extensions/probuilder/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  210. package/extensions/urp/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  211. package/extensions/vfx-graph/unitypkg/Editor/UnityCliExtensionAssembly.cs +3 -0
  212. package/package.json +2 -4
  213. package/skills/unitycli/SKILL.md +11 -2
  214. package/skills/unitycli/manifest.json +1 -1
  215. package/skills/unitycli/references/operation-protocol.md +3 -3
  216. package/unitypkg/Editor/AssemblyInfo.cs +5 -0
  217. package/unitypkg/Editor/Bridge/BridgeCommandRegistry.cs +49 -14
  218. package/unitypkg/Editor/Bridge/BridgeHttpServer.cs +9 -35
  219. package/unitypkg/Editor/Bridge/BridgeQueueState.cs +672 -0
  220. package/unitypkg/Editor/Bridge/BridgeWorkQueue.cs +970 -120
  221. package/unitypkg/Editor/BridgeStartupStateMachine.cs +59 -1
  222. package/unitypkg/Editor/Commands/ProjectToolCommands.cs +4 -0
  223. package/unitypkg/Editor/Commands/RuntimeToolCommands.cs +3 -0
  224. package/unitypkg/Editor/Generated/UnityCliToolCompletionRegistry.g.cs +379 -14
  225. package/unitypkg/Editor/Infrastructure/CodeExecSupport.cs +28 -13
  226. package/unitypkg/Editor/Infrastructure/RegistryOwnershipResolver.cs +132 -105
  227. package/unitypkg/Editor/Infrastructure/UnityCliActiveOperation.cs +138 -29
  228. package/unitypkg/Editor/Infrastructure/UnityCliAdmission.cs +1856 -237
  229. package/unitypkg/Editor/Infrastructure/UnityCliDoctorDiagnostics.cs +220 -0
  230. package/unitypkg/Editor/Infrastructure/UnityCliDurableStatusCoordinator.cs +118 -0
  231. package/unitypkg/Editor/Infrastructure/UnityCliEditorStateSnapshot.cs +2 -1
  232. package/unitypkg/Editor/Infrastructure/UnityCliHierarchyPager.cs +203 -0
  233. package/unitypkg/Editor/Infrastructure/UnityCliInstanceCleanup.cs +2 -1
  234. package/unitypkg/Editor/Infrastructure/UnityCliInstanceRegistry.cs +201 -63
  235. package/unitypkg/Editor/Infrastructure/UnityCliJson.cs +2 -3
  236. package/unitypkg/Editor/Infrastructure/UnityCliLiveBuildCoordinator.cs +289 -46
  237. package/unitypkg/Editor/Infrastructure/UnityCliLiveRefreshCoordinator.cs +87 -53
  238. package/unitypkg/Editor/Infrastructure/UnityCliNavMeshBakeCoordinator.cs +4 -4
  239. package/unitypkg/Editor/Infrastructure/UnityCliObjectRef.cs +128 -25
  240. package/unitypkg/Editor/Infrastructure/UnityCliObjectSerializer.cs +435 -327
  241. package/unitypkg/Editor/Infrastructure/UnityCliOcclusionBakeCoordinator.cs +4 -4
  242. package/unitypkg/Editor/Infrastructure/UnityCliOperationCoordinator.cs +351 -53
  243. package/unitypkg/Editor/Infrastructure/UnityCliPackageResolveCoordinator.cs +118 -18
  244. package/unitypkg/Editor/Infrastructure/UnityCliPackageResolveState.cs +20 -1
  245. package/unitypkg/Editor/Infrastructure/UnityCliReadGeneration.cs +97 -0
  246. package/unitypkg/Editor/Infrastructure/UnityCliReflection.cs +644 -133
  247. package/unitypkg/Editor/Infrastructure/UnityCliReloadOperation.cs +128 -41
  248. package/unitypkg/Editor/Infrastructure/UnityCliRuntimeExecutor.cs +14 -84
  249. package/unitypkg/Editor/Infrastructure/UnityCliSerializer.cs +220 -0
  250. package/unitypkg/Editor/Infrastructure/UnityCliSessionMutationLease.cs +69 -29
  251. package/unitypkg/Editor/Infrastructure/UnityCliTestRunCoordinator.cs +440 -54
  252. package/unitypkg/Editor/Infrastructure/UnityCliWaiter.cs +128 -35
  253. package/unitypkg/Editor/ProjectTools/IUnityCliTool.cs +9 -1
  254. package/unitypkg/Editor/ProjectTools/OfficialAttributeToolRegistry.cs +32 -31
  255. package/unitypkg/Editor/ProjectTools/ProjectToolRegistry.cs +607 -458
  256. package/unitypkg/Editor/ProjectTools/ProjectToolSchemaValidator.cs +35 -7
  257. package/unitypkg/Editor/ProjectTools/RegisteredTool.cs +501 -60
  258. package/unitypkg/Editor/ProjectTools/UnityCliProjectToolContext.cs +21 -0
  259. package/unitypkg/Editor/ProjectTools/UnityCliSchemaDeriver.cs +36 -7
  260. package/unitypkg/Editor/ProjectTools/UnityCliToolName.cs +30 -0
  261. package/unitypkg/Editor/Properties/AssemblyInfo.cs +3 -0
  262. package/unitypkg/Editor/Tools/asset/get-data.cs +16 -7
  263. package/unitypkg/Editor/Tools/build/BuildSceneStateTool.cs +23 -3
  264. package/unitypkg/Editor/Tools/build/BuildToolDtos.cs +2 -1
  265. package/unitypkg/Editor/Tools/build/scene/add.cs +6 -3
  266. package/unitypkg/Editor/Tools/build/scene/disable.cs +1 -1
  267. package/unitypkg/Editor/Tools/build/scene/enable.cs +1 -1
  268. package/unitypkg/Editor/Tools/build/scene/list.cs +1 -1
  269. package/unitypkg/Editor/Tools/build/scene/remove.cs +13 -3
  270. package/unitypkg/Editor/Tools/camera/CameraToolSupport.cs +38 -38
  271. package/unitypkg/Editor/Tools/camera/multiview.cs +13 -6
  272. package/unitypkg/Editor/Tools/camera/screenshot.cs +14 -7
  273. package/unitypkg/Editor/Tools/component/get.cs +16 -9
  274. package/unitypkg/Editor/Tools/component/modify.cs +6 -4
  275. package/unitypkg/Editor/Tools/console/clear.cs +7 -6
  276. package/unitypkg/Editor/Tools/console/get.cs +48 -16
  277. package/unitypkg/Editor/Tools/editor/EditorToolSupport.cs +143 -28
  278. package/unitypkg/Editor/Tools/editor/menu-items.cs +1 -1
  279. package/unitypkg/Editor/Tools/editor/play.cs +2 -11
  280. package/unitypkg/Editor/Tools/editor/selection.cs +1 -1
  281. package/unitypkg/Editor/Tools/editor/stop.cs +2 -11
  282. package/unitypkg/Editor/Tools/editor/windows.cs +1 -1
  283. package/unitypkg/Editor/Tools/go/GameObjectToolSupport.cs +54 -4
  284. package/unitypkg/Editor/Tools/go/delete.cs +1 -1
  285. package/unitypkg/Editor/Tools/go/find.cs +167 -70
  286. package/unitypkg/Editor/Tools/graphics/GraphicsToolSupport.cs +25 -0
  287. package/unitypkg/Editor/Tools/graphics/light-probe-group.cs +9 -3
  288. package/unitypkg/Editor/Tools/graphics/pipeline-info.cs +1 -1
  289. package/unitypkg/Editor/Tools/graphics/pipeline-settings.cs +1 -1
  290. package/unitypkg/Editor/Tools/graphics/quality.cs +2 -2
  291. package/unitypkg/Editor/Tools/graphics/reflection-probe.cs +3 -3
  292. package/unitypkg/Editor/Tools/graphics/stats.cs +1 -1
  293. package/unitypkg/Editor/Tools/object/ObjectToolSupport.cs +4 -4
  294. package/unitypkg/Editor/Tools/object/get-data.cs +9 -7
  295. package/unitypkg/Editor/Tools/object/modify.cs +7 -5
  296. package/unitypkg/Editor/Tools/physics/raycast.cs +24 -6
  297. package/unitypkg/Editor/Tools/prefab/stage.cs +1 -1
  298. package/unitypkg/Editor/Tools/profiler/ProfilerFrameDebuggerSupport.cs +94 -21
  299. package/unitypkg/Editor/Tools/profiler/ProfilerMemorySnapshotSupport.cs +397 -10
  300. package/unitypkg/Editor/Tools/profiler/ProfilerToolSupport.cs +18 -4
  301. package/unitypkg/Editor/Tools/profiler/frame-debugger/enable.cs +1 -1
  302. package/unitypkg/Editor/Tools/profiler/frame-debugger/events.cs +88 -87
  303. package/unitypkg/Editor/Tools/profiler/hierarchy.cs +278 -112
  304. package/unitypkg/Editor/Tools/profiler/memory-snapshot/compare.cs +9 -5
  305. package/unitypkg/Editor/Tools/profiler/memory-snapshot/list.cs +37 -35
  306. package/unitypkg/Editor/Tools/profiler/memory-snapshot/take.cs +99 -97
  307. package/unitypkg/Editor/Tools/project/info.cs +1 -1
  308. package/unitypkg/Editor/Tools/project/layers.cs +1 -1
  309. package/unitypkg/Editor/Tools/project/tags.cs +1 -1
  310. package/unitypkg/Editor/Tools/reflection/method/call.cs +9 -7
  311. package/unitypkg/Editor/Tools/reflection/method/find.cs +27 -37
  312. package/unitypkg/Editor/Tools/reflection/type/schema.cs +24 -28
  313. package/unitypkg/Editor/Tools/scene/gameobject/component.cs +8 -5
  314. package/unitypkg/Editor/Tools/scene/gameobject/components.cs +10 -7
  315. package/unitypkg/Editor/Tools/scene/gameobject-support.cs +104 -8
  316. package/unitypkg/Editor/Tools/scene/gameobject.cs +37 -16
  317. package/unitypkg/Editor/Tools/scene/hierarchy.cs +146 -142
  318. package/unitypkg/Editor/Tools/screenshot/EditorElementCaptureToolSupport.cs +77 -25
  319. package/unitypkg/Editor/Tools/screenshot/ScreenshotToolSupport.cs +315 -95
  320. package/unitypkg/Editor/Tools/screenshot/editor-element.cs +7 -5
  321. package/unitypkg/Editor/Tools/screenshot/game-view.cs +35 -21
  322. package/unitypkg/Editor/Tools/screenshot/isolated-object.cs +29 -23
  323. package/unitypkg/Editor/Tools/screenshot/orbit.cs +37 -25
  324. package/unitypkg/Editor/Tools/screenshot/scene-view.cs +25 -18
  325. package/unitypkg/Editor/Tools/screenshot/screen.cs +177 -17
  326. package/unitypkg/Editor/Tools/screenshot/surround.cs +83 -79
  327. package/unitypkg/Editor/Tools/ui/render-preview.cs +16 -11
  328. package/unitypkg/Editor/UnityCliBridge.cs +97 -34
  329. package/unitypkg/Runtime/Infrastructure/UnityCliRuntimeBridge.cs +753 -122
  330. package/unitypkg/Runtime/Properties/AssemblyInfo.cs +5 -0
  331. package/unitypkg/Runtime/UnityCli.Runtime.asmdef +1 -1
  332. package/unitypkg/Shared/AssemblyInfo.cs +4 -0
  333. package/unitypkg/Shared/UnityCliAdmissionPool.cs +265 -75
  334. package/unitypkg/Shared/UnityCliBridgeQueuePolicy.cs +410 -0
  335. package/unitypkg/Shared/UnityCliBridgeWorkItemState.cs +47 -0
  336. package/unitypkg/Shared/UnityCliExceptionProjection.cs +151 -0
  337. package/unitypkg/Shared/UnityCliQueuePublication.cs +30 -0
  338. package/unitypkg/Shared/UnityCliRequestBudget.cs +352 -0
  339. package/unitypkg/Shared/UnityCliRuntimeRequestPublication.cs +107 -0
  340. package/unitypkg/Tests/Editor/UnityCli.Editor.Tests.asmdef +2 -2
  341. package/unitypkg/Tests/Editor/UnityCliAdmissionCoordinatorIntegrationTests.cs +1329 -0
  342. package/unitypkg/Tests/Editor/UnityCliAdmissionPoolTests.cs +311 -114
  343. package/unitypkg/Tests/Editor/UnityCliAdmissionRepairStateTests.cs +94 -0
  344. package/unitypkg/Tests/Editor/UnityCliBridgeAdmissionIntegrationTests.cs +1229 -0
  345. package/unitypkg/Tests/Editor/UnityCliBridgeQueuePolicyTests.cs +412 -0
  346. package/unitypkg/Tests/Editor/UnityCliContinuationIntegrationTests.cs +292 -0
  347. package/unitypkg/Tests/Editor/UnityCliDiagnosticBoundaryTests.cs +120 -0
  348. package/unitypkg/Tests/Editor/UnityCliDurableStatusTests.cs +84 -0
  349. package/unitypkg/Tests/Editor/UnityCliExceptionProjectionTests.cs +72 -0
  350. package/unitypkg/Tests/Editor/UnityCliInstancePublicationRetryTests.cs +180 -97
  351. package/unitypkg/Tests/Editor/UnityCliMemoryReflectionIntegrationTests.cs +434 -0
  352. package/unitypkg/Tests/Editor/UnityCliRequestBudgetTests.cs +615 -0
  353. package/unitypkg/Tests/Editor/UnityCliRuntimeBridgeIntegrationTests.cs +520 -0
  354. package/unitypkg/Tests/Editor/UnityCliToolCatalogTests.cs +562 -0
  355. package/unitypkg/Tests/Runtime/UnityCli.Runtime.Tests.asmdef +23 -0
  356. package/unitypkg/Tests/Runtime/UnityCliRuntimeCatalogValidationTests.cs +29 -0
  357. package/unitypkg/package.json +1 -1
  358. package/contracts/static-capability-catalog.json +0 -48226
  359. package/dist/bridge/domains/diagnose.d.ts +0 -2
  360. package/dist/bridge/domains/diagnose.js +0 -11
  361. package/dist/bridge/domains/diagnose.js.map +0 -1
  362. package/dist/bridge/domains/extension.d.ts +0 -8
  363. package/dist/bridge/domains/extension.js +0 -20
  364. package/dist/bridge/domains/extension.js.map +0 -1
  365. package/dist/capabilities.d.ts +0 -5
  366. package/dist/capabilities.js +0 -84
  367. package/dist/capabilities.js.map +0 -1
  368. package/dist/static-capability-catalog.d.ts +0 -13
  369. package/dist/static-capability-catalog.js +0 -41
  370. package/dist/static-capability-catalog.js.map +0 -1
  371. package/dist/tools/diagnose/capabilities.d.ts +0 -13
  372. package/dist/tools/diagnose/capabilities.js +0 -34
  373. package/dist/tools/diagnose/capabilities.js.map +0 -1
  374. package/dist/tools/package/info.d.ts +0 -19
  375. package/dist/tools/package/info.js +0 -27
  376. package/dist/tools/package/info.js.map +0 -1
  377. package/dist/tools/package/list.d.ts +0 -27
  378. package/dist/tools/package/list.js +0 -21
  379. package/dist/tools/package/list.js.map +0 -1
  380. package/dist/tools/package/registry-get.d.ts +0 -10
  381. package/dist/tools/package/registry-get.js +0 -22
  382. package/dist/tools/package/registry-get.js.map +0 -1
  383. package/dist/tools/package/scoped-registry-list.d.ts +0 -14
  384. package/dist/tools/package/scoped-registry-list.js +0 -22
  385. package/dist/tools/package/scoped-registry-list.js.map +0 -1
  386. package/dist/tools/package/search.d.ts +0 -17
  387. package/dist/tools/package/search.js +0 -39
  388. package/dist/tools/package/search.js.map +0 -1
  389. package/dist/tools/package/status.d.ts +0 -21
  390. package/dist/tools/package/status.js +0 -37
  391. package/dist/tools/package/status.js.map +0 -1
  392. package/dist/tools/tools/describe.d.ts +0 -27
  393. package/dist/tools/tools/describe.js +0 -35
  394. package/dist/tools/tools/describe.js.map +0 -1
  395. package/dist/tools/tools/group-list.d.ts +0 -16
  396. package/dist/tools/tools/group-list.js +0 -38
  397. package/dist/tools/tools/group-list.js.map +0 -1
  398. package/dist/tools/tools/group.d.ts +0 -13
  399. package/dist/tools/tools/group.js +0 -34
  400. package/dist/tools/tools/group.js.map +0 -1
  401. package/dist/tools/tools/pagination.d.ts +0 -17
  402. package/dist/tools/tools/pagination.js +0 -28
  403. package/dist/tools/tools/pagination.js.map +0 -1
  404. package/dist/tools/tools/search.d.ts +0 -15
  405. package/dist/tools/tools/search.js +0 -42
  406. package/dist/tools/tools/search.js.map +0 -1
  407. package/unitypkg/Editor/Tools/diagnose/preflight.cs +0 -269
  408. package/unitypkg/Editor/Tools/editor/console.cs +0 -26
  409. package/unitypkg/Editor/Tools/extension/status.cs +0 -87
  410. package/unitypkg/Editor/Tools/go/inspect.cs +0 -49
  411. package/unitypkg/Editor/Tools/graphics/pipeline-quality.cs +0 -24
  412. package/unitypkg/Editor/Tools/graphics/probe-positions.cs +0 -58
  413. package/unitypkg/Editor/Tools/graphics/settings.cs +0 -104
  414. package/unitypkg/Editor/Tools/graphics/stats-counters.cs +0 -28
  415. package/unitypkg/Editor/Tools/graphics/stats-memory.cs +0 -21
  416. package/unitypkg/Editor/Tools/instances/list.cs +0 -71
  417. package/unitypkg/Editor/Tools/physics/raycast-all.cs +0 -67
  418. package/unitypkg/Editor/Tools/scene/build-settings.cs +0 -69
  419. package/unitypkg/Editor/Tools/scene/data.cs +0 -125
  420. package/unitypkg/Editor/Tools/tests/list.cs +0 -98
@@ -1,146 +1,148 @@
1
1
  #if UNITY_EDITOR
2
2
  using System;
3
3
  using System.Collections.Generic;
4
- using System.Globalization;
5
4
  using System.IO;
6
5
  using System.Reflection;
7
6
  using System.Threading;
8
7
  using System.Threading.Tasks;
9
- using UnityEditor;
10
- using UnityEngine;
11
8
 
12
9
  namespace UnityCli
13
10
  {
14
- /// <summary>
15
- /// profiler.memory-snapshot.take — 采集内存快照(.snap)。
16
- /// MemoryProfiler.TakeSnapshot 的未来帧回调通过统一 wait scheduler 承接。
17
- /// </summary>
11
+ /// <summary>profiler.memory-snapshot.take — governed pending publication 与唯一 callback terminal。</summary>
18
12
  public class ProfilerMemorySnapshotTakeTool : IUnityCliTool<ProfilerMemorySnapshotTakeTool.Request, ProfilerMemorySnapshotTakeTool.Result>
19
13
  {
20
14
  public sealed class Request
21
15
  {
22
16
  public string Path { get; set; }
17
+ [UnityCliRange(1048576L, ProfilerMemorySnapshotSupport.AbsoluteSnapshotBytes)] public long? MaxBytes { get; set; }
18
+ public UnityCliReadBudgetInput Budget { get; set; }
23
19
  }
24
20
 
25
21
  public sealed class Result
26
22
  {
23
+ public string Path { get; set; }
27
24
  public long SizeBytes { get; set; }
28
- public List<ProfilerPlannedEffect> PlannedEffects { get; set; }
25
+ public long RetainedCountLimit { get; set; }
26
+ public long RetainedBytesLimit { get; set; }
27
+ [UnityCliItemsRange(0, 1)] public List<ProfilerPlannedEffect> PlannedEffects { get; set; }
29
28
  }
30
29
 
31
30
  public ToolDescriptor Describe() => new()
32
31
  {
33
32
  Name = "profiler.memory-snapshot.take",
34
- Summary = "Capture a memory snapshot (.snap) via MemoryProfiler using the unified callback wait path.",
35
- Description = "Capture a memory snapshot (.snap) via MemoryProfiler. Requires package com.unity.memoryprofiler. The tool waits for TakeSnapshot's future-frame callback through the framework wait scheduler instead of a custom deferred interface.",
36
- Group = "profiler",DestructiveHint = true, SideEffects = new[] { "memory-snapshot-write" }, Target = "editor", PlayModeSupport = "supported",
37
- RequiresPackages = new[] { "com.unity.memoryprofiler" },
38
- DefaultTimeoutMs = 30000, MaxTimeoutMs = 600000,
39
- Examples = new[] { new ToolExample { Description = "Take a memory snapshot to a custom path", Input = new Request { Path = "Artifacts/snap1.snap" } } }
33
+ Summary = "Capture one governed Memory Profiler snapshot with bounded retention and one callback terminal.",
34
+ Description = "Capture a .snap artifact only under Library/UnityCli/memory-snapshots. path is a file name, not a directory. maxBytes defaults to and cannot exceed 4 GiB. Successful publication keeps the newest 100 snapshots while enforcing an 8 GiB directory ceiling. A pending same-root file is atomically moved only after a successful non-empty callback; timeout, cancellation, domain reload, late callback and write faults share one terminal and clean pending/orphan files. Requires com.unity.memoryprofiler. Available in Edit and Play Mode; it writes a project-local Library artifact but no Assets content.",
35
+ Group = "profiler", DestructiveHint = false, SideEffects = new[] { "memory-snapshot-write" }, Target = "editor", PlayModeSupport = "supported",
36
+ RequiresPackages = new[] { "com.unity.memoryprofiler" }, DefaultTimeoutMs = 30000, MaxTimeoutMs = 600000,
37
+ Examples = new[] { new ToolExample { Description = "Take a governed snapshot", Input = new Request { Path = "capture.snap", MaxBytes = 1073741824L } } }
40
38
  };
41
39
 
42
40
  public async ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, CancellationToken ct = default)
43
41
  {
44
- var profilerType = ProfilerToolSupport.MemoryProfilerType();
45
- if (profilerType == null)
46
- {
47
- throw new UnityCliBridge.BridgeCommandException("E_PROFILER_PACKAGE_MISSING",
48
- "Package com.unity.memoryprofiler is required for memory snapshots.",
49
- "Install com.unity.memoryprofiler via the Package Manager.");
50
- }
51
-
52
- var outputPath = request.Path;
53
- if (string.IsNullOrEmpty(outputPath))
54
- {
55
- var dir = Path.Combine(Application.temporaryCachePath, "MemoryCaptures");
56
- Directory.CreateDirectory(dir);
57
- outputPath = Path.Combine(dir, "snapshot_" + DateTime.Now.ToString("yyyyMMdd_HHmmss", CultureInfo.InvariantCulture) + ".snap");
58
- }
59
-
60
- var callbackType = typeof(Action<string, bool>);
61
- var captureFlagsType = ProfilerToolSupport.FindType("Unity.Profiling.Memory.CaptureFlags")
62
- ?? ProfilerToolSupport.FindType("UnityEngine.Profiling.Memory.Experimental.CaptureFlags");
63
- MethodInfo takeMethod = null;
64
- object[] invokeArgs = null;
65
- if (captureFlagsType != null)
42
+ request = request ?? new Request();
43
+ var requestBudget = ctx.UseReadBudget(request.Budget);
44
+ requestBudget.CheckpointOrThrow();
45
+ var profilerType = ProfilerToolSupport.MemoryProfilerType(requestBudget);
46
+ if (profilerType == null) throw new UnityCliBridge.BridgeCommandException("E_PROFILER_PACKAGE_MISSING", "Package com.unity.memoryprofiler is required for memory snapshots.", "Install com.unity.memoryprofiler through Package Manager.");
47
+ var finalPath = ProfilerMemorySnapshotSupport.ResolveFinalPath(request.Path, ctx.RequestId);
48
+ if (File.Exists(finalPath)) throw new UnityCliBridge.BridgeCommandException("E_OUTPUT_EXISTS", "Snapshot output already exists: " + finalPath, "Choose another .snap file name.");
49
+ var maxBytes = request.MaxBytes ?? ProfilerMemorySnapshotSupport.AbsoluteSnapshotBytes;
50
+ var pendingPath = ProfilerMemorySnapshotSupport.AcquirePendingPath(ctx.RequestId);
51
+ SnapshotBinding binding;
52
+ try
66
53
  {
67
- takeMethod = profilerType.GetMethod("TakeSnapshot", new[] { typeof(string), callbackType, captureFlagsType });
54
+ binding = ResolveTakeSnapshot(profilerType, pendingPath, requestBudget);
55
+ ctx.CommitEffect();
68
56
  }
69
- if (takeMethod != null)
57
+ catch
70
58
  {
71
- invokeArgs = new object[] { outputPath, null, Enum.ToObject(captureFlagsType, 0) };
59
+ ProfilerMemorySnapshotSupport.ReleasePendingPath(pendingPath);
60
+ throw;
72
61
  }
73
- else
62
+ try
74
63
  {
75
- takeMethod = profilerType.GetMethod("TakeSnapshot", new[] { typeof(string), callbackType });
76
- }
77
- if (takeMethod == null)
78
- {
79
- throw new UnityCliBridge.BridgeCommandException("E_PROFILER_API_UNSUPPORTED",
80
- "MemoryProfiler.TakeSnapshot API not found.",
81
- "The installed com.unity.memoryprofiler version may be incompatible.");
82
- }
83
-
84
- ctx.CommitEffect();
85
- return await ctx.Wait.ForCallback<Result>((complete, fail) =>
86
- {
87
- var callback = new Action<string, bool>((capturedPath, captureResult) =>
64
+ var result = await ctx.Wait.ForCallback<Result>((complete, fail) =>
88
65
  {
89
- try
66
+ var callback = new Action<string, bool>((capturedPath, succeeded) =>
90
67
  {
91
- if (!captureResult)
68
+ try
92
69
  {
93
- fail(new UnityCliBridge.BridgeCommandException("E_PROFILER_SNAPSHOT_FAILED",
94
- "Snapshot capture reported failure for path: " + outputPath,
95
- "Check Unity Console for Memory Profiler errors."));
96
- return;
70
+ var accepted = complete(() =>
71
+ {
72
+ requestBudget.ResumeAfterWait();
73
+ requestBudget.CheckpointOrThrow();
74
+ if (!succeeded) throw ProfilerMemorySnapshotSupport.Error("E_PROFILER_SNAPSHOT_FAILED", "MemoryProfiler reported snapshot failure.", "Inspect Unity Console before retrying.");
75
+ var info = ProfilerMemorySnapshotSupport.Publish(capturedPath, pendingPath, finalPath, maxBytes, requestBudget);
76
+ if (!requestBudget.TryConsumeGetter()) throw new UnityCliRequestBudgetExceededException(requestBudget.ExhaustedDimension);
77
+ return new Result
78
+ {
79
+ Path = finalPath,
80
+ SizeBytes = info.Length,
81
+ RetainedCountLimit = ProfilerMemorySnapshotSupport.RetainedSnapshotCount,
82
+ RetainedBytesLimit = ProfilerMemorySnapshotSupport.RetainedSnapshotBytes,
83
+ PlannedEffects = new List<ProfilerPlannedEffect> { new ProfilerPlannedEffect { Type = "profiler.memory-snapshot.take", Path = finalPath } }
84
+ };
85
+ });
86
+ if (!accepted) ProfilerMemorySnapshotSupport.RequestPendingCleanup(pendingPath);
97
87
  }
98
-
99
- var finalPath = capturedPath ?? outputPath;
100
- var info = new FileInfo(finalPath);
101
- if (!info.Exists || info.Length <= 0)
88
+ finally
102
89
  {
103
- fail(new UnityCliBridge.BridgeCommandException("E_PROFILER_SNAPSHOT_ARTIFACT_MISSING",
104
- "MemoryProfiler reported success without a non-empty snapshot artifact: " + finalPath,
105
- "Check available disk space and the Unity Console, then retry the snapshot."));
106
- return;
90
+ ProfilerMemorySnapshotSupport.ReleasePendingPath(pendingPath);
107
91
  }
108
- complete(new Result
109
- {
110
- SizeBytes = info.Length,
111
- PlannedEffects = new List<ProfilerPlannedEffect> { new ProfilerPlannedEffect { Type = "profiler.memory-snapshot.take", Path = finalPath } }
112
- });
92
+ });
93
+ binding.SetCallback(callback);
94
+ try { binding.Invoke(); }
95
+ catch (TargetInvocationException exception)
96
+ {
97
+ fail(exception.InnerException ?? exception);
98
+ ProfilerMemorySnapshotSupport.ReleasePendingPath(pendingPath);
113
99
  }
114
100
  catch (Exception exception)
115
101
  {
116
- fail(exception);
102
+ fail(ProfilerMemorySnapshotSupport.Error("E_PROFILER_SNAPSHOT_FAILED", "Snapshot capture failed: " + exception.Message, "Inspect Unity Console and the Memory Profiler package."));
103
+ ProfilerMemorySnapshotSupport.ReleasePendingPath(pendingPath);
117
104
  }
118
- });
105
+ }, TimeSpan.FromMilliseconds(Math.Max(1, ctx.TimeoutMs)), ct, () => ProfilerMemorySnapshotSupport.RequestPendingCleanup(pendingPath));
106
+ requestBudget.ResumeAfterWait();
107
+ return result;
108
+ }
109
+ catch
110
+ {
111
+ ProfilerMemorySnapshotSupport.RequestPendingCleanup(pendingPath);
112
+ throw;
113
+ }
114
+ }
119
115
 
120
- if (invokeArgs != null)
121
- {
122
- invokeArgs[1] = callback;
123
- }
124
- else
125
- {
126
- invokeArgs = new object[] { outputPath, callback };
127
- }
116
+ private static SnapshotBinding ResolveTakeSnapshot(Type profilerType, string pendingPath, UnityCliRequestBudget budget)
117
+ {
118
+ var callbackType = typeof(Action<string, bool>);
119
+ var captureFlagsType = ProfilerToolSupport.FindType("Unity.Profiling.Memory.CaptureFlags", budget)
120
+ ?? ProfilerToolSupport.FindType("UnityEngine.Profiling.Memory.Experimental.CaptureFlags", budget);
121
+ MethodInfo method = null;
122
+ object[] args = null;
123
+ if (captureFlagsType != null)
124
+ {
125
+ if (!budget.TryConsumeReflectionCall()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
126
+ method = profilerType.GetMethod("TakeSnapshot", new[] { typeof(string), callbackType, captureFlagsType });
127
+ }
128
+ if (method != null) args = new object[] { pendingPath, null, Enum.ToObject(captureFlagsType, 0) };
129
+ else
130
+ {
131
+ if (!budget.TryConsumeReflectionCall()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
132
+ method = profilerType.GetMethod("TakeSnapshot", new[] { typeof(string), callbackType });
133
+ if (method != null) args = new object[] { pendingPath, null };
134
+ }
135
+ if (method == null) throw new UnityCliBridge.BridgeCommandException("E_PROFILER_API_UNSUPPORTED", "MemoryProfiler.TakeSnapshot API is unavailable.", "Install a supported com.unity.memoryprofiler version.");
136
+ return new SnapshotBinding(method, args);
137
+ }
128
138
 
129
- try
130
- {
131
- takeMethod.Invoke(null, invokeArgs);
132
- }
133
- catch (TargetInvocationException exception)
134
- {
135
- fail(exception.InnerException ?? exception);
136
- }
137
- catch (Exception exception)
138
- {
139
- fail(new UnityCliBridge.BridgeCommandException("E_PROFILER_SNAPSHOT_FAILED",
140
- "Snapshot capture failed: " + exception.Message,
141
- "Check Unity Console and the Memory Profiler package."));
142
- }
143
- }, TimeSpan.FromSeconds(30), ct);
139
+ private sealed class SnapshotBinding
140
+ {
141
+ private readonly MethodInfo method;
142
+ private readonly object[] args;
143
+ internal SnapshotBinding(MethodInfo method, object[] args) { this.method = method; this.args = args; }
144
+ internal void SetCallback(Action<string, bool> callback) { args[1] = callback; }
145
+ internal void Invoke() { method.Invoke(null, args); }
144
146
  }
145
147
  }
146
148
  }
@@ -25,7 +25,7 @@ namespace UnityCli.Tools.Project
25
25
  {
26
26
  Name = "project.info", Summary = "Project metadata: name, path, Unity version, and overall project structure.",
27
27
  Description = "Project metadata: name, path, Unity version, and overall project structure.",
28
- DestructiveHint = false,
28
+ DestructiveHint = false,
29
29
  Group = "project",
30
30
  Target = "editor",
31
31
  PlayModeSupport = "supported",
@@ -28,7 +28,7 @@ namespace UnityCli.Tools.Project
28
28
  {
29
29
  Name = "project.layers", Summary = "List all layers defined in the project's Tag Manager.",
30
30
  Description = "List all layers defined in the project's Tag Manager.",
31
- DestructiveHint = false,
31
+ DestructiveHint = false,
32
32
  Group = "project",
33
33
  Target = "editor",
34
34
  PlayModeSupport = "supported",
@@ -21,7 +21,7 @@ namespace UnityCli.Tools.Project
21
21
  {
22
22
  Name = "project.tags", Summary = "List all tags defined in the project's Tag Manager.",
23
23
  Description = "List all tags defined in the project's Tag Manager.",
24
- DestructiveHint = false,
24
+ DestructiveHint = false,
25
25
  Group = "project",
26
26
  Target = "editor",
27
27
  PlayModeSupport = "supported",
@@ -16,15 +16,16 @@ namespace UnityCli
16
16
  [UnityCliRequired]
17
17
  public string MethodName { get; set; }
18
18
  [UnityCliAnyJson] public object Args { get; set; }
19
- public List<string> ParameterTypes { get; set; }
19
+ [UnityCliItemsRange(0, 256)] public List<string> ParameterTypes { get; set; }
20
20
  [UnityCliAnyJson] public Dictionary<string, object> InstanceRef { get; set; }
21
21
  [UnityCliRequired] public UnityCliCompletionProbe CompletionProbe { get; set; }
22
+ public UnityCliReadBudgetInput Budget { get; set; }
22
23
  }
23
24
 
24
25
  public sealed class Result
25
26
  {
26
27
  [UnityCliAnyJson] public object Data { get; set; }
27
- public List<PlannedEffect> PlannedEffects { get; set; }
28
+ [UnityCliItemsRange(0, 1)] public List<PlannedEffect> PlannedEffects { get; set; }
28
29
  public UnityCliCompletionProbeReadback Completion { get; set; }
29
30
  }
30
31
 
@@ -39,7 +40,7 @@ namespace UnityCli
39
40
  {
40
41
  Name = "reflection.method.call",
41
42
  Summary = "Call one synchronous C# method in the live Editor and prove declared state through a read Tool.",
42
- Description = "Resolve the exact type, overload, arguments, and optional instance before invoking one synchronous method. completionProbe is mandatory and proves declared before/after state through an eligible read Tool in the same Editor turn. Task/ValueTask, iterator, yield, and AsyncOperation methods are rejected; a method return value is never accepted as completion proof.",
43
+ Description = "Resolve the exact type, overload, arguments, and optional instance under one request budget before invoking one synchronous method. completionProbe is mandatory and proves declared before/after state through an eligible read Tool in the same Editor turn. Candidate methods, parameters, signatures, reflection work, monotonic main-thread time, and output bytes are globally bounded in dry-run and execution. Task/ValueTask, iterator, yield, and AsyncOperation methods are rejected; a method return value is never accepted as completion proof.",
43
44
  Group = "reflection",
44
45
  DestructiveHint = true,
45
46
  SideEffects = new[] { "arbitrary-method-invocation" },
@@ -79,13 +80,14 @@ namespace UnityCli
79
80
  "Run tools run reflection.method.find to discover methods, then retry with the required target fields.");
80
81
  }
81
82
 
83
+ var readBudget = ctx.UseReadBudget(request.Budget);
82
84
  var bindings = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static;
83
- // overload、参数与 instance 都是可预见校验,必须在 effect barrier 前完成。
85
+ // overload、参数与 instance 都是可预见校验,必须在 effect barrier 前完成并使用同一 budget。
84
86
  var prepared = UnityCliBridge.ReflectionInvoker.PrepareCall(
85
87
  request.TypeName, request.MethodName,
86
- request.Args, request.ParameterTypes, request.InstanceRef, bindings);
88
+ request.Args, request.ParameterTypes, request.InstanceRef, bindings, readBudget);
87
89
 
88
- // dry-run 必须在任何反射调用前返回,任意方法即使看似只读也不能在预览阶段执行。
90
+ // dry-run 只完成有界 preparation,不执行目标方法。
89
91
  if (ctx.DryRun)
90
92
  {
91
93
  return new System.Threading.Tasks.ValueTask<Result>(new Result
@@ -98,7 +100,7 @@ namespace UnityCli
98
100
  }
99
101
 
100
102
  Dictionary<string, object> data = null;
101
- var completion = ctx.RunCompletionProbe(request.CompletionProbe, () => data = UnityCliBridge.ReflectionInvoker.InvokePrepared(prepared));
103
+ var completion = ctx.RunCompletionProbe(request.CompletionProbe, () => data = UnityCliBridge.ReflectionInvoker.InvokePrepared(prepared, readBudget));
102
104
  return new System.Threading.Tasks.ValueTask<Result>(new Result
103
105
  {
104
106
  Data = data,
@@ -4,67 +4,57 @@ using System.Reflection;
4
4
 
5
5
  namespace UnityCli
6
6
  {
7
- /// <summary>
8
- /// reflection.method.find — 查找类型的公开/私有/静态/实例方法。只读。
9
- /// </summary>
7
+ /// <summary>reflection.method.find — stable raw method ordinal pagination under one reflection budget。</summary>
10
8
  public class ReflectionMethodFindTool : IUnityCliTool<ReflectionMethodFindTool.Request, ReflectionMethodFindTool.Result>
11
9
  {
12
10
  public sealed class Request
13
11
  {
14
- [UnityCliRequired]
15
- public string TypeName { get; set; }
12
+ [UnityCliRequired] public string TypeName { get; set; }
16
13
  public string MethodName { get; set; }
17
14
  public bool IncludePrivate { get; set; }
18
15
  public bool IncludeStatic { get; set; } = true;
19
16
  public bool IncludeInstance { get; set; } = true;
17
+ [UnityCliRange(1L, 500L)] public int? PageSize { get; set; }
18
+ public string Cursor { get; set; }
19
+ public UnityCliReadBudgetInput Budget { get; set; }
20
20
  }
21
21
 
22
22
  public sealed class Result
23
23
  {
24
- public long Count { get; set; }
24
+ public long Total { get; set; }
25
+ public long ReturnedCount { get; set; }
25
26
  public List<UnityCliBridge.ReflectionMethodDescriptor> Methods { get; set; }
27
+ public string NextCursor { get; set; }
28
+ public bool Truncated { get; set; }
29
+ public string Generation { get; set; }
30
+ public UnityCliRequestBudgetUsage Budget { get; set; }
26
31
  }
27
32
 
28
33
  public ToolDescriptor Describe() => new()
29
34
  {
30
35
  Name = "reflection.method.find",
31
- Summary = "Find C# methods on a type by name; does not limit public/private/static/instance scope.",
32
- Description = "Find methods on a live C# type. Does not limit public/private/static/instance scope. Use the returned signatures to construct reflection.method.call calls. Read-only.",
33
- Group = "reflection",
34
- DestructiveHint = false,
35
- Target = "editor",
36
- PlayModeSupport = "supported",
37
- DefaultTimeoutMs = 30000,
38
- MaxTimeoutMs = 600000,
39
- Examples = new[]
40
- {
41
- new ToolExample { Description = "Find Translate methods on Transform", Input = new Request { TypeName = "UnityEngine.Transform", MethodName = "Translate" } }
42
- }
36
+ Summary = "Page live C# method signatures by exact type/name and visibility/static scope under one reflection budget.",
37
+ Description = "Find methods on one exact live type. includePrivate defaults false; includeStatic/includeInstance default true. pageSize is 1..500 (default 100). Filtering advances over raw MethodInfo ordinals, so sparse searches remain bounded and total is the raw method count rather than a fabricated filtered total. Each method and parameter descriptor consumes the shared scan/node/reflection/monotonic-time/UTF-8 budget; defaults are 10000/4096/4096/250 ms/1 MiB and maxima are 100000/20000/20000/2000 ms/8 MiB. A parameter-heavy method may return parametersTruncated with parameterCount. nextCursor binds type, flags, name filter and listener/assembly generation. Read-only in Edit and Play Mode.",
38
+ Group = "reflection", DestructiveHint = false, Target = "editor", PlayModeSupport = "supported",
39
+ DefaultTimeoutMs = 30000, MaxTimeoutMs = 600000,
40
+ Examples = new[] { new ToolExample { Description = "Find Translate overloads", Input = new Request { TypeName = "UnityEngine.Transform", MethodName = "Translate", PageSize = 100 } } }
43
41
  };
44
42
 
45
43
  public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
46
44
  {
47
- if (string.IsNullOrEmpty(request.TypeName))
48
- {
49
- throw new UnityCliBridge.BridgeCommandException("E_TYPE_NAME_REQUIRED",
50
- "reflection.method.find requires typeName.",
51
- "Pass --input '{\"typeName\":\"UnityEngine.Transform\",\"methodName\":\"Translate\"}'.");
52
- }
53
-
54
- // 构建 BindingFlags:默认包含公开/非公开,按 includeStatic/includeInstance 调整
55
- var bindings = BindingFlags.Public | BindingFlags.NonPublic;
56
- if (request.IncludeStatic) bindings |= BindingFlags.Static;
57
- if (request.IncludeInstance) bindings |= BindingFlags.Instance;
58
- if (!request.IncludePrivate)
59
- {
60
- bindings = BindingFlags.Public | (request.IncludeStatic ? BindingFlags.Static : BindingFlags.Default) | (request.IncludeInstance ? BindingFlags.Instance : BindingFlags.Default);
61
- }
62
-
63
- var methods = UnityCliBridge.ReflectionInvoker.FindMethods(request.TypeName, request.MethodName, bindings);
45
+ if (request == null || string.IsNullOrEmpty(request.TypeName))
46
+ throw new UnityCliBridge.BridgeCommandException("E_TYPE_NAME_REQUIRED", "reflection.method.find requires typeName.", "Pass a full live C# type name.");
47
+ var bindings = (request.IncludePrivate ? BindingFlags.Public | BindingFlags.NonPublic : BindingFlags.Public)
48
+ | (request.IncludeStatic ? BindingFlags.Static : BindingFlags.Default)
49
+ | (request.IncludeInstance ? BindingFlags.Instance : BindingFlags.Default);
50
+ if (!request.IncludeStatic && !request.IncludeInstance)
51
+ throw new UnityCliBridge.BridgeCommandException("E_REFLECTION_SCOPE_INVALID", "At least one of includeStatic/includeInstance must be true.", "Enable static methods, instance methods, or both.");
52
+ var budget = ctx.UseReadBudget(request.Budget);
53
+ var page = UnityCliBridge.ReflectionInvoker.FindMethods(request.TypeName, request.MethodName, bindings, request.PageSize ?? 100, request.Cursor, budget);
64
54
  return new System.Threading.Tasks.ValueTask<Result>(new Result
65
55
  {
66
- Count = methods.Count,
67
- Methods = methods
56
+ Total = page.Total, ReturnedCount = page.Methods.Count, Methods = page.Methods,
57
+ NextCursor = page.NextCursor, Truncated = page.Truncated, Generation = page.Generation, Budget = budget.Usage()
68
58
  });
69
59
  }
70
60
  }
@@ -1,54 +1,50 @@
1
1
  #if UNITY_EDITOR
2
- using System.Collections.Generic;
3
-
4
2
  namespace UnityCli
5
3
  {
6
- /// <summary>
7
- /// type.schema — 为 live C# / Unity 类型生成带 $defs 的 JSON Schema。只读。
8
- /// </summary>
4
+ /// <summary>type.schema — live 类型 schema 的有界成员/definition 分页。</summary>
9
5
  public class TypeSchemaTool : IUnityCliTool<TypeSchemaTool.Request, TypeSchemaTool.Result>
10
6
  {
11
7
  public sealed class Request
12
8
  {
13
- [UnityCliRequired]
14
- public string TypeName { get; set; }
15
- public int MaxDepth { get; set; } = 3;
9
+ [UnityCliRequired] public string TypeName { get; set; }
10
+ [UnityCliRange(0L, 16L)] public int? MaxDepth { get; set; }
11
+ [UnityCliRange(1L, 512L)] public int? MaxMembers { get; set; }
12
+ [UnityCliRange(1L, 256L)] public int? MaxDefinitions { get; set; }
13
+ [UnityCliRange(1L, 256L)] public int? PageSize { get; set; }
14
+ public string Cursor { get; set; }
15
+ public UnityCliReadBudgetInput Budget { get; set; }
16
16
  }
17
17
 
18
18
  public sealed class Result
19
19
  {
20
20
  [UnityCliAnyJson] public object Schema { get; set; }
21
+ public bool Truncated { get; set; }
22
+ public string NextCursor { get; set; }
23
+ public string Generation { get; set; }
24
+ public UnityCliRequestBudgetUsage Budget { get; set; }
21
25
  }
22
26
 
23
27
  public ToolDescriptor Describe() => new()
24
28
  {
25
29
  Name = "type.schema",
26
- Summary = "Generate a JSON Schema for a live C# type with $defs.",
27
- Description = "Generate a JSON Schema (with $defs) for a live C# or Unity type. Read-only. Use the schema to understand the structure of objects before calling object.get-data or object.modify.",
28
- Group = "reflection",
29
- DestructiveHint = false,
30
- Target = "editor",
31
- PlayModeSupport = "supported",
32
- DefaultTimeoutMs = 30000,
33
- MaxTimeoutMs = 600000,
34
- Examples = new[]
35
- {
36
- new ToolExample { Description = "Get schema for Rigidbody", Input = new Request { TypeName = "UnityEngine.Rigidbody" } }
37
- }
30
+ Summary = "Page a live C# type schema under global depth, member, definition, reflection and byte ceilings.",
31
+ Description = "Generate a JSON Schema page for one live C# type. maxDepth is 0..16 (default 3), maxMembers 1..512 (default 256), maxDefinitions 1..256 (default 128), and pageSize 1..256 (default 64). Primitive, enum, array, and dictionary roots use the same classification as recursive values and do not expose continuation; only object roots page bounded public member metadata by raw ordinal. nextCursor binds listener/assembly generation, the member fingerprint, and all structural limits. Recursive definitions, member candidates, interfaces, and friendly type names share the same scan/member/node/reflection/monotonic-time/UTF-8 budget (defaults 10000/4096/4096/250 ms/1 MiB; maxima 100000/20000/20000/2000 ms/8 MiB). Assembly reload or compilation invalidates the bounded type cache and old cursors. Read-only in Edit and Play Mode.",
32
+ Group = "reflection", DestructiveHint = false, Target = "editor", PlayModeSupport = "supported",
33
+ DefaultTimeoutMs = 30000, MaxTimeoutMs = 600000,
34
+ Examples = new[] { new ToolExample { Description = "Read the first Rigidbody schema page", Input = new Request { TypeName = "UnityEngine.Rigidbody", PageSize = 64 } } }
38
35
  };
39
36
 
40
37
  public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
41
38
  {
42
- if (string.IsNullOrEmpty(request.TypeName))
43
- {
44
- throw new UnityCliBridge.BridgeCommandException("E_TYPE_NAME_REQUIRED",
45
- "type.schema requires typeName.",
46
- "Pass --input '{\"typeName\":\"UnityEngine.Rigidbody\"}'.");
47
- }
48
- var schema = UnityCliBridge.TypeSchemaGenerator.Generate(request.TypeName, request.MaxDepth);
39
+ if (request == null || string.IsNullOrEmpty(request.TypeName))
40
+ throw new UnityCliBridge.BridgeCommandException("E_TYPE_NAME_REQUIRED", "type.schema requires typeName.", "Pass a full live C# type name.");
41
+ var budget = ctx.UseReadBudget(request.Budget);
42
+ var page = UnityCliBridge.TypeSchemaGenerator.Generate(request.TypeName, request.MaxDepth ?? 3, request.MaxMembers ?? 256,
43
+ request.MaxDefinitions ?? 128, request.PageSize ?? 64, request.Cursor, budget);
49
44
  return new System.Threading.Tasks.ValueTask<Result>(new Result
50
45
  {
51
- Schema = schema
46
+ Schema = page.Data, Truncated = page.Truncated, NextCursor = page.NextCursor,
47
+ Generation = page.Generation, Budget = budget.Usage()
52
48
  });
53
49
  }
54
50
  }
@@ -8,7 +8,7 @@ namespace UnityCli
8
8
  /// <summary>scene.gameobject.component 只读 Tool:只读一个组件预览。</summary>
9
9
  public sealed class SceneGameObjectComponentTool : IUnityCliTool<SceneGameObjectComponentTool.Request, SceneGameObjectComponentTool.Result>
10
10
  {
11
- public sealed class Request { public string Target { get; set; } public int Id { get; set; } public string Path { get; set; } public string Component { get; set; } }
11
+ public sealed class Request { public string Target { get; set; } public int Id { get; set; } public string Path { get; set; } public string Component { get; set; } public UnityCliReadBudgetInput Budget { get; set; } }
12
12
  public sealed class Result { public GameObjectRef GameObject { get; set; } public ComponentInfo Component { get; set; } }
13
13
  public sealed class GameObjectRef { public long Id { get; set; } public string Name { get; set; } public string Path { get; set; } }
14
14
  public sealed class ComponentInfo
@@ -44,16 +44,19 @@ namespace UnityCli
44
44
  public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
45
45
  {
46
46
  request = request ?? new Request();
47
- var gameObject = ResolveSceneContextGameObject(request.Target, request.Id == 0 ? (int?)null : request.Id, request.Path);
47
+ var budget = ctx.UseReadBudget(request.Budget);
48
+ var gameObject = ResolveSceneContextGameObject(request.Target, request.Id == 0 ? (int?)null : request.Id, request.Path, budget);
48
49
  if (string.IsNullOrEmpty(request.Component))
49
50
  throw new BridgeCommandException("E_COMPONENT_TYPE_REQUIRED", "scene.gameobject.component requires component.", "Pass input component with a Unity component type name.");
50
- var component = ResolveComponent(gameObject, request.Component);
51
+ var component = ResolveSceneContextComponent(gameObject, request.Component, budget);
51
52
  if (component == null)
52
53
  throw new BridgeCommandException("E_COMPONENT_NOT_FOUND", "Component not found on target: " + request.Component, "Run tools run scene.gameobject.components with the same target/path/id to list available component names.");
54
+ if (!budget.TryConsumeReflectionCall()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
55
+ var componentType = component.GetType();
53
56
  var result = new Result
54
57
  {
55
- GameObject = new GameObjectRef { Id = gameObject.GetInstanceID(), Name = gameObject.name, Path = HierarchyPath(gameObject) },
56
- Component = new ComponentInfo { Type = component.GetType().Name, FullName = component.GetType().FullName, Enabled = ComponentEnabled(component), Properties = SceneContextComponentReadableProperties(component) }
58
+ GameObject = new GameObjectRef { Id = ConsumeSceneGetter(budget, gameObject.GetInstanceID), Name = ConsumeSceneGetter(budget, () => gameObject.name), Path = GameObjectToolSupport.HierarchyPath(gameObject, budget) },
59
+ Component = new ComponentInfo { Type = componentType.Name, FullName = componentType.FullName, Enabled = GameObjectToolSupport.ComponentEnabled(component, budget), Properties = SceneContextComponentReadableProperties(component, budget) }
57
60
  };
58
61
  return new System.Threading.Tasks.ValueTask<Result>(result);
59
62
  }
@@ -17,12 +17,13 @@ namespace UnityCli
17
17
  public int Id { get; set; }
18
18
  public string Path { get; set; }
19
19
  public bool IncludeProperties { get; set; } = true;
20
+ public UnityCliReadBudgetInput Budget { get; set; }
20
21
  }
21
22
 
22
23
  public sealed class Result
23
24
  {
24
25
  public GameObjectRef GameObject { get; set; }
25
- public List<ComponentInfo> Components { get; set; }
26
+ [UnityCliItemsRange(0, ObjectRefResolver.AbsoluteMaxBatchItems)] public List<ComponentInfo> Components { get; set; }
26
27
  public long Count { get; set; }
27
28
  }
28
29
 
@@ -46,7 +47,7 @@ namespace UnityCli
46
47
  Name = "scene.gameobject.components",
47
48
  Summary = "List components attached to one GameObject, optionally including readable property previews.",
48
49
  Description = "Lightweight list of components attached to a GameObject: type names, enabled state, and optional readable property preview. Use this before component.get/component.modify to choose component name or index. Does not return every serialized field; use component.get for deep component data.",
49
- DestructiveHint = false,
50
+ DestructiveHint = false,
50
51
  Group = "scene",
51
52
  Target = "editor",
52
53
  PlayModeSupport = "supported",
@@ -56,16 +57,18 @@ namespace UnityCli
56
57
  /// <summary>解析目标并直接构造组件列表 DTO,不经过 JSON 字符串。</summary>
57
58
  public System.Threading.Tasks.ValueTask<Result> ExecuteAsync(Request request, UnityCliProjectToolContext ctx, System.Threading.CancellationToken ct = default)
58
59
  {
60
+ request = request ?? new Request();
61
+ var budget = ctx.UseReadBudget(request.Budget);
59
62
  var id = request.Id == 0 ? (int?)null : request.Id;
60
- var gameObject = ResolveSceneContextGameObject(request.Target, id, request.Path);
61
- var components = SceneContextComponentDetails(gameObject, request.IncludeProperties);
63
+ var gameObject = ResolveSceneContextGameObject(request.Target, id, request.Path, budget);
64
+ var components = SceneContextComponentDetails(gameObject, request.IncludeProperties, budget);
62
65
  return new System.Threading.Tasks.ValueTask<Result>(new Result
63
66
  {
64
67
  GameObject = new GameObjectRef
65
68
  {
66
- Id = gameObject.GetInstanceID(),
67
- Name = gameObject.name,
68
- Path = HierarchyPath(gameObject)
69
+ Id = ConsumeSceneGetter(budget, gameObject.GetInstanceID),
70
+ Name = ConsumeSceneGetter(budget, () => gameObject.name),
71
+ Path = GameObjectToolSupport.HierarchyPath(gameObject, budget)
69
72
  },
70
73
  Components = components,
71
74
  Count = components.Count