@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,75 +1,516 @@
1
1
  #if UNITY_EDITOR
2
2
  using System;
3
- using System.CodeDom.Compiler;
3
+ using System.Collections;
4
4
  using System.Collections.Generic;
5
- using System.Globalization;
6
- using System.IO;
5
+ using System.Collections.ObjectModel;
7
6
  using System.Linq;
8
- using System.Net;
9
- using System.Reflection;
10
7
  using System.Text;
11
- using System.Security.Cryptography;
12
- using System.Text.RegularExpressions;
13
8
  using System.Threading;
14
9
  using System.Threading.Tasks;
15
- using Microsoft.CSharp;
16
- using UnityEditor;
17
- using UnityEditor.SceneManagement;
18
- using UnityEngine;
19
- using UnityEngine.Rendering;
20
- using UnityEngine.SceneManagement;
21
- using UnityEngine.UIElements;
22
- using UiButton = UnityEngine.UI.Button;
23
- using UiCanvasScaler = UnityEngine.UI.CanvasScaler;
24
- using UiGraphicRaycaster = UnityEngine.UI.GraphicRaycaster;
25
- using UiImage = UnityEngine.UI.Image;
26
- using UiText = UnityEngine.UI.Text;
27
10
 
28
11
  namespace UnityCli
29
12
  {
13
+ /// <summary>构造期冻结的执行条目;所有 descriptor 集合和 JSON 值均防御性复制。</summary>
30
14
  internal sealed class RegisteredTool
31
15
  {
32
- public ToolDescriptor Descriptor { get; set; }
33
- public string Name { get; set; }
34
- public string Summary { get; set; }
35
- public string Description { get; set; }
36
- public string Group { get; set; }
37
- public string Source { get; set; }
38
- internal string Ownership { get; set; }
39
- public string InputSchema { get; set; }
40
- public string OutputSchema { get; set; }
41
- public bool DestructiveHint { get; set; }
42
- public string[] SideEffects { get; set; }
43
- public bool SupportsDryRun { get; set; }
44
- public string[] Permissions { get; set; }
45
- public string[] RequiresPackages { get; set; }
46
- public ToolExample[] Examples { get; set; }
47
- public string Target { get; set; }
48
- public string AvailabilityScope { get; set; }
49
- public string PlayModeSupport { get; set; }
50
- public string ContractProfile { get; set; }
51
- public int DefaultTimeoutMs { get; set; }
52
- public int MaxTimeoutMs { get; set; }
53
- public string[] RequiredInput { get; set; }
54
- public string RegisteredBy { get; set; }
55
- public string DescriptorSource { get; set; }
56
- public string Assembly { get; set; }
57
- public string Method { get; set; }
58
- public string Fingerprint { get; set; }
59
- public string PinnedFingerprint { get; set; }
60
- public string FingerprintStatus { get; set; }
61
- public string ExpectedFingerprint { get; set; }
62
- public string PinnedFingerprintOwner { get; set; }
63
- public string PinnedFingerprintAlgorithm { get; set; }
64
- public string PinnedFingerprintFormat { get; set; }
65
- public string FingerprintMessage { get; set; }
66
- public string DescriptorSha256 { get; set; }
67
- public string HandlerSha256 { get; set; }
68
- public Type RequestType { get; set; }
69
- public Type ResultType { get; set; }
70
- public UnityCliToolCompletionContract CompletionContract { get; set; }
71
- internal OfficialAttributeToolBinding OfficialAttributeBinding { get; set; }
72
- public Func<object, UnityCliProjectToolContext, CancellationToken, ValueTask<object>> InvokeAsync { get; set; }
16
+ private readonly string[] sideEffects;
17
+ private readonly string[] permissions;
18
+ private readonly string[] requiresPackages;
19
+ private readonly string examplesJson;
20
+
21
+ internal RegisteredTool(
22
+ ToolDescriptor descriptor,
23
+ RegistryToolOwnership ownership,
24
+ string inputSchema,
25
+ string outputSchema,
26
+ string availabilityScope,
27
+ string contractProfile,
28
+ Type requestType,
29
+ Type resultType,
30
+ UnityCliToolCompletionContract completionContract,
31
+ OfficialAttributeToolBinding officialAttributeBinding,
32
+ Func<object, UnityCliProjectToolContext, CancellationToken, ValueTask<object>> invokeAsync)
33
+ {
34
+ if (descriptor == null) throw new ArgumentNullException("descriptor");
35
+ if (ownership == null) throw new ArgumentNullException("ownership");
36
+ Name = descriptor.Name;
37
+ Summary = descriptor.Summary;
38
+ Description = descriptor.Description;
39
+ Group = string.IsNullOrEmpty(descriptor.Group) ? DefaultGroup(descriptor.Name) : descriptor.Group;
40
+ Source = ownership.Source;
41
+ OwnerIdentity = ownership;
42
+ InputSchema = inputSchema;
43
+ OutputSchema = outputSchema;
44
+ DestructiveHint = descriptor.DestructiveHint;
45
+ sideEffects = (descriptor.SideEffects ?? Array.Empty<string>()).ToArray();
46
+ SupportsDryRun = descriptor.SupportsDryRun;
47
+ permissions = (descriptor.Permissions ?? Array.Empty<string>()).ToArray();
48
+ requiresPackages = (descriptor.RequiresPackages ?? Array.Empty<string>()).ToArray();
49
+ examplesJson = UnityCliSerializer.Serialize(
50
+ UnityCliSerializer.Parse(UnityCliSerializer.Serialize(descriptor.Examples ?? Array.Empty<ToolExample>())));
51
+ Target = string.IsNullOrEmpty(descriptor.Target) ? "editor" : descriptor.Target;
52
+ AvailabilityScope = string.IsNullOrEmpty(availabilityScope)
53
+ ? (Target == "runtime" ? "playModeSession" : "editorSession")
54
+ : availabilityScope;
55
+ PlayModeSupport = NormalizePlayModeSupport(descriptor.PlayModeSupport, Target);
56
+ ContractProfile = string.IsNullOrEmpty(contractProfile) ? "native" : contractProfile;
57
+ DefaultTimeoutMs = descriptor.DefaultTimeoutMs <= 0 ? 30000 : descriptor.DefaultTimeoutMs;
58
+ MaxTimeoutMs = descriptor.MaxTimeoutMs <= 0 ? 600000 : descriptor.MaxTimeoutMs;
59
+ RequestType = requestType;
60
+ ResultType = resultType;
61
+ CompletionContract = completionContract;
62
+ OfficialAttributeBinding = officialAttributeBinding;
63
+ InvokeAsync = invokeAsync;
64
+ }
65
+
66
+ public string Name { get; }
67
+ public string Summary { get; }
68
+ public string Description { get; }
69
+ public string Group { get; }
70
+ public string Source { get; }
71
+ public string InputSchema { get; }
72
+ public string OutputSchema { get; }
73
+ public bool DestructiveHint { get; }
74
+ public IReadOnlyList<string> SideEffects { get { return new ReadOnlyCollection<string>(sideEffects.ToArray()); } }
75
+ public bool SupportsDryRun { get; }
76
+ public IReadOnlyList<string> Permissions { get { return new ReadOnlyCollection<string>(permissions.ToArray()); } }
77
+ public IReadOnlyList<string> RequiresPackages { get { return new ReadOnlyCollection<string>(requiresPackages.ToArray()); } }
78
+ public string Target { get; }
79
+ public string AvailabilityScope { get; }
80
+ public string PlayModeSupport { get; }
81
+ public string ContractProfile { get; }
82
+ public int DefaultTimeoutMs { get; }
83
+ public int MaxTimeoutMs { get; }
84
+ public Type RequestType { get; }
85
+ public Type ResultType { get; }
86
+ public UnityCliToolCompletionContract CompletionContract { get; }
87
+ internal RegistryToolOwnership OwnerIdentity { get; }
88
+ internal OfficialAttributeToolBinding OfficialAttributeBinding { get; }
89
+ internal Func<object, UnityCliProjectToolContext, CancellationToken, ValueTask<object>> InvokeAsync { get; }
90
+ internal string ExamplesJson { get { return examplesJson; } }
91
+ internal object CloneExamples() { return UnityCliSerializer.Parse(examplesJson); }
92
+
93
+ private static string DefaultGroup(string name)
94
+ {
95
+ if (string.IsNullOrEmpty(name)) return "custom";
96
+ var dot = name.IndexOf('.');
97
+ return dot > 0 ? name.Substring(0, dot) : "custom";
98
+ }
99
+
100
+ private static string NormalizePlayModeSupport(string value, string target)
101
+ {
102
+ if (value == "supported" || value == "runtime-only" || value == "session-affecting"
103
+ || value == "editor-only" || value == "unknown") return value;
104
+ return target == "runtime" ? "runtime-only" : "editor-only";
105
+ }
106
+ }
107
+
108
+ /// <summary>snapshot reader 唯一可见的 descriptor;不含 CLR Type、binding 或 invoker。</summary>
109
+ internal sealed class RegisteredToolDescriptor
110
+ {
111
+ private readonly string[] sideEffects;
112
+ private readonly string[] permissions;
113
+ private readonly string[] requiresPackages;
114
+ private readonly string examplesJson;
115
+
116
+ internal RegisteredToolDescriptor(RegisteredTool tool)
117
+ {
118
+ Name = tool.Name;
119
+ Summary = tool.Summary;
120
+ Description = tool.Description;
121
+ Group = tool.Group;
122
+ Source = tool.Source;
123
+ InputSchema = tool.InputSchema;
124
+ OutputSchema = tool.OutputSchema;
125
+ DestructiveHint = tool.DestructiveHint;
126
+ sideEffects = tool.SideEffects.ToArray();
127
+ SupportsDryRun = tool.SupportsDryRun;
128
+ permissions = tool.Permissions.ToArray();
129
+ requiresPackages = tool.RequiresPackages.ToArray();
130
+ examplesJson = tool.ExamplesJson;
131
+ Target = tool.Target;
132
+ AvailabilityScope = tool.AvailabilityScope;
133
+ PlayModeSupport = tool.PlayModeSupport;
134
+ ContractProfile = tool.ContractProfile;
135
+ DefaultTimeoutMs = tool.DefaultTimeoutMs;
136
+ CompletionContract = new PublishedToolCompletionContract(tool.CompletionContract);
137
+ }
138
+
139
+ public string Name { get; }
140
+ public string Summary { get; }
141
+ public string Description { get; }
142
+ public string Group { get; }
143
+ public string Source { get; }
144
+ public string InputSchema { get; }
145
+ public string OutputSchema { get; }
146
+ public bool DestructiveHint { get; }
147
+ public IReadOnlyList<string> SideEffects { get { return new ReadOnlyCollection<string>(sideEffects.ToArray()); } }
148
+ public bool SupportsDryRun { get; }
149
+ public IReadOnlyList<string> Permissions { get { return new ReadOnlyCollection<string>(permissions.ToArray()); } }
150
+ public IReadOnlyList<string> RequiresPackages { get { return new ReadOnlyCollection<string>(requiresPackages.ToArray()); } }
151
+ public string Target { get; }
152
+ public string AvailabilityScope { get; }
153
+ public string PlayModeSupport { get; }
154
+ public string ContractProfile { get; }
155
+ public int DefaultTimeoutMs { get; }
156
+ public PublishedToolCompletionContract CompletionContract { get; }
157
+ internal object CloneExamples() { return UnityCliSerializer.Parse(examplesJson); }
158
+ }
159
+
160
+ /// <summary>published descriptor 使用的 completion 深拷贝。</summary>
161
+ internal sealed class PublishedToolCompletionContract
162
+ {
163
+ internal PublishedToolCompletionContract(UnityCliToolCompletionContract source)
164
+ {
165
+ if (source == null) throw new ArgumentNullException("source");
166
+ ExecutionClass = source.ExecutionClass;
167
+ CompletionPredicate = source.CompletionPredicate;
168
+ ProofSource = source.ProofSource;
169
+ ReloadPolicy = source.ReloadPolicy;
170
+ TimeoutError = source.TimeoutError;
171
+ OutcomeUnknownPolicy = source.OutcomeUnknownPolicy;
172
+ CompletionDriverId = source.CompletionDriverId;
173
+ JournalPolicy = source.JournalPolicy;
174
+ Mutation = source.Mutation;
175
+ }
176
+
177
+ public string ExecutionClass { get; }
178
+ public string CompletionPredicate { get; }
179
+ public string ProofSource { get; }
180
+ public string ReloadPolicy { get; }
181
+ public string TimeoutError { get; }
182
+ public string OutcomeUnknownPolicy { get; }
183
+ public string CompletionDriverId { get; }
184
+ public string JournalPolicy { get; }
185
+ public bool Mutation { get; }
186
+ }
187
+
188
+ internal enum UnityCliToolProviderKind
189
+ {
190
+ BuiltIn,
191
+ Extension,
192
+ ProjectInterface,
193
+ OfficialAttribute
194
+ }
195
+
196
+ /// <summary>只返回当前 domain 的 descriptor snapshot,不能取得 executable entry。</summary>
197
+ internal interface IUnityCliToolCatalogSnapshotReader
198
+ {
199
+ UnityCliToolCatalogSnapshot Read();
200
+ }
201
+
202
+ internal interface IUnityCliToolCatalogHealthSnapshotReader
203
+ {
204
+ UnityCliToolCatalogHealthSnapshot Read();
205
+ }
206
+
207
+ internal enum UnityCliToolCatalogOperationKind
208
+ {
209
+ DiscoveryPass,
210
+ ProviderMetadataRead,
211
+ AggregateSuccessLog
212
+ }
213
+
214
+ /// <summary>候选构建期唯一操作账本;所有计数只能由生产动作发生点写入。</summary>
215
+ internal sealed class UnityCliToolCatalogOperationJournal
216
+ {
217
+ private readonly Dictionary<UnityCliToolCatalogOperationKind, int> counts =
218
+ new Dictionary<UnityCliToolCatalogOperationKind, int>();
219
+
220
+ internal void Record(UnityCliToolCatalogOperationKind operation)
221
+ {
222
+ int current;
223
+ counts.TryGetValue(operation, out current);
224
+ counts[operation] = checked(current + 1);
225
+ }
226
+
227
+ internal int Count(UnityCliToolCatalogOperationKind operation)
228
+ {
229
+ int count;
230
+ return counts.TryGetValue(operation, out count) ? count : 0;
231
+ }
232
+ }
233
+
234
+ /// <summary>一次 publication 的不可变 descriptor 投影与真实 discovery 操作计数。</summary>
235
+ internal sealed class UnityCliToolCatalogSnapshot
236
+ {
237
+ internal UnityCliToolCatalogSnapshot(
238
+ IEnumerable<RegisteredToolDescriptor> descriptors,
239
+ string toolCatalogFingerprint,
240
+ int assemblyCount,
241
+ int providerAssemblyCount,
242
+ int builtInToolCount,
243
+ int extensionToolCount,
244
+ int projectInterfaceToolCount,
245
+ int officialAttributeToolCount,
246
+ long elapsedMilliseconds,
247
+ UnityCliToolCatalogOperationJournal operations)
248
+ {
249
+ Descriptors = new ReadOnlyCollection<RegisteredToolDescriptor>(
250
+ descriptors.OrderBy(item => item.Name, StringComparer.Ordinal).ToArray());
251
+ if (string.IsNullOrWhiteSpace(toolCatalogFingerprint)) throw new ArgumentException("Tool catalog fingerprint is required.", "toolCatalogFingerprint");
252
+ ToolCatalogFingerprint = toolCatalogFingerprint;
253
+ AssemblyCount = assemblyCount;
254
+ ProviderAssemblyCount = providerAssemblyCount;
255
+ BuiltInToolCount = builtInToolCount;
256
+ ExtensionToolCount = extensionToolCount;
257
+ ProjectInterfaceToolCount = projectInterfaceToolCount;
258
+ OfficialAttributeToolCount = officialAttributeToolCount;
259
+ if (operations == null) throw new ArgumentNullException("operations");
260
+ ElapsedMilliseconds = Math.Max(0, elapsedMilliseconds);
261
+ DiscoveryPassCount = operations.Count(UnityCliToolCatalogOperationKind.DiscoveryPass);
262
+ ProviderMetadataReadCount = operations.Count(UnityCliToolCatalogOperationKind.ProviderMetadataRead);
263
+ AggregateSuccessLogCount = operations.Count(UnityCliToolCatalogOperationKind.AggregateSuccessLog);
264
+ }
265
+
266
+ public IReadOnlyList<RegisteredToolDescriptor> Descriptors { get; }
267
+ public string ToolCatalogFingerprint { get; }
268
+ public int ToolCount { get { return Descriptors.Count; } }
269
+ public int AssemblyCount { get; }
270
+ public int ProviderAssemblyCount { get; }
271
+ public int BuiltInToolCount { get; }
272
+ public int ExtensionToolCount { get; }
273
+ public int ProjectInterfaceToolCount { get; }
274
+ public int OfficialAttributeToolCount { get; }
275
+ public long ElapsedMilliseconds { get; }
276
+ public int DiscoveryPassCount { get; }
277
+ public int ProviderMetadataReadCount { get; }
278
+ public int AggregateSuccessLogCount { get; }
279
+ }
280
+
281
+ /// <summary>doctor 可独立读取的 bounded health;失败时不暴露 executable table。</summary>
282
+ internal sealed class UnityCliToolCatalogHealthSnapshot
283
+ {
284
+ internal UnityCliToolCatalogHealthSnapshot(bool ready, int toolCount, string failure, string nextAction)
285
+ {
286
+ Ready = ready;
287
+ ToolCount = Math.Max(0, toolCount);
288
+ Failure = failure ?? string.Empty;
289
+ NextAction = nextAction ?? string.Empty;
290
+ }
291
+
292
+ public bool Ready { get; }
293
+ public int ToolCount { get; }
294
+ public string Failure { get; }
295
+ public string NextAction { get; }
296
+ }
297
+
298
+ /// <summary>唯一原子 publication;executable table 与其 descriptor 投影同源、同代。</summary>
299
+ internal sealed class UnityCliPublishedToolCatalog
300
+ {
301
+ internal UnityCliPublishedToolCatalog(Dictionary<string, RegisteredTool> tools, UnityCliToolCatalogSnapshot snapshot)
302
+ {
303
+ ExecutableTools = new ReadOnlyDictionary<string, RegisteredTool>(
304
+ new Dictionary<string, RegisteredTool>(tools, StringComparer.Ordinal));
305
+ Snapshot = snapshot ?? throw new ArgumentNullException("snapshot");
306
+ }
307
+
308
+ internal IReadOnlyDictionary<string, RegisteredTool> ExecutableTools { get; }
309
+ internal UnityCliToolCatalogSnapshot Snapshot { get; }
310
+ }
311
+
312
+ /// <summary>纯内存 pending registry;任一验证失败后永久 fault,失败对象不能替换 publication slot。</summary>
313
+ internal sealed class UnityCliToolCatalogBuilder
314
+ {
315
+ private readonly Dictionary<string, RegisteredTool> pending = new Dictionary<string, RegisteredTool>(StringComparer.Ordinal);
316
+ private readonly HashSet<string> providerMetadata = new HashSet<string>(StringComparer.Ordinal);
317
+ private readonly UnityCliToolCatalogOperationJournal operations = new UnityCliToolCatalogOperationJournal();
318
+ private bool discoveryStarted;
319
+ private bool faulted;
320
+ private bool published;
321
+ private int assemblyCount;
322
+ private int expectedProviderAssemblyCount;
323
+ private int builtInToolCount;
324
+ private int extensionToolCount;
325
+ private int projectInterfaceToolCount;
326
+ private int officialAttributeToolCount;
327
+
328
+ internal void BeginDiscovery(int loadedAssemblyCount, int candidateProviderAssemblyCount)
329
+ {
330
+ if (discoveryStarted || published) throw new InvalidOperationException("Tool catalog discovery can begin only once.");
331
+ if (loadedAssemblyCount < 1 || candidateProviderAssemblyCount < 1 || candidateProviderAssemblyCount > loadedAssemblyCount)
332
+ throw new ArgumentOutOfRangeException("candidateProviderAssemblyCount");
333
+ discoveryStarted = true;
334
+ operations.Record(UnityCliToolCatalogOperationKind.DiscoveryPass);
335
+ assemblyCount = loadedAssemblyCount;
336
+ expectedProviderAssemblyCount = candidateProviderAssemblyCount;
337
+ }
338
+
339
+ /// <summary>生产 discovery 与 301-provider 测试共用此 exact assembly metadata 路径。</summary>
340
+ internal void RecordProviderMetadata(string assemblyIdentity)
341
+ {
342
+ if (!discoveryStarted || published || faulted || string.IsNullOrWhiteSpace(assemblyIdentity))
343
+ throw new InvalidOperationException("Tool provider metadata is not writable.");
344
+ if (!providerMetadata.Add(assemblyIdentity)) throw new InvalidOperationException("Duplicate Tool provider assembly identity: " + assemblyIdentity + ".");
345
+ operations.Record(UnityCliToolCatalogOperationKind.ProviderMetadataRead);
346
+ }
347
+
348
+ internal void Add(RegisteredTool definition, UnityCliToolProviderKind providerKind)
349
+ {
350
+ if (!discoveryStarted || published || faulted) throw new InvalidOperationException("Tool catalog builder is not writable.");
351
+ try
352
+ {
353
+ Validate(definition, providerKind);
354
+ if (pending.ContainsKey(definition.Name)) throw new InvalidOperationException("Duplicate tool registration: " + definition.Name);
355
+ pending.Add(definition.Name, definition);
356
+ switch (providerKind)
357
+ {
358
+ case UnityCliToolProviderKind.BuiltIn: builtInToolCount++; break;
359
+ case UnityCliToolProviderKind.Extension: extensionToolCount++; break;
360
+ case UnityCliToolProviderKind.ProjectInterface: projectInterfaceToolCount++; break;
361
+ case UnityCliToolProviderKind.OfficialAttribute: officialAttributeToolCount++; break;
362
+ default: throw new ArgumentOutOfRangeException("providerKind");
363
+ }
364
+ }
365
+ catch
366
+ {
367
+ faulted = true;
368
+ throw;
369
+ }
370
+ }
371
+
372
+ internal void Abort() { faulted = true; }
373
+
374
+ internal UnityCliPublishedToolCatalog Publish(
375
+ long elapsedMilliseconds,
376
+ Action<UnityCliToolCatalogSnapshot> writeAggregateSuccessLog)
377
+ {
378
+ if (!discoveryStarted || faulted || published) throw new InvalidOperationException("Tool catalog cannot publish an incomplete or faulted table.");
379
+ if (writeAggregateSuccessLog == null) throw new ArgumentNullException("writeAggregateSuccessLog");
380
+ if (providerMetadata.Count != expectedProviderAssemblyCount)
381
+ throw new InvalidOperationException("Tool catalog provider metadata does not match the discovered provider assembly set.");
382
+ if (builtInToolCount + extensionToolCount + projectInterfaceToolCount + officialAttributeToolCount != pending.Count)
383
+ throw new InvalidOperationException("Tool catalog provider counts do not match the pending table.");
384
+
385
+ operations.Record(UnityCliToolCatalogOperationKind.AggregateSuccessLog);
386
+ var orderedTools = pending.Values.OrderBy(tool => tool.Name, StringComparer.Ordinal).ToArray();
387
+ var descriptors = orderedTools.Select(tool => new RegisteredToolDescriptor(tool)).ToArray();
388
+ // publication 时一次性绑定 descriptor 与实现程序集;registry 刷新只能读取缓存值。
389
+ var toolCatalogFingerprint = UnityCliSerializer.Sha256Canonical(new Dictionary<string, object>
390
+ {
391
+ { "descriptors", descriptors },
392
+ { "implementations", orderedTools.Select(tool => new Dictionary<string, object>
393
+ {
394
+ { "name", tool.Name },
395
+ { "assemblyIdentity", tool.OwnerIdentity.AssemblyIdentity },
396
+ { "assemblyMvid", tool.OwnerIdentity.Assembly.ManifestModule.ModuleVersionId.ToString("D") },
397
+ { "implementationType", tool.OwnerIdentity.ImplementationType.FullName }
398
+ }).Cast<object>().ToList() }
399
+ });
400
+ var snapshot = new UnityCliToolCatalogSnapshot(
401
+ descriptors,
402
+ toolCatalogFingerprint,
403
+ assemblyCount,
404
+ providerMetadata.Count,
405
+ builtInToolCount,
406
+ extensionToolCount,
407
+ projectInterfaceToolCount,
408
+ officialAttributeToolCount,
409
+ elapsedMilliseconds,
410
+ operations);
411
+ try
412
+ {
413
+ writeAggregateSuccessLog(snapshot);
414
+ }
415
+ catch
416
+ {
417
+ faulted = true;
418
+ throw;
419
+ }
420
+ published = true;
421
+ return new UnityCliPublishedToolCatalog(pending, snapshot);
422
+ }
423
+
424
+ private static void Validate(RegisteredTool definition, UnityCliToolProviderKind providerKind)
425
+ {
426
+ if (definition != null) UnityCliToolName.Validate(definition.Name, definition.ContractProfile);
427
+ if (definition == null || string.IsNullOrWhiteSpace(definition.Name) || string.IsNullOrWhiteSpace(definition.Summary)
428
+ || string.IsNullOrWhiteSpace(definition.Description) || string.IsNullOrWhiteSpace(definition.Group)
429
+ || definition.CloneExamples() == null || definition.InvokeAsync == null)
430
+ throw new ArgumentException("Tool registration requires name, summary, description, group, examples, and a typed async invoker.");
431
+ if (Utf8ByteCount(definition.Name) > 256 || Utf8ByteCount(definition.Summary) > 512
432
+ || Utf8ByteCount(definition.Group) > 256 || Utf8ByteCount(definition.Description) > 65536
433
+ || Utf8ByteCount(definition.InputSchema) > 1024 * 1024
434
+ || Utf8ByteCount(definition.OutputSchema) > 1024 * 1024
435
+ || Utf8ByteCount(definition.ExamplesJson) > 256 * 1024
436
+ || !BoundedStringList(definition.SideEffects, 128, 256)
437
+ || !BoundedStringList(definition.Permissions, 128, 256)
438
+ || !BoundedStringList(definition.RequiresPackages, 128, 256))
439
+ throw new ArgumentException("Tool descriptor exceeds a UTF-8 catalog transport bound: " + definition.Name);
440
+ if (definition.RequestType == null || definition.ResultType == null
441
+ || string.IsNullOrWhiteSpace(definition.InputSchema) || string.IsNullOrWhiteSpace(definition.OutputSchema)
442
+ || !(UnityCliSerializer.Parse(definition.InputSchema) is IDictionary<string, object>)
443
+ || !(UnityCliSerializer.Parse(definition.OutputSchema) is IDictionary<string, object>))
444
+ throw new ArgumentException("Tool registration requires request/result types and valid object schemas: " + definition.Name);
445
+ if (definition.CompletionContract == null
446
+ || !string.Equals(definition.CompletionContract.ToolName, definition.Name, StringComparison.Ordinal)
447
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.ExecutionClass)
448
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.CompletionPredicate)
449
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.ProofSource)
450
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.ReloadPolicy)
451
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.TimeoutError)
452
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.OutcomeUnknownPolicy)
453
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.CompletionDriverId)
454
+ || string.IsNullOrWhiteSpace(definition.CompletionContract.JournalPolicy))
455
+ throw new ArgumentException("Tool registration requires a complete completion contract: " + definition.Name);
456
+ if (definition.DefaultTimeoutMs <= 0 || definition.MaxTimeoutMs < definition.DefaultTimeoutMs)
457
+ throw new ArgumentException("Tool registration timeout bounds are invalid: " + definition.Name);
458
+ if (!(definition.CloneExamples() is IEnumerable)
459
+ || (definition.Target != "editor" && definition.Target != "runtime" && definition.Target != "both")
460
+ || (definition.AvailabilityScope != "always" && definition.AvailabilityScope != "projectFiles"
461
+ && definition.AvailabilityScope != "editorSession" && definition.AvailabilityScope != "playModeSession")
462
+ || (definition.PlayModeSupport != "supported" && definition.PlayModeSupport != "runtime-only"
463
+ && definition.PlayModeSupport != "session-affecting" && definition.PlayModeSupport != "editor-only"
464
+ && definition.PlayModeSupport != "unknown"))
465
+ throw new ArgumentException("Tool descriptor metadata is incomplete or invalid: " + definition.Name);
466
+
467
+ var expectedSource = providerKind == UnityCliToolProviderKind.BuiltIn ? "built-in"
468
+ : providerKind == UnityCliToolProviderKind.Extension ? "extension" : "project";
469
+ var expectedProfile = providerKind == UnityCliToolProviderKind.OfficialAttribute ? "official-attribute" : "native";
470
+ if (!string.Equals(definition.Source, expectedSource, StringComparison.Ordinal)
471
+ || !string.Equals(definition.ContractProfile, expectedProfile, StringComparison.Ordinal)
472
+ || ((providerKind == UnityCliToolProviderKind.OfficialAttribute) != (definition.OfficialAttributeBinding != null)))
473
+ throw new InvalidOperationException("Tool provider ownership does not match its descriptor: " + definition.Name);
474
+ if (definition.OwnerIdentity == null
475
+ || definition.OwnerIdentity.ImplementationType == null
476
+ || definition.OwnerIdentity.ImplementationType.Assembly != definition.OwnerIdentity.Assembly)
477
+ throw new InvalidOperationException("Tool provider has no exact compiled owner identity: " + definition.Name);
478
+ if (providerKind == UnityCliToolProviderKind.Extension && string.IsNullOrWhiteSpace(definition.OwnerIdentity.ExtensionId))
479
+ throw new InvalidOperationException("Extension Tool has no exact extension id: " + definition.Name);
480
+ if (providerKind != UnityCliToolProviderKind.Extension && !string.IsNullOrEmpty(definition.OwnerIdentity.ExtensionId))
481
+ throw new InvalidOperationException("Non-extension Tool cannot claim an extension id: " + definition.Name);
482
+ if (definition.OfficialAttributeBinding != null
483
+ && (definition.OfficialAttributeBinding.Method == null || definition.OfficialAttributeBinding.DeclaredResultType == null
484
+ || definition.OfficialAttributeBinding.Parameters == null))
485
+ throw new InvalidOperationException("Official attribute Tool binding is incomplete: " + definition.Name);
486
+ var completionOwner = definition.CompletionContract.DescriptorOwner ?? string.Empty;
487
+ if ((providerKind == UnityCliToolProviderKind.BuiltIn && completionOwner != "built-in")
488
+ || (providerKind == UnityCliToolProviderKind.Extension
489
+ && completionOwner != "extension:" + definition.OwnerIdentity.ExtensionId)
490
+ || ((providerKind == UnityCliToolProviderKind.ProjectInterface || providerKind == UnityCliToolProviderKind.OfficialAttribute)
491
+ && completionOwner != "project"))
492
+ throw new InvalidOperationException("Tool completion owner does not match its provider: " + definition.Name);
493
+ var usesOfficialName = definition.Name.StartsWith("UnityPipeline_", StringComparison.Ordinal);
494
+ var usesOfficialGroup = string.Equals(definition.Group, "UnityPipeline", StringComparison.Ordinal);
495
+ if ((providerKind == UnityCliToolProviderKind.OfficialAttribute && (!usesOfficialName || !usesOfficialGroup))
496
+ || (providerKind != UnityCliToolProviderKind.OfficialAttribute && (usesOfficialName || usesOfficialGroup)))
497
+ throw new InvalidOperationException("Tool provider kind does not match the reserved official attribute namespace: " + definition.Name);
498
+ }
499
+
500
+ /// <summary>descriptor field bound统一按wire UTF-8字节计算。</summary>
501
+ private static int Utf8ByteCount(string value)
502
+ {
503
+ return Encoding.UTF8.GetByteCount(value ?? string.Empty);
504
+ }
505
+
506
+ /// <summary>限制公开字符串数组的条目数与单项UTF-8大小。</summary>
507
+ private static bool BoundedStringList(IEnumerable<string> values, int maximumCount, int maximumItemBytes)
508
+ {
509
+ if (values == null) return true;
510
+ var items = values.ToArray();
511
+ return items.Length <= maximumCount
512
+ && items.All(value => !string.IsNullOrWhiteSpace(value) && Utf8ByteCount(value) <= maximumItemBytes);
513
+ }
73
514
  }
