@alpsckr/unitycli 0.4.2 → 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 +35 -42
  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
@@ -7,6 +7,7 @@ using System.Linq;
7
7
  using System.Reflection;
8
8
  using System.Security.Cryptography;
9
9
  using System.Text;
10
+ using System.Threading;
10
11
 
11
12
  namespace UnityCli
12
13
  {
@@ -33,6 +34,25 @@ namespace UnityCli
33
34
  return builder.ToString();
34
35
  }
35
36
 
37
+ /// <summary>在请求的取消、主线程与实际 UTF-8 ceiling 内增量构造最终 JSON。</summary>
38
+ public static string Serialize(object value, UnityCliRequestBudget budget, CancellationToken cancellationToken)
39
+ {
40
+ long ignored;
41
+ return Serialize(value, budget, cancellationToken, out ignored);
42
+ }
43
+
44
+ /// <summary>返回序列化结果及同一次增量写入得到的精确 UTF-8 字节数。</summary>
45
+ internal static string Serialize(object value, UnityCliRequestBudget budget, CancellationToken cancellationToken, out long utf8Bytes)
46
+ {
47
+ if (budget == null) throw new ArgumentNullException("budget");
48
+ budget.CheckpointOrThrow();
49
+ var writer = new BudgetedJsonWriter(budget, cancellationToken);
50
+ WriteBudgetedValue(writer, value, budget, cancellationToken);
51
+ budget.CheckpointOrThrow();
52
+ utf8Bytes = writer.Utf8Bytes;
53
+ return writer.ToString();
54
+ }
55
+
36
56
  private static void WriteValue(StringBuilder builder, object value)
37
57
  {
38
58
  if (value == null)
@@ -104,6 +124,206 @@ namespace UnityCli
104
124
  builder.Append('}');
105
125
  }
106
126
 
