@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
@@ -0,0 +1,412 @@
1
+ using System;
2
+ using System.Collections.Generic;
3
+ using System.Linq;
4
+ using NUnit.Framework;
5
+
6
+ namespace UnityCli.Tests
7
+ {
8
+ /// <summary>验证BridgeWorkQueue复用的纯分类、容量与启动选择策略。</summary>
9
+ public sealed class UnityCliBridgeQueuePolicyTests
10
+ {
11
+ private const string SafeStatusCommand = "internal.editor.compile.status";
12
+
13
+ [Test]
14
+ public void RunningMutationBlocksPendingMutationAndLaterReadsButSafeStatusPassesWithinBounds()
15
+ {
16
+ var queued = new[]
17
+ {
18
+ Node("mutation-b", UnityCliBridgeQueuePolicy.WorkClass.Mutation),
19
+ Node("later-read", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
20
+ Safe("status-0"), Safe("status-1"), Safe("status-2"),
21
+ Safe("status-3"), Safe("status-4"), Safe("status-5")
22
+ };
23
+
24
+ var result = UnityCliBridgeQueuePolicy.SelectStarts(
25
+ queued, 0, true, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
26
+
27
+ Assert.That(Ids(result), Is.EqualTo(new[] { "status-0", "status-1", "status-2", "status-3" }));
28
+ Assert.That(result.Starts.Select(item => item.QueueIndex), Is.EqualTo(new[] { 2, 3, 4, 5 }));
29
+ Assert.That(result.Starts.Count, Is.LessThanOrEqualTo(UnityCliBridgeQueuePolicy.MaxStartsPerTick));
30
+ Assert.That(result.Starts.Count(item => item.Class == UnityCliBridgeQueuePolicy.WorkClass.SafeStatus),
31
+ Is.EqualTo(UnityCliBridgeQueuePolicy.MaxSafeStatusStartsPerTick));
32
+ Assert.That(queued.Select(node => node.NodeId), Is.EqualTo(new[]
33
+ {
34
+ "mutation-b", "later-read", "status-0", "status-1", "status-2", "status-3", "status-4", "status-5"
35
+ }));
36
+ }
37
+
38
+ [Test]
39
+ public void ReadsBeforeMutationDrainBeforeItStartsAndLaterReadsStayBehind()
40
+ {
41
+ var readA = Node("read-a", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead);
42
+ var readB = Node("read-b", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead);
43
+ var mutation = Node("mutation-b", UnityCliBridgeQueuePolicy.WorkClass.Mutation);
44
+ var laterRead = Node("later-read", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead);
45
+
46
+ var drain = UnityCliBridgeQueuePolicy.SelectStarts(
47
+ new[] { readA, readB, mutation, laterRead }, 0, false,
48
+ UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
49
+ Assert.That(Ids(drain), Is.EqualTo(new[] { "read-a", "read-b" }));
50
+
51
+ var whileReadsRun = UnityCliBridgeQueuePolicy.SelectStarts(
52
+ new[] { mutation, laterRead }, 2, false,
53
+ UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
54
+ Assert.That(whileReadsRun.Starts, Is.Empty);
55
+
56
+ var mutationStarts = UnityCliBridgeQueuePolicy.SelectStarts(
57
+ new[] { mutation, laterRead }, 0, false,
58
+ UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
59
+ Assert.That(Ids(mutationStarts), Is.EqualTo(new[] { "mutation-b" }));
60
+ Assert.That(mutationStarts.Starts.Single().QueueIndex, Is.EqualTo(0));
61
+ }
62
+
63
+ [Test]
64
+ public void ContinuousSafeStatusCannotStarveEligibleMutationAndAllTickBoundsHold()
65
+ {
66
+ var queued = Enumerable.Range(0, 20)
67
+ .Select(index => Safe("status-" + index.ToString()))
68
+ .Concat(new[] { Node("mutation-b", UnityCliBridgeQueuePolicy.WorkClass.Mutation) })
69
+ .ToArray();
70
+
71
+ var result = UnityCliBridgeQueuePolicy.SelectStarts(
72
+ queued, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
73
+
74
+ Assert.That(Ids(result), Is.EqualTo(new[] { "status-0", "status-1", "status-2", "status-3", "mutation-b" }));
75
+ Assert.That(result.Starts.Count, Is.LessThanOrEqualTo(UnityCliBridgeQueuePolicy.MaxStartsPerTick));
76
+ Assert.That(result.Starts.Count(item => item.Class == UnityCliBridgeQueuePolicy.WorkClass.SafeStatus),
77
+ Is.EqualTo(UnityCliBridgeQueuePolicy.MaxSafeStatusStartsPerTick));
78
+ Assert.That(result.NodesExamined, Is.EqualTo(queued.Length));
79
+
80
+ var nextTick = UnityCliBridgeQueuePolicy.SelectStarts(
81
+ Enumerable.Range(20, 20).Select(index => Safe("status-" + index.ToString())).ToArray(),
82
+ 0, true, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
83
+ Assert.That(nextTick.Starts.Count, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxSafeStatusStartsPerTick));
84
+ Assert.That(nextTick.Starts.All(item => item.Class == UnityCliBridgeQueuePolicy.WorkClass.SafeStatus), Is.True);
85
+
86
+ var saturated = UnityCliBridgeQueuePolicy.SelectStarts(
87
+ Enumerable.Range(40, 20).Select(index => Safe("status-" + index.ToString()))
88
+ .Concat(Enumerable.Range(0, 20).Select(index => Node("read-" + index.ToString(), UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead)))
89
+ .ToArray(),
90
+ 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
91
+ Assert.That(saturated.Starts.Count, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxStartsPerTick));
92
+ Assert.That(saturated.Starts.Count(item => item.Class == UnityCliBridgeQueuePolicy.WorkClass.SafeStatus),
93
+ Is.EqualTo(UnityCliBridgeQueuePolicy.MaxSafeStatusStartsPerTick));
94
+ }
95
+
96
+ [Test]
97
+ public void New129thBypassIdentityIsRejectedWhileExactAttachRemainsAllowed()
98
+ {
99
+ var identities = Enumerable.Range(0, UnityCliBridgeQueuePolicy.MaxBypassIdentities)
100
+ .Select(index => Identity(index, index))
101
+ .ToArray();
102
+ var originalOrder = identities.Select(identity => identity.RequestId).ToArray();
103
+
104
+ var rejected = UnityCliBridgeQueuePolicy.DecideBypassAdmission(
105
+ identities, Identity(UnityCliBridgeQueuePolicy.MaxBypassIdentities, UnityCliBridgeQueuePolicy.MaxBypassIdentities));
106
+ Assert.That(rejected.Outcome, Is.EqualTo(UnityCliBridgeQueuePolicy.BypassAdmissionOutcome.RejectCapacity));
107
+ Assert.That(rejected.ExistingIndex, Is.EqualTo(-1));
108
+
109
+ var attached = UnityCliBridgeQueuePolicy.DecideBypassAdmission(
110
+ identities, Identity(UnityCliBridgeQueuePolicy.MaxBypassIdentities - 1, UnityCliBridgeQueuePolicy.MaxBypassIdentities - 1));
111
+ Assert.That(attached.Outcome, Is.EqualTo(UnityCliBridgeQueuePolicy.BypassAdmissionOutcome.Attach));
112
+ Assert.That(attached.ExistingIndex, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxBypassIdentities - 1));
113
+
114
+ var mismatch = UnityCliBridgeQueuePolicy.DecideBypassAdmission(
115
+ identities, Identity(UnityCliBridgeQueuePolicy.MaxBypassIdentities - 1, 999));
116
+ Assert.That(mismatch.Outcome, Is.EqualTo(UnityCliBridgeQueuePolicy.BypassAdmissionOutcome.RejectIdentityMismatch));
117
+ Assert.That(mismatch.ExistingIndex, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxBypassIdentities - 1));
118
+ Assert.That(identities.Select(identity => identity.RequestId), Is.EqualTo(originalOrder));
119
+ }
120
+
121
+ [Test]
122
+ public void TotalNodeVisitBoundIsTheExactSumOfIndependentLaneBudgets()
123
+ {
124
+ Assert.That(UnityCliBridgeQueuePolicy.MaxNodesExaminedPerTick, Is.EqualTo(
125
+ UnityCliBridgeQueuePolicy.MaxSafeStatusNodesExaminedPerTick
126
+ + UnityCliBridgeQueuePolicy.MaxControlNodesExaminedPerTick
127
+ + UnityCliBridgeQueuePolicy.MaxFifoNodesExaminedPerTick));
128
+ Assert.That(UnityCliBridgeQueuePolicy.MaxSafeStatusNodesExaminedPerTick,
129
+ Is.EqualTo(UnityCliBridgeQueuePolicy.MaxSafeStatusStartsPerTick));
130
+ }
131
+
132
+ [Test]
133
+ public void NodeScanBoundCountsActualIndexerVisits()
134
+ {
135
+ var queued = new CountingQueue(Enumerable.Range(0, UnityCliBridgeQueuePolicy.MaxNodesExaminedPerTick - 1)
136
+ .Select(index => Node("read-" + index.ToString(), UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead))
137
+ .Concat(new[] { Node("mutation-last", UnityCliBridgeQueuePolicy.WorkClass.Mutation) })
138
+ .ToArray());
139
+
140
+ var result = UnityCliBridgeQueuePolicy.SelectStarts(
141
+ queued, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
142
+
143
+ Assert.That(queued.IndexerVisits, Is.LessThanOrEqualTo(UnityCliBridgeQueuePolicy.MaxNodesExaminedPerTick));
144
+ Assert.That(queued.IndexerVisits, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxNodesExaminedPerTick));
145
+ Assert.That(result.NodesExamined, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxNodesExaminedPerTick));
146
+ Assert.That(result.Starts.Count, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxStartsPerTick));
147
+ }
148
+
149
+ [Test]
150
+ public void EligibleNodeBeyondScanBoundDoesNotStart()
151
+ {
152
+ var queued = Enumerable.Range(0, UnityCliBridgeQueuePolicy.MaxNodesExaminedPerTick)
153
+ .Select(index => Node("read-" + index.ToString(), UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead))
154
+ .Concat(new[] { Safe("eligible-beyond-bound") })
155
+ .ToArray();
156
+
157
+ var result = UnityCliBridgeQueuePolicy.SelectStarts(
158
+ queued, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Held);
159
+
160
+ Assert.That(result.NodesExamined, Is.EqualTo(UnityCliBridgeQueuePolicy.MaxNodesExaminedPerTick));
161
+ Assert.That(result.Starts, Is.Empty);
162
+ }
163
+
164
+ [Test]
165
+ public void UnreadableDurableBarrierBlocksMutationAndOrdinaryReadsButOnlyExactSafeStatusPasses()
166
+ {
167
+ var queued = new[]
168
+ {
169
+ Node("mutation", UnityCliBridgeQueuePolicy.WorkClass.Mutation),
170
+ Node("ordinary", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
171
+ Safe("exact-status"),
172
+ Classified("generic-status", "internal.unknown.status", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
173
+ Classified("snapshot", "internal.navmesh.bake.snapshot", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
174
+ Classified("plan", "internal.navmesh.bake.plan", UnityCliBridgeQueuePolicy.WorkClass.Mutation),
175
+ Classified("cancel", "internal.navmesh.bake.cancel", UnityCliBridgeQueuePolicy.WorkClass.Control)
176
+ };
177
+
178
+ var result = UnityCliBridgeQueuePolicy.SelectStarts(
179
+ queued, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Unreadable);
180
+
181
+ Assert.That(Ids(result), Is.EqualTo(new[] { "exact-status" }));
182
+ Assert.That(result.Starts.All(item => item.Class == UnityCliBridgeQueuePolicy.WorkClass.SafeStatus), Is.True);
183
+ }
184
+
185
+ [Test]
186
+ public void MutationFifoIsPreservedAcrossReadPhases()
187
+ {
188
+ var beforeA = Node("read-before-a", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead);
189
+ var mutationA = Node("mutation-a", UnityCliBridgeQueuePolicy.WorkClass.Mutation);
190
+ var between = Node("read-between", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead);
191
+ var mutationB = Node("mutation-b", UnityCliBridgeQueuePolicy.WorkClass.Mutation);
192
+ var afterB = Node("read-after-b", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead);
193
+
194
+ Assert.That(Ids(Select(new[] { beforeA, mutationA, between, mutationB, afterB })),
195
+ Is.EqualTo(new[] { "read-before-a" }));
196
+ Assert.That(Ids(Select(new[] { mutationA, between, mutationB, afterB })),
197
+ Is.EqualTo(new[] { "mutation-a" }));
198
+
199
+ var whileARuns = UnityCliBridgeQueuePolicy.SelectStarts(
200
+ new[] { between, mutationB, afterB }, 0, true,
201
+ UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
202
+ Assert.That(whileARuns.Starts, Is.Empty);
203
+
204
+ Assert.That(Ids(Select(new[] { between, mutationB, afterB })),
205
+ Is.EqualTo(new[] { "read-between" }));
206
+ Assert.That(Ids(Select(new[] { mutationB, afterB })),
207
+ Is.EqualTo(new[] { "mutation-b" }));
208
+ Assert.That(Ids(Select(new[] { afterB })),
209
+ Is.EqualTo(new[] { "read-after-b" }));
210
+ }
211
+
212
+ [Test]
213
+ public void SafeStatusClassificationUsesOnlyTheClosedExactAllowlist()
214
+ {
215
+ var allowed = new[]
216
+ {
217
+ "internal.editor.compile.status",
218
+ "internal.editor.refresh.status",
219
+ "internal.editor.state.snapshot",
220
+ "internal.asset.refresh.status",
221
+ "internal.package.embed.status",
222
+ "internal.package.resolve.status",
223
+ "internal.test.run.status",
224
+ "internal.test.run.cancel.status",
225
+ "internal.navmesh.bake.status",
226
+ "internal.occlusion.bake.status"
227
+ };
228
+ foreach (var command in allowed)
229
+ Assert.That(UnityCliBridgeQueuePolicy.Classify(command, UnityCliBridgeQueuePolicy.WorkClass.SafeStatus),
230
+ Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.SafeStatus), command);
231
+
232
+ var excluded = new[]
233
+ {
234
+ "internal.editor.compile.Status",
235
+ "internal.editor.state.snapshot.extra",
236
+ "internal.unknown.status",
237
+ "project-tool.run",
238
+ "profiler.status",
239
+ "extension.status"
240
+ };
241
+ foreach (var command in excluded)
242
+ {
243
+ Assert.That(UnityCliBridgeQueuePolicy.IsSafeStatusCommand(command), Is.False, command);
244
+ Assert.That(UnityCliBridgeQueuePolicy.Classify(command, UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
245
+ Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead), command);
246
+ }
247
+
248
+ Assert.That(UnityCliBridgeQueuePolicy.Classify("internal.navmesh.bake.plan", UnityCliBridgeQueuePolicy.WorkClass.Mutation),
249
+ Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.Mutation));
250
+ foreach (var command in new[] { "internal.navmesh.bake.cancel", "internal.test.run.cancel", "internal.package.files.claim" })
251
+ {
252
+ Assert.That(UnityCliBridgeQueuePolicy.IsDurableControlCommand(command), Is.True, command);
253
+ Assert.That(UnityCliBridgeQueuePolicy.Classify(command, UnityCliBridgeQueuePolicy.WorkClass.Control),
254
+ Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.Control), command);
255
+ }
256
+ Assert.That(UnityCliBridgeQueuePolicy.Classify("internal.navmesh.bake.snapshot", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
257
+ Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead));
258
+ Assert.That(UnityCliBridgeQueuePolicy.IsOrdinaryReadInternalCommand("internal.navmesh.bake.snapshot"), Is.True);
259
+ Assert.That(UnityCliBridgeQueuePolicy.IsOrdinaryReadInternalCommand("internal.occlusion.bake.snapshot"), Is.True);
260
+ Assert.That(UnityCliBridgeQueuePolicy.IsOrdinaryReadInternalCommand("internal.navmesh.bake.plan"), Is.False);
261
+ Assert.That(UnityCliBridgeQueuePolicy.Classify("project-tool.run", UnityCliBridgeQueuePolicy.WorkClass.Mutation),
262
+ Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.Mutation));
263
+ Assert.Throws<ArgumentException>(() => UnityCliBridgeQueuePolicy.Classify(SafeStatusCommand, UnityCliBridgeQueuePolicy.WorkClass.Mutation));
264
+ }
265
+
266
+ [Test]
267
+ public void HeldBarrierStartsOnlyOneExplicitlyAuthorizedControl()
268
+ {
269
+ var rejected = Classified("control-rejected", "internal.package.files.claim", UnityCliBridgeQueuePolicy.WorkClass.Control);
270
+ var exact = Classified("control-exact", "internal.navmesh.bake.cancel", UnityCliBridgeQueuePolicy.WorkClass.Control)
271
+ .WithControlAuthorization(true);
272
+ var later = Classified("control-later", "internal.occlusion.bake.cancel", UnityCliBridgeQueuePolicy.WorkClass.Control)
273
+ .WithControlAuthorization(true);
274
+
275
+ var held = UnityCliBridgeQueuePolicy.SelectStarts(
276
+ new[] { rejected, exact, later }, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Held);
277
+ var unreadable = UnityCliBridgeQueuePolicy.SelectStarts(
278
+ new[] { exact }, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Unreadable);
279
+ var clear = UnityCliBridgeQueuePolicy.SelectStarts(
280
+ new[] { exact }, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
281
+
282
+ Assert.That(Ids(held), Is.EqualTo(new[] { "control-exact" }));
283
+ Assert.That(held.Starts.Single().Class, Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.Control));
284
+ Assert.That(unreadable.Starts, Is.Empty);
285
+ Assert.That(clear.Starts, Is.Empty);
286
+ }
287
+
288
+ [Test]
289
+ public void TerminalControlDecisionsShareTheBoundedScanAndDoNotBlockLaterWork()
290
+ {
291
+ var missing = Classified("missing-parent", "internal.package.files.claim", UnityCliBridgeQueuePolicy.WorkClass.Control)
292
+ .WithControlDisposition(UnityCliBridgeQueuePolicy.ControlDisposition.RejectParentUnavailable);
293
+ var mismatch = Classified("mismatched-parent", "internal.navmesh.bake.cancel", UnityCliBridgeQueuePolicy.WorkClass.Control)
294
+ .WithControlDisposition(UnityCliBridgeQueuePolicy.ControlDisposition.RejectIdentityMismatch);
295
+ var expired = Classified("expired-control", "internal.occlusion.bake.cancel", UnityCliBridgeQueuePolicy.WorkClass.Control)
296
+ .WithControlDisposition(UnityCliBridgeQueuePolicy.ControlDisposition.ExpireDeadline);
297
+ var mutation = Node("next-mutation", UnityCliBridgeQueuePolicy.WorkClass.Mutation);
298
+
299
+ var clear = UnityCliBridgeQueuePolicy.SelectStarts(new[] { missing, mismatch, expired, mutation }, 0, false,
300
+ UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
301
+ var unreadable = UnityCliBridgeQueuePolicy.SelectStarts(new[] { expired, mutation }, 0, false,
302
+ UnityCliBridgeQueuePolicy.DurableMutationBarrier.Unreadable);
303
+
304
+ Assert.That(clear.Rejects.Select(value => value.NodeId), Is.EqualTo(new[] { "missing-parent", "mismatched-parent", "expired-control" }));
305
+ Assert.That(Ids(clear), Is.EqualTo(new[] { "next-mutation" }));
306
+ Assert.That(clear.NodesExamined, Is.EqualTo(4));
307
+ Assert.That(unreadable.Rejects.Single().NodeId, Is.EqualTo("expired-control"));
308
+ Assert.That(unreadable.Starts, Is.Empty);
309
+ }
310
+
311
+ [Test]
312
+ public void EditorStateSnapshotProgressesWhenMutationOrDurableBarrierBlocksRegularWork()
313
+ {
314
+ var queued = new[]
315
+ {
316
+ Node("mutation", UnityCliBridgeQueuePolicy.WorkClass.Mutation),
317
+ Node("ordinary", UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
318
+ Safe("snapshot")
319
+ };
320
+
321
+ var mutationRunning = UnityCliBridgeQueuePolicy.SelectStarts(
322
+ queued, 0, true, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
323
+ Assert.That(Ids(mutationRunning), Is.EqualTo(new[] { "snapshot" }));
324
+
325
+ var held = UnityCliBridgeQueuePolicy.SelectStarts(
326
+ queued, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Held);
327
+ Assert.That(Ids(held), Is.EqualTo(new[] { "snapshot" }));
328
+
329
+ var unreadable = UnityCliBridgeQueuePolicy.SelectStarts(
330
+ queued, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Unreadable);
331
+ Assert.That(Ids(unreadable), Is.EqualTo(new[] { "snapshot" }));
332
+ }
333
+
334
+ [Test]
335
+ public void CommandLengthMatchesCanonicalAdmissionBoundary()
336
+ {
337
+ Assert.That(UnityCliBridgeQueuePolicy.Classify(new string('c', 256), UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead),
338
+ Is.EqualTo(UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead));
339
+ Assert.Throws<ArgumentException>(() => UnityCliBridgeQueuePolicy.Classify(new string('c', 257), UnityCliBridgeQueuePolicy.WorkClass.OrdinaryRead));
340
+ }
341
+
342
+ private static UnityCliBridgeQueuePolicy.TickSelection Select(IReadOnlyList<UnityCliBridgeQueuePolicy.QueueNode> queued)
343
+ {
344
+ return UnityCliBridgeQueuePolicy.SelectStarts(
345
+ queued, 0, false, UnityCliBridgeQueuePolicy.DurableMutationBarrier.Clear);
346
+ }
347
+
348
+ private static UnityCliBridgeQueuePolicy.QueueNode Node(string id, UnityCliBridgeQueuePolicy.WorkClass workClass)
349
+ {
350
+ if (workClass == UnityCliBridgeQueuePolicy.WorkClass.SafeStatus)
351
+ throw new ArgumentException("Tests must create SafeStatus through its exact command.", "workClass");
352
+ return new UnityCliBridgeQueuePolicy.QueueNode(id, "project-tool.run", workClass);
353
+ }
354
+
355
+ private static UnityCliBridgeQueuePolicy.QueueNode Safe(string id)
356
+ {
357
+ return new UnityCliBridgeQueuePolicy.QueueNode(id, SafeStatusCommand, UnityCliBridgeQueuePolicy.WorkClass.SafeStatus);
358
+ }
359
+
360
+ private static UnityCliBridgeQueuePolicy.QueueNode Classified(string id, string command, UnityCliBridgeQueuePolicy.WorkClass workClass)
361
+ {
362
+ return new UnityCliBridgeQueuePolicy.QueueNode(id, command, workClass);
363
+ }
364
+
365
+ private static UnityCliBridgeQueuePolicy.BypassIdentity Identity(int requestIndex, int digestIndex)
366
+ {
367
+ return new UnityCliBridgeQueuePolicy.BypassIdentity(
368
+ "request-" + requestIndex.ToString(), digestIndex.ToString("x64"));
369
+ }
370
+
371
+ private static string[] Ids(UnityCliBridgeQueuePolicy.TickSelection selection)
372
+ {
373
+ return selection.Starts.Select(item => item.NodeId).ToArray();
374
+ }
375
+
376
+ private sealed class CountingQueue : IReadOnlyList<UnityCliBridgeQueuePolicy.QueueNode>
377
+ {
378
+ private readonly UnityCliBridgeQueuePolicy.QueueNode[] _nodes;
379
+
380
+ public CountingQueue(UnityCliBridgeQueuePolicy.QueueNode[] nodes)
381
+ {
382
+ _nodes = nodes;
383
+ }
384
+
385
+ public int IndexerVisits { get; private set; }
386
+
387
+ public int Count
388
+ {
389
+ get { return _nodes.Length; }
390
+ }
391
+
392
+ public UnityCliBridgeQueuePolicy.QueueNode this[int index]
393
+ {
394
+ get
395
+ {
396
+ IndexerVisits += 1;
397
+ return _nodes[index];
398
+ }
399
+ }
400
+
401
+ public IEnumerator<UnityCliBridgeQueuePolicy.QueueNode> GetEnumerator()
402
+ {
403
+ return ((IEnumerable<UnityCliBridgeQueuePolicy.QueueNode>)_nodes).GetEnumerator();
404
+ }
405
+
406
+ System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
407
+ {
408
+ return GetEnumerator();
409
+ }
410
+ }
411
+ }
412
+ }