74
515
  }
75
516
  #endif
@@ -63,6 +63,27 @@ namespace UnityCli
63
63
  /// <summary>当前请求的取消令牌。异步工具应把它继续传给 ctx.Wait.*。</summary>
64
64
  public CancellationToken CancellationToken { get; set; }
65
65
 
66
+ /// <summary>受影响读取能力共享的单一请求预算;递归、分页与多路径读取不得自行重置。</summary>
67
+ internal UnityCliRequestBudget ReadBudget { get; private set; }
68
+
69
+ /// <summary>在第一次 Unity 主线程读取前创建预算;后续调用始终复用同一账本。</summary>
70
+ public UnityCliRequestBudget UseReadBudget(UnityCliReadBudgetInput input = null)
71
+ {
72
+ if (ReadBudget != null) return ReadBudget;
73
+ try
74
+ {
75
+ ReadBudget = new UnityCliRequestBudget(input, TimeoutMs, CancellationToken);
76
+ return ReadBudget;
77
+ }
78
+ catch (ArgumentOutOfRangeException exception)
79
+ {
80
+ throw new UnityCliBridge.BridgeCommandException(
81
+ "E_REQUEST_BUDGET_INVALID",
82
+ exception.ParamName + " is outside the documented request-wide budget range.",
83
+ "Pass a positive budget value no greater than the maximum shown by tools describe.");
84
+ }
85
+ }
86
+
66
87
  }
67
88
  }
68
89
  #endif