127
+ private const int MaximumProtocolMembers = 256;
128
+ private const int MaximumDictionaryEntries = 4096;
129
+ private const int MaximumMemberMetadataUtf8Bytes = 64 * 1024;
130
+ private const int MaximumCachedProtocolTypes = 128;
131
+ private static readonly object BudgetedMemberCacheLock = new object();
132
+ private static readonly Dictionary<Type, MemberInfo[]> BudgetedMemberCache = new Dictionary<Type, MemberInfo[]>();
133
+
134
+ /// <summary>请求态序列化逐项处理集合和成员,任何候选都先计入同一预算。</summary>
135
+ private static void WriteBudgetedValue(BudgetedJsonWriter writer, object value, UnityCliRequestBudget budget, CancellationToken cancellationToken)
136
+ {
137
+ cancellationToken.ThrowIfCancellationRequested();
138
+ budget.CheckpointOrThrow();
139
+ if (value == null) { writer.Append("null"); return; }
140
+
141
+ var type = value.GetType();
142
+ if (type == typeof(string) || type == typeof(char)) { WriteBudgetedString(writer, Convert.ToString(value, CultureInfo.InvariantCulture)); return; }
143
+ if (type == typeof(bool)) { writer.Append((bool)value ? "true" : "false"); return; }
144
+ if (type.IsEnum) { WriteBudgetedString(writer, Enum.GetName(type, value)); return; }
145
+ if (UnityCliSchemaDeriver.IsInteger(type)) { writer.Append(Convert.ToString(value, CultureInfo.InvariantCulture)); return; }
146
+ if (type == typeof(decimal)) { writer.Append(((decimal)value).ToString(CultureInfo.InvariantCulture)); return; }
147
+ if (type == typeof(double) || type == typeof(float))
148
+ {
149
+ var number = Convert.ToDouble(value, CultureInfo.InvariantCulture);
150
+ if (double.IsNaN(number) || double.IsInfinity(number)) throw new FormatException("JSON does not support non-finite numbers.");
151
+ writer.Append(number.ToString("R", CultureInfo.InvariantCulture));
152
+ return;
153
+ }
154
+
155
+ var dictionary = value as IDictionary;
156
+ if (dictionary != null)
157
+ {
158
+ var entries = new List<DictionaryEntry>();
159
+ foreach (DictionaryEntry entry in dictionary)
160
+ {
161
+ if (!budget.TryConsumeScannedRecord() || entries.Count >= MaximumDictionaryEntries)
162
+ throw new UnityCliRequestBudgetExceededException(entries.Count >= MaximumDictionaryEntries ? "dictionaryEntries" : budget.ExhaustedDimension);
163
+ entries.Add(entry);
164
+ }
165
+ entries.Sort((left, right) => string.CompareOrdinal(Convert.ToString(left.Key, CultureInfo.InvariantCulture), Convert.ToString(right.Key, CultureInfo.InvariantCulture)));
166
+ writer.Append("{");
167
+ for (var index = 0; index < entries.Count; index++)
168
+ {
169
+ if (index > 0) writer.Append(",");
170
+ WriteBudgetedString(writer, Convert.ToString(entries[index].Key, CultureInfo.InvariantCulture));
171
+ writer.Append(":");
172
+ WriteBudgetedValue(writer, entries[index].Value, budget, cancellationToken);
173
+ }
174
+ writer.Append("}");
175
+ return;
176
+ }
177
+
178
+ var enumerable = value as IEnumerable;
179
+ if (enumerable != null)
180
+ {
181
+ writer.Append("[");
182
+ var first = true;
183
+ foreach (var item in enumerable)
184
+ {
185
+ if (!budget.TryConsumeScannedRecord()) throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
186
+ if (!first) writer.Append(",");
187
+ first = false;
188
+ WriteBudgetedValue(writer, item, budget, cancellationToken);
189
+ }
190
+ writer.Append("]");
191
+ return;
192
+ }
193
+
194
+ writer.Append("{");
195
+ var firstMember = true;
196
+ foreach (var member in BudgetedSerializableMembers(type, budget))
197
+ {
198
+ if (!budget.TryConsumeScannedRecord() || !budget.TryConsumeReflectionCall() || !budget.TryConsumeGetter())
199
+ throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
200
+ var memberValue = UnityCliSchemaDeriver.GetMemberValue(member, value);
201
+ if (memberValue == null) continue;
202
+ if (!firstMember) writer.Append(",");
203
+ firstMember = false;
204
+ WriteBudgetedString(writer, ToCamelCase(member.Name));
205
+ writer.Append(":");
206
+ WriteBudgetedValue(writer, memberValue, budget, cancellationToken);
207
+ }
208
+ writer.Append("}");
209
+ }
210
+
211
+ /// <summary>缓存只活在当前 domain generation,且类型数、成员数与 metadata 字节均有硬上限。</summary>
212
+ private static IReadOnlyList<MemberInfo> BudgetedSerializableMembers(Type type, UnityCliRequestBudget budget)
213
+ {
214
+ lock (BudgetedMemberCacheLock)
215
+ {
216
+ MemberInfo[] cached;
217
+ if (BudgetedMemberCache.TryGetValue(type, out cached)) return cached;
218
+ }
219
+
220
+ var members = new Dictionary<string, MemberInfo>(StringComparer.Ordinal);
221
+ var metadataBytes = 0;
222
+ var depth = 0;
223
+ for (var current = type; current != null && current != typeof(object); current = current.BaseType)
224
+ {
225
+ if (++depth > 32) throw new UnityCliRequestBudgetExceededException("nodes");
226
+ foreach (var property in UnityCliReflectionSnapshot.DeclaredProperties(current, budget, MaximumProtocolMembers))
227
+ {
228
+ if (!budget.TryConsumeReflectionCall() || !budget.TryConsumeScannedRecord())
229
+ throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
230
+ CountMemberMetadata(property, ref metadataBytes);
231
+ if (property.GetMethod == null || !property.GetMethod.IsPublic || property.GetIndexParameters().Length != 0) continue;
232
+ AddBudgetedMember(members, property);
233
+ }
234
+ foreach (var field in UnityCliReflectionSnapshot.DeclaredFields(current, budget, MaximumProtocolMembers))
235
+ {
236
+ if (!budget.TryConsumeReflectionCall() || !budget.TryConsumeScannedRecord())
237
+ throw new UnityCliRequestBudgetExceededException(budget.ExhaustedDimension);
238
+ CountMemberMetadata(field, ref metadataBytes);
239
+ if (!field.IsPublic || field.IsStatic) continue;
240
+ AddBudgetedMember(members, field);
241
+ }
242
+ }
243
+
244
+ var result = members.Values.OrderBy(member => ToCamelCase(member.Name), StringComparer.Ordinal).ToArray();
245
+ lock (BudgetedMemberCacheLock)
246
+ {
247
+ if (BudgetedMemberCache.Count >= MaximumCachedProtocolTypes) BudgetedMemberCache.Clear();
248
+ BudgetedMemberCache[type] = result;
249
+ }
250
+ return result;
251
+ }
252
+
253
+ private static void AddBudgetedMember(IDictionary<string, MemberInfo> members, MemberInfo member)
254
+ {
255
+ var name = ToCamelCase(member.Name);
256
+ if (!members.ContainsKey(name)) members.Add(name, member);
257
+ if (members.Count > MaximumProtocolMembers) throw new UnityCliRequestBudgetExceededException("nodes");
258
+ }
259
+
260
+ private static void CountMemberMetadata(MemberInfo member, ref int metadataBytes)
261
+ {
262
+ var declaring = member.DeclaringType == null ? string.Empty : member.DeclaringType.FullName;
263
+ metadataBytes += Encoding.UTF8.GetByteCount(member.Name ?? string.Empty) + Encoding.UTF8.GetByteCount(declaring ?? string.Empty);
264
+ if (metadataBytes > MaximumMemberMetadataUtf8Bytes) throw new UnityCliRequestBudgetExceededException("serializedUtf8Bytes");
265
+ }
266
+
267
+ private static void WriteBudgetedString(BudgetedJsonWriter writer, string value)
268
+ {
269
+ writer.Append("\"");
270
+ if (value != null)
271
+ {
272
+ var runStart = 0;
273
+ for (var index = 0; index < value.Length; index++)
274
+ {
275
+ string escaped = null;
276
+ switch (value[index])
277
+ {
278
+ case '"': escaped = "\\\""; break;
279
+ case '\\': escaped = "\\\\"; break;
280
+ case '\b': escaped = "\\b"; break;
281
+ case '\f': escaped = "\\f"; break;
282
+ case '\n': escaped = "\\n"; break;
283
+ case '\r': escaped = "\\r"; break;
284
+ case '\t': escaped = "\\t"; break;
285
+ default:
286
+ if (value[index] < 0x20) escaped = "\\u" + ((int)value[index]).ToString("x4", CultureInfo.InvariantCulture);
287
+ break;
288
+ }
289
+ if (escaped == null) continue;
290
+ if (index > runStart) writer.Append(value.Substring(runStart, index - runStart));
291
+ writer.Append(escaped);
292
+ runStart = index + 1;
293
+ }
294
+ if (runStart < value.Length) writer.Append(value.Substring(runStart));
295
+ }
296
+ writer.Append("\"");
297
+ }
298
+
299
+ private sealed class BudgetedJsonWriter
300
+ {
301
+ private readonly StringBuilder builder = new StringBuilder();
302
+ private readonly UnityCliRequestBudget budget;
303
+ private readonly CancellationToken cancellationToken;
304
+ private long utf8Bytes;
305
+
306
+ internal BudgetedJsonWriter(UnityCliRequestBudget budget, CancellationToken cancellationToken)
307
+ {
308
+ this.budget = budget;
309
+ this.cancellationToken = cancellationToken;
310
+ }
311
+
312
+ internal void Append(string value)
313
+ {
314
+ cancellationToken.ThrowIfCancellationRequested();
315
+ budget.CheckpointOrThrow();
316
+ var next = checked(utf8Bytes + Encoding.UTF8.GetByteCount(value ?? string.Empty));
317
+ budget.ValidateSerializedUtf8Bytes(next);
318
+ builder.Append(value);
319
+ utf8Bytes = next;
320
+ }
321
+
322
+ internal long Utf8Bytes { get { return utf8Bytes; } }
323
+
324
+ public override string ToString() { return builder.ToString(); }
325
+ }
326
+
107
327
  // PascalCase → camelCase:仅首字母小写(对生成 DTO 的标准 PascalCase 足够)。
