@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
@@ -13,10 +13,6 @@ export type BridgeRequest = ProtocolBridgeRequest<Record<string, unknown>>;
13
13
  export type BridgeError = ToolError<Record<string, unknown>>;
14
14
  export type BridgeResponse = ProtocolEnvelope<Record<string, unknown>, Record<string, unknown>>;
15
15
  export type BridgeFlags = Record<string, string | boolean>;
16
- /** 动态 Tool 的 live descriptor 指纹只用于正确性校验,不构成执行授权。 */
17
- export interface BridgeDescriptorBinding {
18
- liveDescriptorFingerprint?: string;
19
- }
20
16
  export interface BridgeInvocationOptions {
21
17
  mode?: "execute" | "read" | "observeNow";
22
18
  mutation?: boolean;
@@ -28,14 +24,19 @@ export interface BridgeInvocationOptions {
28
24
  /** 仅 editor.state 内部传递已完成的真实选择结果;Symbol 字段不会进入公开请求。 */
29
25
  [observationSelectionKey]?: import("../instances.js").InstanceSelection;
30
26
  [transitionBindingKey]?: true;
27
+ [transitionResponseKey]?: true;
31
28
  }
32
29
  declare const observationSelectionKey: unique symbol;
33
30
  declare const transitionBindingKey: unique symbol;
31
+ declare const transitionResponseKey: unique symbol;
34
32
  export declare function withObservationSelection(options: Omit<BridgeInvocationOptions, typeof observationSelectionKey>, selection: import("../instances.js").InstanceSelection): BridgeInvocationOptions;
35
33
  export declare function observationSelectionFrom(options: BridgeInvocationOptions): import("../instances.js").InstanceSelection | undefined;
36
- /** compile continuation 可在 registry transitioning 时绑定同一会话。 */
34
+ /** 仅白名单内的跨 reload 内部调用可在 registry transitioning 时绑定同一会话。 */
37
35
  export declare function withTransitionBinding(options: Omit<BridgeInvocationOptions, typeof transitionBindingKey>): BridgeInvocationOptions;
38
36
  export declare function transitionBindingAllowed(options: BridgeInvocationOptions): boolean;
37
+ /** 仅 durable status coordinator 可接管 canonical transition 响应并重新观察。 */
38
+ export declare function withTransitionStatusObservation(options: Omit<BridgeInvocationOptions, typeof transitionBindingKey | typeof transitionResponseKey | "mode" | "mutation">): BridgeInvocationOptions;
39
+ export declare function transitionResponseAllowed(options: BridgeInvocationOptions): boolean;
39
40
  export interface BridgeArgContext {
40
41
  command: string;
41
42
  flags: BridgeFlags;
@@ -1,17 +1,31 @@
1
- // 不导出 key,外部 flags、CLI 输入和 JSON 均不能伪造这个内部调用字段。
1
+ // 不导出 key,外部 flags、CLI 输入和 JSON 均不能伪造这些内部调用字段。
2
2
  const observationSelectionKey = Symbol("unity-cli.observation-selection");
3
3
  const transitionBindingKey = Symbol("unity-cli.transition-binding");
4
+ const transitionResponseKey = Symbol("unity-cli.transition-response");
4
5
  export function withObservationSelection(options, selection) {
5
6
  return { ...options, [observationSelectionKey]: selection };
6
7
  }
7
8
  export function observationSelectionFrom(options) {
8
9
  return options[observationSelectionKey];
9
10
  }
10
- /** compile continuation 可在 registry transitioning 时绑定同一会话。 */
11
+ /** 仅白名单内的跨 reload 内部调用可在 registry transitioning 时绑定同一会话。 */
11
12
  export function withTransitionBinding(options) {
12
13
  return { ...options, [transitionBindingKey]: true };
13
14
  }
14
15
  export function transitionBindingAllowed(options) {
15
16
  return options[transitionBindingKey] === true;
16
17
  }
18
+ /** 仅 durable status coordinator 可接管 canonical transition 响应并重新观察。 */
19
+ export function withTransitionStatusObservation(options) {
20
+ return {
21
+ ...options,
22
+ mode: "read",
23
+ mutation: false,
24
+ [transitionBindingKey]: true,
25
+ [transitionResponseKey]: true,
26
+ };
27
+ }
28
+ export function transitionResponseAllowed(options) {
29
+ return options[transitionResponseKey] === true;
30
+ }
17
31
  //# sourceMappingURL=types.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/bridge/types.ts"],"names":[],"mappings":"AA4CA,+CAA+C;AAC/C,MAAM,uBAAuB,GAAkB,MAAM,CAAC,iCAAiC,CAAC,CAAC;AACzF,MAAM,oBAAoB,GAAkB,MAAM,CAAC,8BAA8B,CAAC,CAAC;AAEnF,MAAM,UAAU,wBAAwB,CACtC,OAAsE,EACtE,SAAsD;IAEtD,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,uBAAuB,CAAC,EAAE,SAAS,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAAgC;IACvE,OAAO,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAC1C,CAAC;AAED,gEAAgE;AAChE,MAAM,UAAU,qBAAqB,CAAC,OAAmE;IACvG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAAgC;IACvE,OAAO,OAAO,CAAC,oBAAoB,CAAC,KAAK,IAAI,CAAC;AAChD,CAAC"}
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/bridge/types.ts"],"names":[],"mappings":"AAwCA,+CAA+C;AAC/C,MAAM,uBAAuB,GAAkB,MAAM,CAAC,iCAAiC,CAAC,CAAC;AACzF,MAAM,oBAAoB,GAAkB,MAAM,CAAC,8BAA8B,CAAC,CAAC;AACnF,MAAM,qBAAqB,GAAkB,MAAM,CAAC,+BAA+B,CAAC,CAAC;AAErF,MAAM,UAAU,wBAAwB,CACtC,OAAsE,EACtE,SAAsD;IAEtD,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,uBAAuB,CAAC,EAAE,SAAS,EAAE,CAAC;AAC9D,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAAgC;IACvE,OAAO,OAAO,CAAC,uBAAuB,CAAC,CAAC;AAC1C,CAAC;AAED,4DAA4D;AAC5D,MAAM,UAAU,qBAAqB,CAAC,OAAmE;IACvG,OAAO,EAAE,GAAG,OAAO,EAAE,CAAC,oBAAoB,CAAC,EAAE,IAAI,EAAE,CAAC;AACtD,CAAC;AAED,MAAM,UAAU,wBAAwB,CAAC,OAAgC;IACvE,OAAO,OAAO,CAAC,oBAAoB,CAAC,KAAK,IAAI,CAAC;AAChD,CAAC;AAED,qEAAqE;AACrE,MAAM,UAAU,+BAA+B,CAC7C,OAAwH;IAExH,OAAO;QACL,GAAG,OAAO;QACV,IAAI,EAAE,MAAM;QACZ,QAAQ,EAAE,KAAK;QACf,CAAC,oBAAoB,CAAC,EAAE,IAAI;QAC5B,CAAC,qBAAqB,CAAC,EAAE,IAAI;KAC9B,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CAAC,OAAgC;IACxE,OAAO,OAAO,CAAC,qBAAqB,CAAC,KAAK,IAAI,CAAC;AACjD,CAAC"}
@@ -0,0 +1,64 @@
1
+ import { type ProjectToolRuntime } from "./project-tool-discovery.js";
2
+ import type { CliResult } from "./types.js";
3
+ import { type ResolvedToolMetadata } from "./tools/metadata/index.js";
4
+ export declare const MAX_CATALOG_PAGE_FETCH = 101;
5
+ export interface CatalogSummaryQuery {
6
+ group?: string;
7
+ keyword?: string;
8
+ limit: number;
9
+ expectedGeneration?: string;
10
+ reservedNames: string[];
11
+ localNames: string[];
12
+ cursorContext: string;
13
+ cursorToken?: string;
14
+ }
15
+ export interface CatalogRoutingSummary {
16
+ name: string;
17
+ summary: string;
18
+ group: string;
19
+ target: "editor" | "runtime" | "both";
20
+ contractProfile: "native" | "official-attribute";
21
+ commandName?: string;
22
+ available?: false;
23
+ unavailableReason?: string;
24
+ }
25
+ export interface CatalogGroupSummary {
26
+ name: string;
27
+ toolCount: number;
28
+ }
29
+ export type CatalogSummaryResult = {
30
+ ok: true;
31
+ generation: string;
32
+ total: number;
33
+ tools: CatalogRoutingSummary[];
34
+ hasMore: boolean;
35
+ pageNames: string[];
36
+ continuationToken: string;
37
+ } | (CliResult & {
38
+ ok: false;
39
+ });
40
+ export type CatalogGroupsResult = {
41
+ ok: true;
42
+ generation: string;
43
+ groups: CatalogGroupSummary[];
44
+ } | (CliResult & {
45
+ ok: false;
46
+ });
47
+ export type CatalogDescribeResult = {
48
+ ok: true;
49
+ generation: string;
50
+ tool?: ResolvedToolMetadata;
51
+ } | (CliResult & {
52
+ ok: false;
53
+ });
54
+ /** Editor catalog summary 在 Bridge 主线程完成筛选和上限裁剪。 */
55
+ export declare function readEditorCatalogSummary(flags: Record<string, string | boolean>, runtime: ProjectToolRuntime, requestId: string, query: CatalogSummaryQuery, absoluteDeadlineMs?: number): Promise<CatalogSummaryResult>;
56
+ /** Runtime catalog summary 只补充当前 Runtime target 的可用性。 */
57
+ export declare function readRuntimeCatalogSummary(flags: Record<string, string | boolean>, runtime: ProjectToolRuntime, requestId: string, query: CatalogSummaryQuery, absoluteDeadlineMs?: number): Promise<CatalogSummaryResult>;
58
+ /** Group 聚合只传输 group/count,不物化 descriptor 图。 */
59
+ export declare function readEditorCatalogGroups(flags: Record<string, string | boolean>, runtime: ProjectToolRuntime, requestId: string, expectedGeneration: string | undefined, reservedNames: string[], absoluteDeadlineMs?: number): Promise<CatalogGroupsResult>;
60
+ export declare function readRuntimeCatalogGroups(flags: Record<string, string | boolean>, runtime: ProjectToolRuntime, requestId: string, expectedGeneration: string | undefined, reservedNames: string[], absoluteDeadlineMs?: number): Promise<CatalogGroupsResult>;
61
+ /** exact descriptor retrieval 是 schema/执行解析的唯一 live 入口。 */
62
+ export declare function readEditorCatalogDescriptor(flags: Record<string, string | boolean>, runtime: ProjectToolRuntime, requestId: string, name: string, absoluteDeadlineMs?: number, fallbackName?: string): Promise<CatalogDescribeResult>;
63
+ export declare function readRuntimeCatalogDescriptor(flags: Record<string, string | boolean>, runtime: ProjectToolRuntime, requestId: string, name: string, absoluteDeadlineMs?: number): Promise<CatalogDescribeResult>;
64
+ export declare function compareText(left: string, right: string): number;
@@ -0,0 +1,460 @@
1
+ import { createHash, createHmac, randomBytes, timingSafeEqual } from "node:crypto";
2
+ import { executeBridgePayload } from "./bridge/index.js";
3
+ import { failure } from "./output.js";
4
+ import { projectDescriptorToToolMetadata } from "./project-tool-discovery.js";
5
+ import { normalizeToolMetadata } from "./tools/metadata/index.js";
6
+ export const MAX_CATALOG_PAGE_FETCH = 101;
7
+ const MAX_CATALOG_SUMMARY_BYTES = 256 * 1024;
8
+ const MAX_CATALOG_GROUPS_BYTES = 2 * 1024 * 1024;
9
+ const MAX_CATALOG_DESCRIPTOR_BYTES = 3 * 1024 * 1024;
10
+ const fixtureCursorSecret = randomBytes(32);
11
+ /** Editor catalog summary 在 Bridge 主线程完成筛选和上限裁剪。 */
12
+ export function readEditorCatalogSummary(flags, runtime, requestId, query, absoluteDeadlineMs) {
13
+ return readCatalogSummary("editor", flags, runtime, requestId, query, absoluteDeadlineMs);
14
+ }
15
+ /** Runtime catalog summary 只补充当前 Runtime target 的可用性。 */
16
+ export function readRuntimeCatalogSummary(flags, runtime, requestId, query, absoluteDeadlineMs) {
17
+ return readCatalogSummary("runtime", flags, runtime, requestId, query, absoluteDeadlineMs);
18
+ }
19
+ /** Group 聚合只传输 group/count,不物化 descriptor 图。 */
20
+ export function readEditorCatalogGroups(flags, runtime, requestId, expectedGeneration, reservedNames, absoluteDeadlineMs) {
21
+ return readCatalogGroups("editor", flags, runtime, requestId, expectedGeneration, reservedNames, absoluteDeadlineMs);
22
+ }
23
+ export function readRuntimeCatalogGroups(flags, runtime, requestId, expectedGeneration, reservedNames, absoluteDeadlineMs) {
24
+ return readCatalogGroups("runtime", flags, runtime, requestId, expectedGeneration, reservedNames, absoluteDeadlineMs);
25
+ }
26
+ /** exact descriptor retrieval 是 schema/执行解析的唯一 live 入口。 */
27
+ export function readEditorCatalogDescriptor(flags, runtime, requestId, name, absoluteDeadlineMs, fallbackName) {
28
+ return readCatalogDescriptor("editor", flags, runtime, requestId, name, absoluteDeadlineMs, fallbackName);
29
+ }
30
+ export function readRuntimeCatalogDescriptor(flags, runtime, requestId, name, absoluteDeadlineMs) {
31
+ return readCatalogDescriptor("runtime", flags, runtime, requestId, name, absoluteDeadlineMs);
32
+ }
33
+ async function readCatalogSummary(target, flags, runtime, requestId, query, absoluteDeadlineMs) {
34
+ const queryFailure = validateSummaryQuery(requestId, query);
35
+ if (queryFailure)
36
+ return queryFailure;
37
+ const fixture = target === "runtime" ? runtime.runtimeTools ?? runtime.projectTools : runtime.projectTools;
38
+ if (fixture)
39
+ return summarizeFixture(target, fixture, requestId, query);
40
+ const command = `${target === "editor" ? "project" : "runtime"}-tool.summary`;
41
+ const result = await executeBridgePayload(requestId, command, {
42
+ ...(query.group ? { group: query.group } : {}),
43
+ ...(query.keyword ? { keyword: query.keyword } : {}),
44
+ limit: query.limit,
45
+ ...(query.expectedGeneration ? { expectedCatalogGeneration: query.expectedGeneration } : {}),
46
+ reservedNames: query.reservedNames,
47
+ ...(query.localNames ? { localNames: query.localNames } : {}),
48
+ ...(query.cursorContext ? { cursorContext: query.cursorContext } : {}),
49
+ ...(query.cursorToken ? { cursorToken: query.cursorToken } : {}),
50
+ }, flags, runtime, { mode: "read", mutation: false, absoluteDeadlineMs });
51
+ if (!result.ok)
52
+ return result;
53
+ return parseSummaryResponse(result.data, requestId, command, query);
54
+ }
55
+ async function readCatalogGroups(target, flags, runtime, requestId, expectedGeneration, reservedNames, absoluteDeadlineMs) {
56
+ const boundsFailure = validateGenerationAndReservedNames(requestId, expectedGeneration, reservedNames);
57
+ if (boundsFailure)
58
+ return boundsFailure;
59
+ const fixture = target === "runtime" ? runtime.runtimeTools ?? runtime.projectTools : runtime.projectTools;
60
+ if (fixture)
61
+ return groupsFixture(target, fixture, requestId, expectedGeneration, reservedNames);
62
+ const command = `${target === "editor" ? "project" : "runtime"}-tool.groups`;
63
+ const result = await executeBridgePayload(requestId, command, {
64
+ ...(expectedGeneration ? { expectedCatalogGeneration: expectedGeneration } : {}),
65
+ reservedNames,
66
+ }, flags, runtime, { mode: "read", mutation: false, absoluteDeadlineMs });
67
+ if (!result.ok)
68
+ return result;
69
+ return parseGroupsResponse(result.data, requestId, command);
70
+ }
71
+ async function readCatalogDescriptor(target, flags, runtime, requestId, name, absoluteDeadlineMs, fallbackName) {
72
+ if (!name || utf8ByteLength(name) > 256)
73
+ return schemaFailure(requestId, "Catalog describe name is required and must not exceed 256 UTF-8 bytes.");
74
+ if (fallbackName !== undefined && (!fallbackName || utf8ByteLength(fallbackName) > 256 || fallbackName === name)) {
75
+ return schemaFailure(requestId, "Catalog describe fallbackName must be distinct and must not exceed 256 characters.");
76
+ }
77
+ const fixture = target === "runtime" ? runtime.runtimeTools ?? runtime.projectTools : runtime.projectTools;
78
+ if (fixture) {
79
+ const tools = fixtureTools(target, fixture);
80
+ const integrity = fixtureCatalogIntegrity(requestId, tools);
81
+ if (integrity)
82
+ return integrity;
83
+ return {
84
+ ok: true,
85
+ generation: fixtureGeneration(target, tools),
86
+ tool: tools.find((tool) => tool.name === name) ?? (fallbackName ? tools.find((tool) => tool.name === fallbackName) : undefined),
87
+ };
88
+ }
89
+ const command = `${target === "editor" ? "project" : "runtime"}-tool.describe`;
90
+ const input = target === "editor" && fallbackName ? { name, fallbackName } : { name };
91
+ const result = await executeBridgePayload(requestId, command, input, flags, runtime, { mode: "read", mutation: false, absoluteDeadlineMs });
92
+ if (!result.ok)
93
+ return result;
94
+ return parseDescriptorResponse(result.data, requestId, command, name, target, target === "editor" ? fallbackName : undefined);
95
+ }
96
+ /** 测试注入仍执行真实筛选、generation 与 ownership 规则。 */
97
+ function summarizeFixture(target, fixture, requestId, query) {
98
+ const tools = fixtureTools(target, fixture);
99
+ const integrity = fixtureCatalogIntegrity(requestId, tools);
100
+ if (integrity)
101
+ return integrity;
102
+ const generation = fixtureGeneration(target, tools);
103
+ const generationFailure = requireGeneration(requestId, query.expectedGeneration, generation);
104
+ if (generationFailure)
105
+ return generationFailure;
106
+ const ownershipFailure = reservedNameConflict(requestId, tools, query.reservedNames);
107
+ if (ownershipFailure)
108
+ return ownershipFailure;
109
+ const tokens = searchTokens(query.keyword);
110
+ const matches = tools.filter((tool) => (!query.group || tool.group === query.group)
111
+ && (tokens.length === 0 || tokens.some((token) => [tool.name, tool.summary, tool.description, tool.group]
112
+ .some((value) => value.toLowerCase().includes(token))))).sort(compareToolName);
113
+ const nativeNames = new Set([...tools.filter((item) => item.contractProfile !== "official-attribute").map((item) => item.name), ...query.reservedNames]);
114
+ const scope = fixtureCursorScope(target, generation, query);
115
+ const cursor = query.cursorToken ? verifyFixtureCursor(query.cursorToken, scope) : { offset: 0, boundary: "" };
116
+ if (!cursor)
117
+ return invalidCursor(requestId);
118
+ const localNames = query.localNames ?? [];
119
+ const combinedNames = [...new Set([...localNames, ...matches.map((tool) => tool.name)])].sort(compareText);
120
+ if (cursor.offset > combinedNames.length || cursor.offset > 0 && combinedNames[cursor.offset - 1] !== cursor.boundary)
121
+ return invalidCursor(requestId);
122
+ const end = Math.min(cursor.offset + query.limit, combinedNames.length);
123
+ const pageNames = new Set(combinedNames.slice(cursor.offset, end));
124
+ const hasMore = end < combinedNames.length;
125
+ return {
126
+ ok: true,
127
+ generation,
128
+ total: matches.length,
129
+ tools: matches.filter((tool) => pageNames.has(tool.name)).map((tool) => routingSummary(tool, nativeNames)),
130
+ hasMore,
131
+ pageNames: combinedNames.slice(cursor.offset, end),
132
+ continuationToken: signFixtureCursor(scope, end, combinedNames[end - 1] ?? cursor.boundary),
133
+ };
134
+ }
135
+ function groupsFixture(target, fixture, requestId, expectedGeneration, reservedNames) {
136
+ const tools = fixtureTools(target, fixture);
137
+ const integrity = fixtureCatalogIntegrity(requestId, tools);
138
+ if (integrity)
139
+ return integrity;
140
+ const generation = fixtureGeneration(target, tools);
141
+ const generationFailure = requireGeneration(requestId, expectedGeneration, generation);
142
+ if (generationFailure)
143
+ return generationFailure;
144
+ const ownershipFailure = reservedNameConflict(requestId, tools, reservedNames);
145
+ if (ownershipFailure)
146
+ return ownershipFailure;
147
+ const groups = new Map();
148
+ for (const tool of tools)
149
+ groups.set(tool.group, (groups.get(tool.group) ?? 0) + 1);
150
+ return {
151
+ ok: true,
152
+ generation,
153
+ groups: [...groups].sort(([left], [right]) => compareText(left, right)).map(([name, toolCount]) => ({ name, toolCount })),
154
+ };
155
+ }
156
+ function fixtureTools(target, fixture) {
157
+ return fixture.map((tool) => normalizeToolMetadata(tool, tool.source ?? "project"))
158
+ .filter((tool) => target === "editor" || tool.target === "runtime" || tool.target === "both");
159
+ }
160
+ function fixtureCatalogIntegrity(requestId, tools) {
161
+ const names = new Set();
162
+ for (const tool of tools) {
163
+ if (utf8ByteLength(tool.name) > 256 || utf8ByteLength(tool.summary) > 512 || utf8ByteLength(tool.group) > 256)
164
+ return failure(requestId, "E_TOOL_REGISTRY_UNHEALTHY", `Tool ${tool.name} exceeds a catalog routing field bound.`, ["Shorten the Tool name, group, or summary before retrying discovery."]);
165
+ if (names.has(tool.name))
166
+ return failure(requestId, "E_TOOL_SCHEMA_CONFLICT", `Tool catalog conflict for ${tool.name}: duplicate live registrations use the same name.`, ["Fix the duplicate Tool registration, then retry discovery."]);
167
+ names.add(tool.name);
168
+ const attribute = tool.contractProfile === "official-attribute";
169
+ const prefix = tool.name.startsWith("UnityPipeline_");
170
+ const group = tool.group === "UnityPipeline";
171
+ if (attribute && (!prefix || !group))
172
+ return failure(requestId, "E_TOOL_SCHEMA_CONFLICT", `Tool catalog conflict for ${tool.name}: official-attribute registration must use the UnityPipeline_ prefix and UnityPipeline group.`, ["Fix the Tool registration, then retry discovery."]);
173
+ if (!attribute && (prefix || group))
174
+ return failure(requestId, "E_TOOL_SCHEMA_CONFLICT", `Tool catalog conflict for ${tool.name}: native registration cannot use the reserved UnityPipeline_ prefix or UnityPipeline group.`, ["Fix the Tool registration, then retry discovery."]);
175
+ }
176
+ return undefined;
177
+ }
178
+ function fixtureGeneration(target, tools) {
179
+ const material = tools.sort(compareToolName).map((tool) => [
180
+ tool.name, tool.summary, tool.description, tool.group, tool.target, tool.contractProfile,
181
+ tool.available ?? true, tool.unavailableReason ?? "",
182
+ ]);
183
+ return createHash("sha256").update(JSON.stringify({ target, tools: material }), "utf8").digest("hex");
184
+ }
185
+ function routingSummary(tool, nativeNames) {
186
+ const available = tool.available ?? true;
187
+ const attributeName = tool.contractProfile === "official-attribute" && tool.name.startsWith("UnityPipeline_")
188
+ ? tool.name.slice("UnityPipeline_".length)
189
+ : tool.name;
190
+ return {
191
+ name: tool.name,
192
+ summary: tool.summary,
193
+ group: tool.group,
194
+ target: tool.target === "runtime" || tool.target === "both" ? tool.target : "editor",
195
+ contractProfile: tool.contractProfile ?? "native",
196
+ commandName: tool.contractProfile === "official-attribute" && !nativeNames.has(attributeName) ? attributeName : tool.name,
197
+ ...(!available ? { available: false, unavailableReason: tool.unavailableReason } : {}),
198
+ };
199
+ }
200
+ function parseSummaryResponse(data, requestId, command, query) {
201
+ if (jsonByteLength(data) > MAX_CATALOG_SUMMARY_BYTES)
202
+ return unhealthySummary(requestId, `${command} exceeded the bounded summary transport size.`);
203
+ const record = objectRecord(data);
204
+ const generation = stringField(record, "catalogGeneration");
205
+ const total = numberField(record, "total");
206
+ const hasMore = record?.hasMore;
207
+ const rawTools = record?.tools;
208
+ const continuationToken = record?.continuationToken;
209
+ const rawPageNames = record?.pageNames;
210
+ const allowedKeys = ["catalogGeneration", "total", "hasMore", "tools", "pageNames", "continuationToken"];
211
+ if (!record || !hasOnlyKeys(record, allowedKeys)
212
+ || !generation || utf8ByteLength(generation) > 128 || total === undefined || !Number.isSafeInteger(total) || total < 0
213
+ || typeof hasMore !== "boolean" || !Array.isArray(rawTools) || rawTools.length > query.limit || rawTools.length > total
214
+ || !Array.isArray(rawPageNames) || rawPageNames.length > query.limit
215
+ || rawPageNames.some((name) => typeof name !== "string" || !name || utf8ByteLength(name) > 256)
216
+ || !strictlySortedUnique(rawPageNames)
217
+ || typeof continuationToken !== "string" || !continuationToken || utf8ByteLength(continuationToken) > 8192) {
218
+ return unhealthySummary(requestId, `${command} returned an invalid bounded summary envelope.`);
219
+ }
220
+ const tools = [];
221
+ for (let index = 0; index < rawTools.length; index += 1) {
222
+ const parsed = parseRoutingSummary(rawTools[index]);
223
+ if (!parsed)
224
+ return unhealthySummary(requestId, `${command} tools[${index}] is not a routing summary.`);
225
+ if (query.group && parsed.group !== query.group)
226
+ return unhealthySummary(requestId, `${command} tools[${index}] escaped the requested group.`);
227
+ tools.push(parsed);
228
+ }
229
+ if (!strictlySortedUnique(tools.map((tool) => tool.name))) {
230
+ return unhealthySummary(requestId, `${command} summary names must be unique and ordinally sorted.`);
231
+ }
232
+ return {
233
+ ok: true,
234
+ generation,
235
+ total,
236
+ tools,
237
+ hasMore,
238
+ pageNames: rawPageNames,
239
+ continuationToken: continuationToken,
240
+ };
241
+ }
242
+ function parseGroupsResponse(data, requestId, command) {
243
+ if (jsonByteLength(data) > MAX_CATALOG_GROUPS_BYTES)
244
+ return unhealthySummary(requestId, `${command} exceeded the bounded group transport size.`);
245
+ const record = objectRecord(data);
246
+ const generation = stringField(record, "catalogGeneration");
247
+ const rawGroups = record?.groups;
248
+ if (!record || !hasOnlyKeys(record, ["catalogGeneration", "groups"]) || !generation || utf8ByteLength(generation) > 128
249
+ || !Array.isArray(rawGroups) || rawGroups.length > 4096) {
250
+ return unhealthySummary(requestId, `${command} returned an invalid group envelope.`);
251
+ }
252
+ const groups = [];
253
+ for (let index = 0; index < rawGroups.length; index += 1) {
254
+ const item = objectRecord(rawGroups[index]);
255
+ const name = stringField(item, "name");
256
+ const toolCount = numberField(item, "toolCount");
257
+ if (!item || !hasOnlyKeys(item, ["name", "toolCount"]) || !name || utf8ByteLength(name) > 256
258
+ || toolCount === undefined || !Number.isSafeInteger(toolCount) || toolCount < 1) {
259
+ return unhealthySummary(requestId, `${command} groups[${index}] is invalid.`);
260
+ }
261
+ groups.push({ name, toolCount });
262
+ }
263
+ if (!strictlySortedUnique(groups.map((group) => group.name)))
264
+ return unhealthySummary(requestId, `${command} group names must be unique and ordinally sorted.`);
265
+ return { ok: true, generation, groups };
266
+ }
267
+ function parseDescriptorResponse(data, requestId, command, expectedName, target, fallbackName) {
268
+ if (jsonByteLength(data) > MAX_CATALOG_DESCRIPTOR_BYTES)
269
+ return unhealthySummary(requestId, `${command} exceeded the bounded exact descriptor transport size.`);
270
+ const record = objectRecord(data);
271
+ const generation = stringField(record, "catalogGeneration");
272
+ if (!record || !generation || utf8ByteLength(generation) > 128 || typeof record.found !== "boolean"
273
+ || !hasOnlyKeys(record, record.found ? ["catalogGeneration", "found", "descriptor"] : ["catalogGeneration", "found"])) {
274
+ return unhealthySummary(requestId, `${command} returned an invalid exact descriptor envelope.`);
275
+ }
276
+ if (!record.found)
277
+ return { ok: true, generation };
278
+ const tool = projectDescriptorToToolMetadata(record.descriptor);
279
+ if (!tool || tool.name !== expectedName && tool.name !== fallbackName
280
+ || target === "runtime" && tool.target !== "runtime" && tool.target !== "both") {
281
+ return unhealthySummary(requestId, `${command} returned a descriptor outside the exact requested identity.`);
282
+ }
283
+ return { ok: true, generation, tool };
284
+ }
285
+ function parseRoutingSummary(value) {
286
+ const record = objectRecord(value);
287
+ const name = stringField(record, "name");
288
+ const summary = stringField(record, "summary");
289
+ const group = stringField(record, "group");
290
+ const target = record?.target;
291
+ const contractProfile = record?.contractProfile;
292
+ const commandName = record?.commandName;
293
+ const available = record?.available;
294
+ const unavailableReason = record?.unavailableReason;
295
+ if (!record || !hasOnlyKeys(record, ["name", "summary", "group", "target", "contractProfile", "commandName", "available", "unavailableReason"])
296
+ || !name || utf8ByteLength(name) > 256 || !summary || utf8ByteLength(summary) > 512 || !group || utf8ByteLength(group) > 256
297
+ || !(target === "editor" || target === "runtime" || target === "both")
298
+ || !(contractProfile === "native" || contractProfile === "official-attribute")
299
+ || (commandName !== undefined && (typeof commandName !== "string" || !commandName || utf8ByteLength(commandName) > 256))
300
+ || (available !== undefined && available !== false)
301
+ || (available === false && (typeof unavailableReason !== "string" || !unavailableReason || utf8ByteLength(unavailableReason) > 2048))
302
+ || (available !== false && unavailableReason !== undefined))
303
+ return undefined;
304
+ const usesAttributePrefix = name.startsWith("UnityPipeline_");
305
+ const usesAttributeGroup = group === "UnityPipeline";
306
+ const attributeName = usesAttributePrefix ? name.slice("UnityPipeline_".length) : "";
307
+ if (contractProfile === "native" && (usesAttributePrefix || usesAttributeGroup || commandName !== undefined && commandName !== name))
308
+ return undefined;
309
+ if (contractProfile === "official-attribute" && (!usesAttributePrefix || !usesAttributeGroup || !attributeName
310
+ || commandName !== undefined && commandName !== name && commandName !== attributeName))
311
+ return undefined;
312
+ return {
313
+ name,
314
+ summary,
315
+ group,
316
+ target,
317
+ contractProfile,
318
+ ...(typeof commandName === "string" ? { commandName } : {}),
319
+ ...(available === false ? { available: false, unavailableReason: unavailableReason } : {}),
320
+ };
321
+ }
322
+ /** 注入fixture使用同形scope,确保测试不会绕过cursor integrity。 */
323
+ function fixtureCursorScope(target, generation, query) {
324
+ return createHash("sha256").update(JSON.stringify({
325
+ target,
326
+ generation,
327
+ cursorContext: query.cursorContext,
328
+ group: query.group ?? "",
329
+ keyword: query.keyword ?? "",
330
+ localNames: query.localNames ?? [],
331
+ reservedNames: query.reservedNames,
332
+ }), "utf8").digest("hex");
333
+ }
334
+ /** fixture secret仅活在当前测试进程,不进入产品持久状态。 */
335
+ function signFixtureCursor(scope, offset, boundary) {
336
+ const payload = Buffer.from(JSON.stringify({ scope, offset, boundary }), "utf8").toString("base64url");
337
+ const signature = createHmac("sha256", fixtureCursorSecret).update(payload, "utf8").digest("base64url");
338
+ return `${payload}.${signature}`;
339
+ }
340
+ /** 验证fixture token签名并恢复其不可编辑边界。 */
341
+ function verifyFixtureCursor(token, scope) {
342
+ try {
343
+ const [payload, signature, extra] = token.split(".");
344
+ if (!payload || !signature || extra !== undefined)
345
+ return undefined;
346
+ const actual = Buffer.from(signature, "base64url");
347
+ const expected = createHmac("sha256", fixtureCursorSecret).update(payload, "utf8").digest();
348
+ if (actual.length !== expected.length || !timingSafeEqual(actual, expected))
349
+ return undefined;
350
+ const parsed = JSON.parse(Buffer.from(payload, "base64url").toString("utf8"));
351
+ if (Object.keys(parsed).some((key) => !["scope", "offset", "boundary"].includes(key))
352
+ || parsed.scope !== scope || !Number.isSafeInteger(parsed.offset) || Number(parsed.offset) < 0
353
+ || typeof parsed.boundary !== "string" || utf8ByteLength(parsed.boundary) > 256
354
+ || Number(parsed.offset) === 0 !== (parsed.boundary === ""))
355
+ return undefined;
356
+ return { offset: Number(parsed.offset), boundary: parsed.boundary };
357
+ }
358
+ catch {
359
+ return undefined;
360
+ }
361
+ }
362
+ /** 统一fixture与live target的cursor拒绝语义。 */
363
+ function invalidCursor(requestId) {
364
+ return failure(requestId, "E_DISCOVERY_CURSOR_INVALID", "The target rejected an altered or cross-query discovery continuation.", [
365
+ "Restart this exact discovery query from its first page."
366
+ ]);
367
+ }
368
+ function requireGeneration(requestId, expected, actual) {
369
+ if (!expected || expected === actual)
370
+ return undefined;
371
+ return failure(requestId, "E_TOOL_CATALOG_CHANGED", "The Tool catalog generation changed before this continuation page was read.", [
372
+ "Restart this discovery query from its first page against the current Unity generation."
373
+ ]);
374
+ }
375
+ function reservedNameConflict(requestId, tools, reservedNames) {
376
+ const reserved = new Set(reservedNames);
377
+ const conflict = tools.find((tool) => reserved.has(tool.name));
378
+ if (!conflict)
379
+ return undefined;
380
+ return failure(requestId, "E_TOOL_SCHEMA_CONFLICT", `Tool catalog conflict for ${conflict.name}: package-local and live registrations use the same name.`, [
381
+ "Fix the duplicate Tool registration in the selected Unity project, then retry discovery."
382
+ ], { toolName: conflict.name, reason: "package-local and live registrations use the same name" });
383
+ }
384
+ function unhealthySummary(requestId, message) {
385
+ return failure(requestId, "E_TOOL_REGISTRY_UNHEALTHY", message, [
386
+ "Fix the Tool descriptor registry, then let Unity compile and reload the domain before retrying discovery."
387
+ ]);
388
+ }
389
+ function validateSummaryQuery(requestId, query) {
390
+ if (!Number.isSafeInteger(query.limit) || query.limit < 1 || query.limit > MAX_CATALOG_PAGE_FETCH) {
391
+ return schemaFailure(requestId, "Catalog summary limit must be an integer in [1,101].");
392
+ }
393
+ if (utf8ByteLength(query.group ?? "") > 256 || utf8ByteLength(query.keyword ?? "") > 2048) {
394
+ return schemaFailure(requestId, "Catalog summary filters exceed their bounded string limits.");
395
+ }
396
+ const tokens = searchTokens(query.keyword);
397
+ if (tokens.length > 16 || tokens.some((token) => utf8ByteLength(token) > 128)) {
398
+ return schemaFailure(requestId, "Catalog search accepts at most 16 keywords of at most 128 UTF-8 bytes each.");
399
+ }
400
+ if (query.localNames.length > 4096 || query.localNames.some((name) => !name || utf8ByteLength(name) > 256)
401
+ || !strictlySortedUnique(query.localNames))
402
+ return schemaFailure(requestId, "Catalog local names must be a bounded ordinally sorted set.");
403
+ if (!/^[a-f0-9]{64}$/.test(query.cursorContext))
404
+ return schemaFailure(requestId, "Catalog cursor context must be a SHA-256 value.");
405
+ if (query.cursorToken !== undefined && (!query.cursorToken || utf8ByteLength(query.cursorToken) > 8192)) {
406
+ return schemaFailure(requestId, "Catalog continuation token is invalid.");
407
+ }
408
+ return validateGenerationAndReservedNames(requestId, query.expectedGeneration, query.reservedNames);
409
+ }
410
+ function validateGenerationAndReservedNames(requestId, generation, reservedNames) {
411
+ if (utf8ByteLength(generation ?? "") > 128)
412
+ return schemaFailure(requestId, "Catalog generation exceeds its bounded string limit.");
413
+ if (reservedNames.length > 4096 || reservedNames.some((name) => !name || utf8ByteLength(name) > 256)) {
414
+ return schemaFailure(requestId, "Catalog reserved names exceed their bounded item or string limits.");
415
+ }
416
+ return undefined;
417
+ }
418
+ function schemaFailure(requestId, message) {
419
+ return failure(requestId, "E_SCHEMA_INVALID", message, ["Use the bounded private catalog protocol fields."]);
420
+ }
421
+ function searchTokens(keyword) {
422
+ return (keyword ?? "").split("|").map((token) => token.trim().toLowerCase()).filter(Boolean);
423
+ }
424
+ function jsonByteLength(value) {
425
+ try {
426
+ return Buffer.byteLength(JSON.stringify(value), "utf8");
427
+ }
428
+ catch {
429
+ return Number.POSITIVE_INFINITY;
430
+ }
431
+ }
432
+ /** catalog public string limits全部按wire UTF-8字节计算。 */
433
+ function utf8ByteLength(value) {
434
+ return Buffer.byteLength(value, "utf8");
435
+ }
436
+ function objectRecord(value) {
437
+ return value && typeof value === "object" && !Array.isArray(value) ? value : undefined;
438
+ }
439
+ function hasOnlyKeys(record, allowed) {
440
+ const keys = new Set(allowed);
441
+ return Object.keys(record).every((key) => keys.has(key));
442
+ }
443
+ function stringField(record, key) {
444
+ const value = record?.[key];
445
+ return typeof value === "string" && value.length > 0 ? value : undefined;
446
+ }
447
+ function numberField(record, key) {
448
+ const value = record?.[key];
449
+ return typeof value === "number" && Number.isFinite(value) ? value : undefined;
450
+ }
451
+ function compareToolName(left, right) {
452
+ return compareText(left.name, right.name);
453
+ }
454
+ export function compareText(left, right) {
455
+ return left < right ? -1 : left > right ? 1 : 0;
456
+ }
457
+ function strictlySortedUnique(values) {
458
+ return values.every((value, index) => index === 0 || compareText(values[index - 1], value) < 0);
459
+ }
460
+ //# sourceMappingURL=catalog-protocol.js.map