108
328
  private static string ToCamelCase(string name)
109
329
  {
@@ -35,44 +35,84 @@ namespace UnityCli
35
35
  {
36
36
  recoveryBlocked = false;
37
37
  if (!RecoverStaleOwner()) { recoveryBlocked = true; return; }
38
- TryFinalizeOwnedPlayModeRoot();
39
- Owner current;
40
- byte[] ignored;
41
- if (!TryReadOwnerSnapshot(out current, out ignored)) { recoveryBlocked = true; return; }
38
+ try
39
+ {
40
+ var directOutcome = ReconcileAcceptedDirectMutationBeforeLeaseRestore(ProductionQueueState, null);
41
+ if (directOutcome == DirectMutationReloadOutcome.IdentityBlocked)
42
+ {
43
+ recoveryBlocked = true;
44
+ return;
45
+ }
46
+ TryFinalizeOwnedPlayModeRoot();
47
+ if (!RestoreValidatedActiveRootLease(ProductionQueueState)) recoveryBlocked = true;
48
+ }
49
+ catch { recoveryBlocked = true; }
50
+ }
51
+
52
+ /// <summary>测试只通过隔离state执行与production相同的direct reconciliation→generic restore顺序。</summary>
53
+ internal static string InitializeRecoveryOrderForTests(BridgeQueueState state, bool cleanupPending = false)
54
+ {
55
+ if (state == null || state.IsolatedExecution == null)
56
+ throw new ArgumentException("Lease recovery order tests require isolated state.", "state");
57
+ var directOutcome = ReconcileAcceptedDirectMutationBeforeLeaseRestore(state, (requestId, requestDigest) => cleanupPending);
58
+ return directOutcome == DirectMutationReloadOutcome.IdentityBlocked || !RestoreValidatedActiveRootLease(state)
59
+ ? DirectMutationReloadOutcome.IdentityBlocked.ToString()
60
+ : directOutcome.ToString();
61
+ }
42
62
 
43
- // 仅交叉读取每个 coordinator 的固定 active 文件,不扫描任何请求目录。
44
- // 铁律:active 文件属上次启动(editorSessionId 不符)时不恢复,机制状态重启作废。
63
+ /// <summary>accepted direct root必须先冻结effect-before终态;显式依赖默认使用production cleanup identity。</summary>
64
+ private static DirectMutationReloadOutcome ReconcileAcceptedDirectMutationBeforeLeaseRestore(BridgeQueueState state, Func<string, string, bool> cleanupPending)
65
+ {
66
+ var root = state.LoadOperation("direct-mutation");
67
+ if (root == null || !string.Equals(root.ContainsKey("phase") ? root["phase"] as string : null, "accepted_before_effect", StringComparison.Ordinal))
68
+ return DirectMutationReloadOutcome.NotApplicable;
69
+ if (!string.Equals(root.ContainsKey("editorSessionId") ? root["editorSessionId"] as string : null, EditorSessionId(), StringComparison.Ordinal))
70
+ {
71
+ state.ClearOperation("direct-mutation");
72
+ return DirectMutationReloadOutcome.NotApplicable;
73
+ }
74
+ var requestId = root.ContainsKey("requestId") ? root["requestId"] as string : null;
75
+ var requestDigest = root.ContainsKey("requestDigest") ? root["requestDigest"] as string : null;
76
+ var releaseExactOwner = cleanupPending == null
77
+ ? DirectMutationCleanupPendingForIdentity(requestId, requestDigest)
78
+ : cleanupPending(requestId, requestDigest);
79
+ return ReconcileAcceptedDirectMutationAfterReload(state, requestId, requestDigest, releaseExactOwner);
80
+ }
81
+
82
+ /// <summary>固定scope恢复只接受当前session唯一root;direct reconciliation已经在本方法之前完成。</summary>
83
+ private static bool RestoreValidatedActiveRootLease(BridgeQueueState state)
84
+ {
85
+ string currentRequestId;
86
+ string currentRequestDigest;
87
+ if (!state.TryGetCurrentLeaseOwner(out currentRequestId, out currentRequestDigest)) return false;
45
88
  Owner recoverable = null;
46
89
  var currentSession = EditorSessionId();
47
90
  foreach (var scope in new[] { "compile", "package-resolve", "refresh", "asset-refresh", "package-embed", "test-run", "build", "navmesh-bake", "occlusion-bake", "direct-mutation" })
48
91
  {
49
- if (!UnityCliActiveOperation.Exists(scope)) continue;
50
- try
92
+ if (!state.OperationExists(scope)) continue;
93
+ Dictionary<string, object> root;
94
+ try { root = state.LoadOperation(scope); }
95
+ catch { return false; }
96
+ object requestId;
97
+ object requestDigest;
98
+ object stateSession;
99
+ if (root == null || !root.TryGetValue("requestId", out requestId) || !root.TryGetValue("requestDigest", out requestDigest)
100
+ || !root.TryGetValue("editorSessionId", out stateSession)) return false;
101
+ if (!string.Equals(stateSession as string, currentSession, StringComparison.Ordinal))
51
102
  {
52
- var state = UnityCliActiveOperation.Load(scope);
53
- object requestId;
54
- object requestDigest;
55
- object stateSession;
56
- if (state == null || !state.TryGetValue("requestId", out requestId) || !state.TryGetValue("requestDigest", out requestDigest)
57
- || !state.TryGetValue("editorSessionId", out stateSession)) { recoveryBlocked = true; return; }
58
- if (!string.Equals(stateSession as string, currentSession, StringComparison.Ordinal)) { UnityCliActiveOperation.Clear(scope); continue; }
59
- var candidate = new Owner { RequestId = requestId as string, RequestDigest = requestDigest as string };
60
- if (!IsSafeId(candidate.RequestId) || !IsSha256(candidate.RequestDigest)) { recoveryBlocked = true; return; }
61
- if (recoverable != null) { recoveryBlocked = true; return; }
62
- recoverable = candidate;
103
+ state.ClearOperation(scope);
104
+ continue;
63
105
  }
64
- catch { recoveryBlocked = true; return; }
65
- }
66
- if (recoverable == null) return;
67
- if (current != null)
68
- {
69
- if (!OwnsCurrentProcess(current)
70
- || !string.Equals(current.RequestId, recoverable.RequestId, StringComparison.Ordinal)
71
- || !string.Equals(current.RequestDigest, recoverable.RequestDigest, StringComparison.Ordinal)) recoveryBlocked = true;
72
- return;
106
+ var candidate = new Owner { RequestId = requestId as string, RequestDigest = requestDigest as string };
107
+ if (!IsSafeId(candidate.RequestId) || !IsSha256(candidate.RequestDigest) || recoverable != null) return false;
108
+ recoverable = candidate;
73
109
  }
110
+ if (recoverable == null) return true;
111
+ if (!string.IsNullOrEmpty(currentRequestId) || !string.IsNullOrEmpty(currentRequestDigest))
112
+ return string.Equals(currentRequestId, recoverable.RequestId, StringComparison.Ordinal)
113
+ && string.Equals(currentRequestDigest, recoverable.RequestDigest, StringComparison.Ordinal);
74
114
  bool recoveredLease;
75
- if (!TryAcquireCore(recoverable.RequestId, recoverable.RequestDigest, true, out recoveredLease)) recoveryBlocked = true;
115
+ return state.TryRecoverLease(recoverable.RequestId, recoverable.RequestDigest, out recoveredLease);
76
116
  }
77
117
 
78
118
  /// <summary>