unity-open-mcp 0.6.1 → 0.8.2

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 (899) hide show
  1. package/README.md +15 -67
  2. package/dist/batch-spawn.d.ts +12 -0
  3. package/dist/batch-spawn.js +127 -20
  4. package/dist/batch-spawn.js.map +1 -1
  5. package/dist/bridge-tools-cache.d.ts +46 -0
  6. package/dist/bridge-tools-cache.js +83 -0
  7. package/dist/bridge-tools-cache.js.map +1 -0
  8. package/dist/capabilities/build-capabilities.d.ts +39 -5
  9. package/dist/capabilities/build-capabilities.js +190 -452
  10. package/dist/capabilities/build-capabilities.js.map +1 -1
  11. package/dist/capabilities/intent-groups.d.ts +99 -0
  12. package/dist/capabilities/intent-groups.js +518 -0
  13. package/dist/capabilities/intent-groups.js.map +1 -0
  14. package/dist/capabilities/lifecycle.js +1 -1
  15. package/dist/capabilities/lifecycle.js.map +1 -1
  16. package/dist/capabilities/list-rules.js +12 -20
  17. package/dist/capabilities/list-rules.js.map +1 -1
  18. package/dist/capabilities/rule-catalog.d.ts +22 -1
  19. package/dist/capabilities/rule-catalog.js +53 -20
  20. package/dist/capabilities/rule-catalog.js.map +1 -1
  21. package/dist/capabilities/tool-groups.d.ts +14 -13
  22. package/dist/capabilities/tool-groups.js +47 -22
  23. package/dist/capabilities/tool-groups.js.map +1 -1
  24. package/dist/cli/cli.js +65 -8
  25. package/dist/cli/cli.js.map +1 -1
  26. package/dist/cli/commands.d.ts +20 -0
  27. package/dist/cli/commands.js +142 -73
  28. package/dist/cli/commands.js.map +1 -1
  29. package/dist/cli/help-text.d.ts +2 -0
  30. package/dist/cli/help-text.js +77 -0
  31. package/dist/cli/help-text.js.map +1 -0
  32. package/dist/cli/ping-poller.d.ts +7 -5
  33. package/dist/cli/ping-poller.js +16 -15
  34. package/dist/cli/ping-poller.js.map +1 -1
  35. package/dist/compressible-router.d.ts +9 -2
  36. package/dist/compressible-router.js +70 -7
  37. package/dist/compressible-router.js.map +1 -1
  38. package/dist/compression/compact.d.ts +1 -0
  39. package/dist/compression/compact.js +82 -14
  40. package/dist/compression/compact.js.map +1 -1
  41. package/dist/dialog-dismiss.d.ts +10 -0
  42. package/dist/dialog-dismiss.js +110 -10
  43. package/dist/dialog-dismiss.js.map +1 -1
  44. package/dist/editor-process-control.d.ts +68 -0
  45. package/dist/editor-process-control.js +249 -0
  46. package/dist/editor-process-control.js.map +1 -0
  47. package/dist/event-stream.d.ts +2 -1
  48. package/dist/event-stream.js +43 -8
  49. package/dist/event-stream.js.map +1 -1
  50. package/dist/index.d.ts +1 -2
  51. package/dist/index.js +18 -142
  52. package/dist/index.js.map +1 -1
  53. package/dist/live-client.d.ts +52 -10
  54. package/dist/live-client.js +399 -42
  55. package/dist/live-client.js.map +1 -1
  56. package/dist/offline/api.js +336 -91
  57. package/dist/offline/api.js.map +1 -1
  58. package/dist/offline/hierarchy.js +100 -3
  59. package/dist/offline/hierarchy.js.map +1 -1
  60. package/dist/offline/index-builders.d.ts +120 -2
  61. package/dist/offline/index-builders.js +374 -35
  62. package/dist/offline/index-builders.js.map +1 -1
  63. package/dist/offline/overrides.js +5 -1
  64. package/dist/offline/overrides.js.map +1 -1
  65. package/dist/offline/parse.js +21 -9
  66. package/dist/offline/parse.js.map +1 -1
  67. package/dist/offline/paths.d.ts +32 -0
  68. package/dist/offline/paths.js +71 -2
  69. package/dist/offline/paths.js.map +1 -1
  70. package/dist/offline/primitives.d.ts +15 -0
  71. package/dist/offline/primitives.js +130 -6
  72. package/dist/offline/primitives.js.map +1 -1
  73. package/dist/offline/types.d.ts +29 -0
  74. package/dist/offline/types.js.map +1 -1
  75. package/dist/ping-cache.d.ts +35 -0
  76. package/dist/ping-cache.js +70 -0
  77. package/dist/ping-cache.js.map +1 -1
  78. package/dist/process-diagnostics.d.ts +146 -0
  79. package/dist/process-diagnostics.js +333 -0
  80. package/dist/process-diagnostics.js.map +1 -0
  81. package/dist/schema-defaults.d.ts +11 -0
  82. package/dist/schema-defaults.js +32 -1
  83. package/dist/schema-defaults.js.map +1 -1
  84. package/dist/server-instructions.js +7 -2
  85. package/dist/server-instructions.js.map +1 -1
  86. package/dist/server.d.ts +17 -0
  87. package/dist/server.js +195 -0
  88. package/dist/server.js.map +1 -0
  89. package/dist/skill/client-paths.d.ts +23 -0
  90. package/dist/skill/client-paths.js +46 -1
  91. package/dist/skill/client-paths.js.map +1 -1
  92. package/dist/tool-router.d.ts +55 -0
  93. package/dist/tool-router.js +782 -188
  94. package/dist/tool-router.js.map +1 -1
  95. package/dist/tool-session-state.d.ts +82 -10
  96. package/dist/tool-session-state.js +134 -22
  97. package/dist/tool-session-state.js.map +1 -1
  98. package/dist/tools/agent-capabilities.d.ts +40 -2
  99. package/dist/tools/agent-capabilities.js +16 -21
  100. package/dist/tools/agent-capabilities.js.map +1 -1
  101. package/dist/tools/animation-create.d.ts +40 -2
  102. package/dist/tools/animation-create.js +17 -26
  103. package/dist/tools/animation-create.js.map +1 -1
  104. package/dist/tools/animation-get-data.d.ts +40 -2
  105. package/dist/tools/animation-get-data.js +13 -18
  106. package/dist/tools/animation-get-data.js.map +1 -1
  107. package/dist/tools/animation-modify.d.ts +40 -2
  108. package/dist/tools/animation-modify.js +31 -40
  109. package/dist/tools/animation-modify.js.map +1 -1
  110. package/dist/tools/animator-create.d.ts +40 -2
  111. package/dist/tools/animator-create.js +17 -26
  112. package/dist/tools/animator-create.js.map +1 -1
  113. package/dist/tools/animator-get-data.d.ts +40 -2
  114. package/dist/tools/animator-get-data.js +13 -18
  115. package/dist/tools/animator-get-data.js.map +1 -1
  116. package/dist/tools/animator-modify.d.ts +40 -2
  117. package/dist/tools/animator-modify.js +37 -46
  118. package/dist/tools/animator-modify.js.map +1 -1
  119. package/dist/tools/apply-fix.d.ts +40 -2
  120. package/dist/tools/apply-fix.js +41 -52
  121. package/dist/tools/apply-fix.js.map +1 -1
  122. package/dist/tools/asmdef-create.d.ts +40 -2
  123. package/dist/tools/asmdef-create.js +82 -100
  124. package/dist/tools/asmdef-create.js.map +1 -1
  125. package/dist/tools/asmdef-get.d.ts +40 -2
  126. package/dist/tools/asmdef-get.js +14 -19
  127. package/dist/tools/asmdef-get.js.map +1 -1
  128. package/dist/tools/asmdef-list.d.ts +40 -2
  129. package/dist/tools/asmdef-list.js +25 -30
  130. package/dist/tools/asmdef-list.js.map +1 -1
  131. package/dist/tools/asmdef-modify.d.ts +40 -2
  132. package/dist/tools/asmdef-modify.js +76 -94
  133. package/dist/tools/asmdef-modify.js.map +1 -1
  134. package/dist/tools/assets-copy.d.ts +40 -2
  135. package/dist/tools/assets-copy.js +26 -38
  136. package/dist/tools/assets-copy.js.map +1 -1
  137. package/dist/tools/assets-create-folder.d.ts +40 -2
  138. package/dist/tools/assets-create-folder.js +28 -41
  139. package/dist/tools/assets-create-folder.js.map +1 -1
  140. package/dist/tools/assets-delete.d.ts +40 -2
  141. package/dist/tools/assets-delete.js +16 -28
  142. package/dist/tools/assets-delete.js.map +1 -1
  143. package/dist/tools/assets-move.d.ts +40 -2
  144. package/dist/tools/assets-move.js +27 -39
  145. package/dist/tools/assets-move.js.map +1 -1
  146. package/dist/tools/assets-refresh.d.ts +40 -2
  147. package/dist/tools/assets-refresh.js +16 -28
  148. package/dist/tools/assets-refresh.js.map +1 -1
  149. package/dist/tools/audio-listener-get.d.ts +40 -2
  150. package/dist/tools/audio-listener-get.js +8 -13
  151. package/dist/tools/audio-listener-get.js.map +1 -1
  152. package/dist/tools/audio-mixer-get-parameter.d.ts +40 -2
  153. package/dist/tools/audio-mixer-get-parameter.js +15 -20
  154. package/dist/tools/audio-mixer-get-parameter.js.map +1 -1
  155. package/dist/tools/audio-mixer-set-parameter.d.ts +40 -2
  156. package/dist/tools/audio-mixer-set-parameter.js +29 -38
  157. package/dist/tools/audio-mixer-set-parameter.js.map +1 -1
  158. package/dist/tools/audio-source-add.d.ts +40 -2
  159. package/dist/tools/audio-source-add.js +58 -70
  160. package/dist/tools/audio-source-add.js.map +1 -1
  161. package/dist/tools/audio-source-modify.d.ts +40 -2
  162. package/dist/tools/audio-source-modify.js +36 -46
  163. package/dist/tools/audio-source-modify.js.map +1 -1
  164. package/dist/tools/baseline-create.d.ts +40 -2
  165. package/dist/tools/baseline-create.js +12 -17
  166. package/dist/tools/baseline-create.js.map +1 -1
  167. package/dist/tools/batch-execute.d.ts +40 -2
  168. package/dist/tools/batch-execute.js +64 -68
  169. package/dist/tools/batch-execute.js.map +1 -1
  170. package/dist/tools/bridge-status.d.ts +40 -2
  171. package/dist/tools/bridge-status.js +34 -40
  172. package/dist/tools/bridge-status.js.map +1 -1
  173. package/dist/tools/build-get-active-target.d.ts +40 -2
  174. package/dist/tools/build-get-active-target.js +7 -12
  175. package/dist/tools/build-get-active-target.js.map +1 -1
  176. package/dist/tools/build-get-defines.d.ts +40 -2
  177. package/dist/tools/build-get-defines.js +7 -12
  178. package/dist/tools/build-get-defines.js.map +1 -1
  179. package/dist/tools/build-get-scenes.d.ts +40 -2
  180. package/dist/tools/build-get-scenes.js +7 -12
  181. package/dist/tools/build-get-scenes.js.map +1 -1
  182. package/dist/tools/build-get-targets.d.ts +40 -2
  183. package/dist/tools/build-get-targets.js +8 -13
  184. package/dist/tools/build-get-targets.js.map +1 -1
  185. package/dist/tools/build-set-defines.d.ts +40 -2
  186. package/dist/tools/build-set-defines.js +22 -40
  187. package/dist/tools/build-set-defines.js.map +1 -1
  188. package/dist/tools/build-set-scenes.d.ts +40 -2
  189. package/dist/tools/build-set-scenes.js +36 -49
  190. package/dist/tools/build-set-scenes.js.map +1 -1
  191. package/dist/tools/build-set-target.d.ts +40 -2
  192. package/dist/tools/build-set-target.js +17 -38
  193. package/dist/tools/build-set-target.js.map +1 -1
  194. package/dist/tools/build-start.d.ts +40 -2
  195. package/dist/tools/build-start.js +34 -50
  196. package/dist/tools/build-start.js.map +1 -1
  197. package/dist/tools/capture-inline.d.ts +40 -2
  198. package/dist/tools/capture-inline.js +43 -48
  199. package/dist/tools/capture-inline.js.map +1 -1
  200. package/dist/tools/checkpoint-create.d.ts +40 -2
  201. package/dist/tools/checkpoint-create.js +13 -13
  202. package/dist/tools/checkpoint-create.js.map +1 -1
  203. package/dist/tools/cinemachine-brain-ensure.d.ts +40 -2
  204. package/dist/tools/cinemachine-brain-ensure.js +14 -23
  205. package/dist/tools/cinemachine-brain-ensure.js.map +1 -1
  206. package/dist/tools/cinemachine-camera-list.d.ts +40 -2
  207. package/dist/tools/cinemachine-camera-list.js +6 -11
  208. package/dist/tools/cinemachine-camera-list.js.map +1 -1
  209. package/dist/tools/cinemachine-create-camera.d.ts +40 -2
  210. package/dist/tools/cinemachine-create-camera.js +38 -47
  211. package/dist/tools/cinemachine-create-camera.js.map +1 -1
  212. package/dist/tools/cinemachine-set-body.d.ts +40 -2
  213. package/dist/tools/cinemachine-set-body.js +20 -29
  214. package/dist/tools/cinemachine-set-body.js.map +1 -1
  215. package/dist/tools/cinemachine-set-lens.d.ts +40 -2
  216. package/dist/tools/cinemachine-set-lens.js +28 -37
  217. package/dist/tools/cinemachine-set-lens.js.map +1 -1
  218. package/dist/tools/cinemachine-set-noise.d.ts +40 -2
  219. package/dist/tools/cinemachine-set-noise.js +18 -27
  220. package/dist/tools/cinemachine-set-noise.js.map +1 -1
  221. package/dist/tools/cinemachine-set-targets.d.ts +40 -2
  222. package/dist/tools/cinemachine-set-targets.js +17 -26
  223. package/dist/tools/cinemachine-set-targets.js.map +1 -1
  224. package/dist/tools/compile-check.d.ts +40 -2
  225. package/dist/tools/compile-check.js +18 -23
  226. package/dist/tools/compile-check.js.map +1 -1
  227. package/dist/tools/component-add.d.ts +40 -2
  228. package/dist/tools/component-add.js +30 -42
  229. package/dist/tools/component-add.js.map +1 -1
  230. package/dist/tools/component-destroy.d.ts +40 -2
  231. package/dist/tools/component-destroy.js +29 -41
  232. package/dist/tools/component-destroy.js.map +1 -1
  233. package/dist/tools/component-get.d.ts +40 -2
  234. package/dist/tools/component-get.js +77 -82
  235. package/dist/tools/component-get.js.map +1 -1
  236. package/dist/tools/component-list-all.d.ts +40 -2
  237. package/dist/tools/component-list-all.js +29 -34
  238. package/dist/tools/component-list-all.js.map +1 -1
  239. package/dist/tools/component-modify.d.ts +40 -2
  240. package/dist/tools/component-modify.js +60 -72
  241. package/dist/tools/component-modify.js.map +1 -1
  242. package/dist/tools/console-clear.d.ts +40 -2
  243. package/dist/tools/console-clear.js +9 -14
  244. package/dist/tools/console-clear.js.map +1 -1
  245. package/dist/tools/console-log.d.ts +40 -2
  246. package/dist/tools/console-log.js +34 -39
  247. package/dist/tools/console-log.js.map +1 -1
  248. package/dist/tools/constraint-add.d.ts +40 -2
  249. package/dist/tools/constraint-add.js +49 -61
  250. package/dist/tools/constraint-add.js.map +1 -1
  251. package/dist/tools/delta.d.ts +40 -2
  252. package/dist/tools/delta.js +10 -14
  253. package/dist/tools/delta.js.map +1 -1
  254. package/dist/tools/dependencies.d.ts +40 -2
  255. package/dist/tools/dependencies.js +55 -57
  256. package/dist/tools/dependencies.js.map +1 -1
  257. package/dist/tools/editor-add-layer.d.ts +40 -2
  258. package/dist/tools/editor-add-layer.js +30 -43
  259. package/dist/tools/editor-add-layer.js.map +1 -1
  260. package/dist/tools/editor-add-tag.d.ts +40 -2
  261. package/dist/tools/editor-add-tag.js +20 -33
  262. package/dist/tools/editor-add-tag.js.map +1 -1
  263. package/dist/tools/editor-clear-history.d.ts +40 -2
  264. package/dist/tools/editor-clear-history.js +9 -21
  265. package/dist/tools/editor-clear-history.js.map +1 -1
  266. package/dist/tools/editor-get-layers.d.ts +40 -2
  267. package/dist/tools/editor-get-layers.js +12 -17
  268. package/dist/tools/editor-get-layers.js.map +1 -1
  269. package/dist/tools/editor-get-tags.d.ts +40 -2
  270. package/dist/tools/editor-get-tags.js +10 -15
  271. package/dist/tools/editor-get-tags.js.map +1 -1
  272. package/dist/tools/editor-redo.d.ts +40 -2
  273. package/dist/tools/editor-redo.js +15 -20
  274. package/dist/tools/editor-redo.js.map +1 -1
  275. package/dist/tools/editor-set-state.d.ts +40 -2
  276. package/dist/tools/editor-set-state.js +33 -42
  277. package/dist/tools/editor-set-state.js.map +1 -1
  278. package/dist/tools/editor-status.d.ts +40 -2
  279. package/dist/tools/editor-status.js +9 -14
  280. package/dist/tools/editor-status.js.map +1 -1
  281. package/dist/tools/editor-undo-history.d.ts +40 -2
  282. package/dist/tools/editor-undo-history.js +11 -16
  283. package/dist/tools/editor-undo-history.js.map +1 -1
  284. package/dist/tools/editor-undo.d.ts +40 -2
  285. package/dist/tools/editor-undo.js +17 -22
  286. package/dist/tools/editor-undo.js.map +1 -1
  287. package/dist/tools/editorprefs-delete.d.ts +40 -2
  288. package/dist/tools/editorprefs-delete.js +12 -17
  289. package/dist/tools/editorprefs-delete.js.map +1 -1
  290. package/dist/tools/editorprefs-get.d.ts +40 -2
  291. package/dist/tools/editorprefs-get.js +17 -22
  292. package/dist/tools/editorprefs-get.js.map +1 -1
  293. package/dist/tools/editorprefs-set.d.ts +40 -2
  294. package/dist/tools/editorprefs-set.js +22 -27
  295. package/dist/tools/editorprefs-set.js.map +1 -1
  296. package/dist/tools/execute-csharp.d.ts +40 -2
  297. package/dist/tools/execute-csharp.js +44 -71
  298. package/dist/tools/execute-csharp.js.map +1 -1
  299. package/dist/tools/execute-menu.d.ts +40 -2
  300. package/dist/tools/execute-menu.js +12 -37
  301. package/dist/tools/execute-menu.js.map +1 -1
  302. package/dist/tools/find-members.d.ts +40 -2
  303. package/dist/tools/find-members.js +41 -46
  304. package/dist/tools/find-members.js.map +1 -1
  305. package/dist/tools/find-references.d.ts +40 -2
  306. package/dist/tools/find-references.js +48 -46
  307. package/dist/tools/find-references.js.map +1 -1
  308. package/dist/tools/frame-debugger.d.ts +40 -2
  309. package/dist/tools/frame-debugger.js +27 -32
  310. package/dist/tools/frame-debugger.js.map +1 -1
  311. package/dist/tools/gameobject-create.d.ts +40 -2
  312. package/dist/tools/gameobject-create.js +44 -56
  313. package/dist/tools/gameobject-create.js.map +1 -1
  314. package/dist/tools/gameobject-destroy.d.ts +40 -2
  315. package/dist/tools/gameobject-destroy.js +21 -33
  316. package/dist/tools/gameobject-destroy.js.map +1 -1
  317. package/dist/tools/gameobject-duplicate.d.ts +40 -2
  318. package/dist/tools/gameobject-duplicate.js +23 -35
  319. package/dist/tools/gameobject-duplicate.js.map +1 -1
  320. package/dist/tools/gameobject-find.d.ts +40 -2
  321. package/dist/tools/gameobject-find.js +49 -54
  322. package/dist/tools/gameobject-find.js.map +1 -1
  323. package/dist/tools/gameobject-modify.d.ts +40 -2
  324. package/dist/tools/gameobject-modify.js +101 -113
  325. package/dist/tools/gameobject-modify.js.map +1 -1
  326. package/dist/tools/gameobject-set-parent.d.ts +40 -2
  327. package/dist/tools/gameobject-set-parent.js +42 -50
  328. package/dist/tools/gameobject-set-parent.js.map +1 -1
  329. package/dist/tools/gate-budget-estimate.d.ts +40 -2
  330. package/dist/tools/gate-budget-estimate.js +35 -40
  331. package/dist/tools/gate-budget-estimate.js.map +1 -1
  332. package/dist/tools/generate-skill.d.ts +40 -2
  333. package/dist/tools/generate-skill.js +30 -35
  334. package/dist/tools/generate-skill.js.map +1 -1
  335. package/dist/tools/hub-available-releases.d.ts +40 -2
  336. package/dist/tools/hub-available-releases.js +12 -17
  337. package/dist/tools/hub-available-releases.js.map +1 -1
  338. package/dist/tools/hub-get-install-path.d.ts +40 -2
  339. package/dist/tools/hub-get-install-path.js +11 -16
  340. package/dist/tools/hub-get-install-path.js.map +1 -1
  341. package/dist/tools/hub-install-editor.d.ts +40 -2
  342. package/dist/tools/hub-install-editor.js +29 -34
  343. package/dist/tools/hub-install-editor.js.map +1 -1
  344. package/dist/tools/hub-install-modules.d.ts +40 -2
  345. package/dist/tools/hub-install-modules.js +31 -36
  346. package/dist/tools/hub-install-modules.js.map +1 -1
  347. package/dist/tools/hub-list-editors.d.ts +40 -2
  348. package/dist/tools/hub-list-editors.js +14 -19
  349. package/dist/tools/hub-list-editors.js.map +1 -1
  350. package/dist/tools/hub-set-install-path.d.ts +40 -2
  351. package/dist/tools/hub-set-install-path.js +18 -23
  352. package/dist/tools/hub-set-install-path.js.map +1 -1
  353. package/dist/tools/impact-preview.d.ts +40 -2
  354. package/dist/tools/impact-preview.js +31 -36
  355. package/dist/tools/impact-preview.js.map +1 -1
  356. package/dist/tools/index.d.ts +1 -0
  357. package/dist/tools/index.js +17 -0
  358. package/dist/tools/index.js.map +1 -1
  359. package/dist/tools/inputsystem-action-add.d.ts +40 -2
  360. package/dist/tools/inputsystem-action-add.js +48 -57
  361. package/dist/tools/inputsystem-action-add.js.map +1 -1
  362. package/dist/tools/inputsystem-actionmap-add.d.ts +40 -2
  363. package/dist/tools/inputsystem-actionmap-add.js +17 -26
  364. package/dist/tools/inputsystem-actionmap-add.js.map +1 -1
  365. package/dist/tools/inputsystem-asset-create.d.ts +40 -2
  366. package/dist/tools/inputsystem-asset-create.js +19 -28
  367. package/dist/tools/inputsystem-asset-create.js.map +1 -1
  368. package/dist/tools/inputsystem-binding-add.d.ts +40 -2
  369. package/dist/tools/inputsystem-binding-add.js +34 -43
  370. package/dist/tools/inputsystem-binding-add.js.map +1 -1
  371. package/dist/tools/inputsystem-binding-composite-add.d.ts +40 -2
  372. package/dist/tools/inputsystem-binding-composite-add.js +37 -46
  373. package/dist/tools/inputsystem-binding-composite-add.js.map +1 -1
  374. package/dist/tools/inputsystem-controlscheme-add.d.ts +40 -2
  375. package/dist/tools/inputsystem-controlscheme-add.js +29 -38
  376. package/dist/tools/inputsystem-controlscheme-add.js.map +1 -1
  377. package/dist/tools/inputsystem-get.d.ts +40 -2
  378. package/dist/tools/inputsystem-get.js +12 -17
  379. package/dist/tools/inputsystem-get.js.map +1 -1
  380. package/dist/tools/invoke-method.d.ts +40 -2
  381. package/dist/tools/invoke-method.js +73 -91
  382. package/dist/tools/invoke-method.js.map +1 -1
  383. package/dist/tools/light-add.d.ts +40 -2
  384. package/dist/tools/light-add.js +38 -50
  385. package/dist/tools/light-add.js.map +1 -1
  386. package/dist/tools/light-modify.d.ts +40 -2
  387. package/dist/tools/light-modify.js +22 -31
  388. package/dist/tools/light-modify.js.map +1 -1
  389. package/dist/tools/light-set.d.ts +40 -2
  390. package/dist/tools/light-set.js +40 -49
  391. package/dist/tools/light-set.js.map +1 -1
  392. package/dist/tools/list-assets-of-type.d.ts +40 -2
  393. package/dist/tools/list-assets-of-type.js +37 -42
  394. package/dist/tools/list-assets-of-type.js.map +1 -1
  395. package/dist/tools/list-assets.d.ts +40 -2
  396. package/dist/tools/list-assets.js +19 -24
  397. package/dist/tools/list-assets.js.map +1 -1
  398. package/dist/tools/list-rules.d.ts +40 -2
  399. package/dist/tools/list-rules.js +19 -24
  400. package/dist/tools/list-rules.js.map +1 -1
  401. package/dist/tools/lod-add-level.d.ts +40 -2
  402. package/dist/tools/lod-add-level.js +31 -43
  403. package/dist/tools/lod-add-level.js.map +1 -1
  404. package/dist/tools/lod-group-configure.d.ts +40 -2
  405. package/dist/tools/lod-group-configure.js +30 -42
  406. package/dist/tools/lod-group-configure.js.map +1 -1
  407. package/dist/tools/manage-tools.d.ts +40 -2
  408. package/dist/tools/manage-tools.js +72 -38
  409. package/dist/tools/manage-tools.js.map +1 -1
  410. package/dist/tools/material-create.d.ts +40 -2
  411. package/dist/tools/material-create.js +30 -31
  412. package/dist/tools/material-create.js.map +1 -1
  413. package/dist/tools/material-get-keywords.d.ts +40 -2
  414. package/dist/tools/material-get-keywords.js +14 -19
  415. package/dist/tools/material-get-keywords.js.map +1 -1
  416. package/dist/tools/material-get-properties.d.ts +40 -2
  417. package/dist/tools/material-get-properties.js +21 -26
  418. package/dist/tools/material-get-properties.js.map +1 -1
  419. package/dist/tools/material-set-keyword.d.ts +40 -2
  420. package/dist/tools/material-set-keyword.js +26 -38
  421. package/dist/tools/material-set-keyword.js.map +1 -1
  422. package/dist/tools/material-set-property.d.ts +40 -2
  423. package/dist/tools/material-set-property.js +35 -47
  424. package/dist/tools/material-set-property.js.map +1 -1
  425. package/dist/tools/material-set-shader.d.ts +40 -2
  426. package/dist/tools/material-set-shader.js +23 -35
  427. package/dist/tools/material-set-shader.js.map +1 -1
  428. package/dist/tools/memory-snapshot-capture.d.ts +40 -2
  429. package/dist/tools/memory-snapshot-capture.js +37 -42
  430. package/dist/tools/memory-snapshot-capture.js.map +1 -1
  431. package/dist/tools/mutation-explain.d.ts +40 -2
  432. package/dist/tools/mutation-explain.js +19 -24
  433. package/dist/tools/mutation-explain.js.map +1 -1
  434. package/dist/tools/navigation-agent-add.d.ts +40 -2
  435. package/dist/tools/navigation-agent-add.js +24 -33
  436. package/dist/tools/navigation-agent-add.js.map +1 -1
  437. package/dist/tools/navigation-agent-set-destination.d.ts +40 -2
  438. package/dist/tools/navigation-agent-set-destination.js +18 -27
  439. package/dist/tools/navigation-agent-set-destination.js.map +1 -1
  440. package/dist/tools/navigation-get.d.ts +40 -2
  441. package/dist/tools/navigation-get.js +11 -16
  442. package/dist/tools/navigation-get.js.map +1 -1
  443. package/dist/tools/navigation-link-add.d.ts +40 -2
  444. package/dist/tools/navigation-link-add.js +43 -52
  445. package/dist/tools/navigation-link-add.js.map +1 -1
  446. package/dist/tools/navigation-list.d.ts +40 -2
  447. package/dist/tools/navigation-list.js +8 -13
  448. package/dist/tools/navigation-list.js.map +1 -1
  449. package/dist/tools/navigation-modifier-add.d.ts +40 -2
  450. package/dist/tools/navigation-modifier-add.js +28 -37
  451. package/dist/tools/navigation-modifier-add.js.map +1 -1
  452. package/dist/tools/navigation-modifier-volume-add.d.ts +40 -2
  453. package/dist/tools/navigation-modifier-volume-add.js +27 -36
  454. package/dist/tools/navigation-modifier-volume-add.js.map +1 -1
  455. package/dist/tools/navigation-modify.d.ts +40 -2
  456. package/dist/tools/navigation-modify.js +33 -42
  457. package/dist/tools/navigation-modify.js.map +1 -1
  458. package/dist/tools/navigation-set-bake-settings.d.ts +40 -2
  459. package/dist/tools/navigation-set-bake-settings.js +27 -36
  460. package/dist/tools/navigation-set-bake-settings.js.map +1 -1
  461. package/dist/tools/navigation-surface-add.d.ts +40 -2
  462. package/dist/tools/navigation-surface-add.js +27 -39
  463. package/dist/tools/navigation-surface-add.js.map +1 -1
  464. package/dist/tools/navigation-surface-bake.d.ts +40 -2
  465. package/dist/tools/navigation-surface-bake.js +15 -24
  466. package/dist/tools/navigation-surface-bake.js.map +1 -1
  467. package/dist/tools/object-get-data.d.ts +40 -2
  468. package/dist/tools/object-get-data.js +44 -49
  469. package/dist/tools/object-get-data.js.map +1 -1
  470. package/dist/tools/object-modify.d.ts +40 -2
  471. package/dist/tools/object-modify.js +48 -60
  472. package/dist/tools/object-modify.js.map +1 -1
  473. package/dist/tools/package-add.d.ts +40 -2
  474. package/dist/tools/package-add.js +20 -35
  475. package/dist/tools/package-add.js.map +1 -1
  476. package/dist/tools/package-check.d.ts +40 -2
  477. package/dist/tools/package-check.js +15 -20
  478. package/dist/tools/package-check.js.map +1 -1
  479. package/dist/tools/package-get-dependencies.d.ts +40 -2
  480. package/dist/tools/package-get-dependencies.js +8 -13
  481. package/dist/tools/package-get-dependencies.js.map +1 -1
  482. package/dist/tools/package-get-info.d.ts +40 -2
  483. package/dist/tools/package-get-info.js +21 -26
  484. package/dist/tools/package-get-info.js.map +1 -1
  485. package/dist/tools/package-list.d.ts +40 -2
  486. package/dist/tools/package-list.js +45 -50
  487. package/dist/tools/package-list.js.map +1 -1
  488. package/dist/tools/package-remove.d.ts +40 -2
  489. package/dist/tools/package-remove.js +18 -33
  490. package/dist/tools/package-remove.js.map +1 -1
  491. package/dist/tools/package-search.d.ts +40 -2
  492. package/dist/tools/package-search.js +29 -34
  493. package/dist/tools/package-search.js.map +1 -1
  494. package/dist/tools/particle-system-get.d.ts +40 -2
  495. package/dist/tools/particle-system-get.js +24 -29
  496. package/dist/tools/particle-system-get.js.map +1 -1
  497. package/dist/tools/particle-system-modify.d.ts +40 -2
  498. package/dist/tools/particle-system-modify.js +50 -59
  499. package/dist/tools/particle-system-modify.js.map +1 -1
  500. package/dist/tools/ping.d.ts +40 -2
  501. package/dist/tools/ping.js +4 -9
  502. package/dist/tools/ping.js.map +1 -1
  503. package/dist/tools/playerprefs-delete.d.ts +40 -2
  504. package/dist/tools/playerprefs-delete.js +13 -18
  505. package/dist/tools/playerprefs-delete.js.map +1 -1
  506. package/dist/tools/playerprefs-get.d.ts +40 -2
  507. package/dist/tools/playerprefs-get.js +17 -22
  508. package/dist/tools/playerprefs-get.js.map +1 -1
  509. package/dist/tools/playerprefs-set.d.ts +40 -2
  510. package/dist/tools/playerprefs-set.js +25 -30
  511. package/dist/tools/playerprefs-set.js.map +1 -1
  512. package/dist/tools/prefab-apply.d.ts +40 -2
  513. package/dist/tools/prefab-apply.js +22 -34
  514. package/dist/tools/prefab-apply.js.map +1 -1
  515. package/dist/tools/prefab-close.d.ts +40 -2
  516. package/dist/tools/prefab-close.js +13 -25
  517. package/dist/tools/prefab-close.js.map +1 -1
  518. package/dist/tools/prefab-create.d.ts +40 -2
  519. package/dist/tools/prefab-create.js +35 -47
  520. package/dist/tools/prefab-create.js.map +1 -1
  521. package/dist/tools/prefab-get-overrides.d.ts +40 -2
  522. package/dist/tools/prefab-get-overrides.js +18 -23
  523. package/dist/tools/prefab-get-overrides.js.map +1 -1
  524. package/dist/tools/prefab-instantiate.d.ts +40 -2
  525. package/dist/tools/prefab-instantiate.js +35 -47
  526. package/dist/tools/prefab-instantiate.js.map +1 -1
  527. package/dist/tools/prefab-open.d.ts +40 -2
  528. package/dist/tools/prefab-open.js +12 -24
  529. package/dist/tools/prefab-open.js.map +1 -1
  530. package/dist/tools/prefab-revert.d.ts +40 -2
  531. package/dist/tools/prefab-revert.js +21 -33
  532. package/dist/tools/prefab-revert.js.map +1 -1
  533. package/dist/tools/prefab-save.d.ts +40 -2
  534. package/dist/tools/prefab-save.js +8 -20
  535. package/dist/tools/prefab-save.js.map +1 -1
  536. package/dist/tools/prefab-status.d.ts +40 -2
  537. package/dist/tools/prefab-status.js +18 -23
  538. package/dist/tools/prefab-status.js.map +1 -1
  539. package/dist/tools/prefab-unpack.d.ts +40 -2
  540. package/dist/tools/prefab-unpack.js +27 -39
  541. package/dist/tools/prefab-unpack.js.map +1 -1
  542. package/dist/tools/probuilder-create-shape.d.ts +40 -2
  543. package/dist/tools/probuilder-create-shape.js +24 -33
  544. package/dist/tools/probuilder-create-shape.js.map +1 -1
  545. package/dist/tools/probuilder-delete-faces.d.ts +40 -2
  546. package/dist/tools/probuilder-delete-faces.js +24 -33
  547. package/dist/tools/probuilder-delete-faces.js.map +1 -1
  548. package/dist/tools/probuilder-extrude.d.ts +40 -2
  549. package/dist/tools/probuilder-extrude.js +35 -44
  550. package/dist/tools/probuilder-extrude.js.map +1 -1
  551. package/dist/tools/probuilder-get-mesh-info.d.ts +40 -2
  552. package/dist/tools/probuilder-get-mesh-info.js +12 -17
  553. package/dist/tools/probuilder-get-mesh-info.js.map +1 -1
  554. package/dist/tools/probuilder-set-face-material.d.ts +40 -2
  555. package/dist/tools/probuilder-set-face-material.js +30 -39
  556. package/dist/tools/probuilder-set-face-material.js.map +1 -1
  557. package/dist/tools/profiler-capture-frame.d.ts +40 -2
  558. package/dist/tools/profiler-capture-frame.js +59 -63
  559. package/dist/tools/profiler-capture-frame.js.map +1 -1
  560. package/dist/tools/profiler-capture.d.ts +40 -2
  561. package/dist/tools/profiler-capture.js +76 -81
  562. package/dist/tools/profiler-capture.js.map +1 -1
  563. package/dist/tools/profiler-clear-data.d.ts +40 -2
  564. package/dist/tools/profiler-clear-data.js +9 -14
  565. package/dist/tools/profiler-clear-data.js.map +1 -1
  566. package/dist/tools/profiler-enable-module.d.ts +40 -2
  567. package/dist/tools/profiler-enable-module.js +18 -23
  568. package/dist/tools/profiler-enable-module.js.map +1 -1
  569. package/dist/tools/profiler-get-config.d.ts +40 -2
  570. package/dist/tools/profiler-get-config.js +10 -15
  571. package/dist/tools/profiler-get-config.js.map +1 -1
  572. package/dist/tools/profiler-get-script-stats.d.ts +40 -2
  573. package/dist/tools/profiler-get-script-stats.js +9 -14
  574. package/dist/tools/profiler-get-script-stats.js.map +1 -1
  575. package/dist/tools/profiler-get-status.d.ts +40 -2
  576. package/dist/tools/profiler-get-status.js +10 -15
  577. package/dist/tools/profiler-get-status.js.map +1 -1
  578. package/dist/tools/profiler-list-modules.d.ts +40 -2
  579. package/dist/tools/profiler-list-modules.js +9 -14
  580. package/dist/tools/profiler-list-modules.js.map +1 -1
  581. package/dist/tools/profiler-load-data.d.ts +40 -2
  582. package/dist/tools/profiler-load-data.js +23 -28
  583. package/dist/tools/profiler-load-data.js.map +1 -1
  584. package/dist/tools/profiler-memory.d.ts +40 -2
  585. package/dist/tools/profiler-memory.js +13 -18
  586. package/dist/tools/profiler-memory.js.map +1 -1
  587. package/dist/tools/profiler-rendering.d.ts +40 -2
  588. package/dist/tools/profiler-rendering.js +8 -13
  589. package/dist/tools/profiler-rendering.js.map +1 -1
  590. package/dist/tools/profiler-save-data.d.ts +40 -2
  591. package/dist/tools/profiler-save-data.js +16 -28
  592. package/dist/tools/profiler-save-data.js.map +1 -1
  593. package/dist/tools/profiler-set-config.d.ts +40 -2
  594. package/dist/tools/profiler-set-config.js +58 -63
  595. package/dist/tools/profiler-set-config.js.map +1 -1
  596. package/dist/tools/profiler-start.d.ts +40 -2
  597. package/dist/tools/profiler-start.js +16 -21
  598. package/dist/tools/profiler-start.js.map +1 -1
  599. package/dist/tools/profiler-stop.d.ts +40 -2
  600. package/dist/tools/profiler-stop.js +9 -14
  601. package/dist/tools/profiler-stop.js.map +1 -1
  602. package/dist/tools/pull-events.d.ts +40 -2
  603. package/dist/tools/pull-events.js +23 -28
  604. package/dist/tools/pull-events.js.map +1 -1
  605. package/dist/tools/read-asset.d.ts +40 -2
  606. package/dist/tools/read-asset.js +66 -71
  607. package/dist/tools/read-asset.js.map +1 -1
  608. package/dist/tools/read-compile-errors.d.ts +40 -2
  609. package/dist/tools/read-compile-errors.js +40 -45
  610. package/dist/tools/read-compile-errors.js.map +1 -1
  611. package/dist/tools/read-console.d.ts +40 -2
  612. package/dist/tools/read-console.js +49 -54
  613. package/dist/tools/read-console.js.map +1 -1
  614. package/dist/tools/reflection-probe-bake.d.ts +40 -2
  615. package/dist/tools/reflection-probe-bake.js +30 -40
  616. package/dist/tools/reflection-probe-bake.js.map +1 -1
  617. package/dist/tools/reflection-probe-get.d.ts +40 -2
  618. package/dist/tools/reflection-probe-get.js +10 -15
  619. package/dist/tools/reflection-probe-get.js.map +1 -1
  620. package/dist/tools/regression-check.d.ts +40 -2
  621. package/dist/tools/regression-check.js +28 -33
  622. package/dist/tools/regression-check.js.map +1 -1
  623. package/dist/tools/reimport-package.d.ts +40 -2
  624. package/dist/tools/reimport-package.js +22 -38
  625. package/dist/tools/reimport-package.js.map +1 -1
  626. package/dist/tools/reserialize.d.ts +40 -2
  627. package/dist/tools/reserialize.js +19 -28
  628. package/dist/tools/reserialize.js.map +1 -1
  629. package/dist/tools/resource-pressure.d.ts +40 -0
  630. package/dist/tools/resource-pressure.js +57 -0
  631. package/dist/tools/resource-pressure.js.map +1 -0
  632. package/dist/tools/restart-editor.d.ts +40 -0
  633. package/dist/tools/restart-editor.js +74 -0
  634. package/dist/tools/restart-editor.js.map +1 -0
  635. package/dist/tools/run-tests.d.ts +40 -2
  636. package/dist/tools/run-tests.js +41 -46
  637. package/dist/tools/run-tests.js.map +1 -1
  638. package/dist/tools/scan-all.d.ts +40 -2
  639. package/dist/tools/scan-all.js +17 -22
  640. package/dist/tools/scan-all.js.map +1 -1
  641. package/dist/tools/scan-paths.d.ts +40 -2
  642. package/dist/tools/scan-paths.js +51 -56
  643. package/dist/tools/scan-paths.js.map +1 -1
  644. package/dist/tools/scene-create.d.ts +40 -2
  645. package/dist/tools/scene-create.js +41 -42
  646. package/dist/tools/scene-create.js.map +1 -1
  647. package/dist/tools/scene-focus.d.ts +40 -2
  648. package/dist/tools/scene-focus.js +38 -50
  649. package/dist/tools/scene-focus.js.map +1 -1
  650. package/dist/tools/scene-get-data.d.ts +40 -2
  651. package/dist/tools/scene-get-data.js +66 -71
  652. package/dist/tools/scene-get-data.js.map +1 -1
  653. package/dist/tools/scene-get-dirty-summary.d.ts +40 -2
  654. package/dist/tools/scene-get-dirty-summary.js +9 -14
  655. package/dist/tools/scene-get-dirty-summary.js.map +1 -1
  656. package/dist/tools/scene-list-opened.d.ts +40 -2
  657. package/dist/tools/scene-list-opened.js +8 -13
  658. package/dist/tools/scene-list-opened.js.map +1 -1
  659. package/dist/tools/scene-open.d.ts +40 -2
  660. package/dist/tools/scene-open.js +24 -43
  661. package/dist/tools/scene-open.js.map +1 -1
  662. package/dist/tools/scene-save.d.ts +40 -2
  663. package/dist/tools/scene-save.js +25 -38
  664. package/dist/tools/scene-save.js.map +1 -1
  665. package/dist/tools/scene-set-active.d.ts +40 -2
  666. package/dist/tools/scene-set-active.js +27 -39
  667. package/dist/tools/scene-set-active.js.map +1 -1
  668. package/dist/tools/scene-unload.d.ts +40 -2
  669. package/dist/tools/scene-unload.js +25 -38
  670. package/dist/tools/scene-unload.js.map +1 -1
  671. package/dist/tools/sceneview-get-camera.d.ts +40 -2
  672. package/dist/tools/sceneview-get-camera.js +7 -12
  673. package/dist/tools/sceneview-get-camera.js.map +1 -1
  674. package/dist/tools/sceneview-set-camera.d.ts +40 -2
  675. package/dist/tools/sceneview-set-camera.js +38 -50
  676. package/dist/tools/sceneview-set-camera.js.map +1 -1
  677. package/dist/tools/schema-fragments.d.ts +86 -0
  678. package/dist/tools/schema-fragments.js +119 -0
  679. package/dist/tools/schema-fragments.js.map +1 -0
  680. package/dist/tools/screenshot-camera.d.ts +40 -2
  681. package/dist/tools/screenshot-camera.js +47 -52
  682. package/dist/tools/screenshot-camera.js.map +1 -1
  683. package/dist/tools/screenshot-window.d.ts +40 -2
  684. package/dist/tools/screenshot-window.js +40 -45
  685. package/dist/tools/screenshot-window.js.map +1 -1
  686. package/dist/tools/screenshot.d.ts +40 -2
  687. package/dist/tools/screenshot.js +39 -44
  688. package/dist/tools/screenshot.js.map +1 -1
  689. package/dist/tools/script-delete.d.ts +40 -2
  690. package/dist/tools/script-delete.js +18 -30
  691. package/dist/tools/script-delete.js.map +1 -1
  692. package/dist/tools/script-read.d.ts +40 -2
  693. package/dist/tools/script-read.js +34 -39
  694. package/dist/tools/script-read.js.map +1 -1
  695. package/dist/tools/script-write.d.ts +40 -2
  696. package/dist/tools/script-write.js +37 -49
  697. package/dist/tools/script-write.js.map +1 -1
  698. package/dist/tools/scriptableobject-create.d.ts +40 -2
  699. package/dist/tools/scriptableobject-create.js +56 -68
  700. package/dist/tools/scriptableobject-create.js.map +1 -1
  701. package/dist/tools/search-assets.d.ts +40 -2
  702. package/dist/tools/search-assets.js +55 -58
  703. package/dist/tools/search-assets.js.map +1 -1
  704. package/dist/tools/selection-get.d.ts +40 -2
  705. package/dist/tools/selection-get.js +16 -21
  706. package/dist/tools/selection-get.js.map +1 -1
  707. package/dist/tools/selection-set.d.ts +40 -2
  708. package/dist/tools/selection-set.js +57 -62
  709. package/dist/tools/selection-set.js.map +1 -1
  710. package/dist/tools/settings-get-lighting.d.ts +40 -2
  711. package/dist/tools/settings-get-lighting.js +9 -14
  712. package/dist/tools/settings-get-lighting.js.map +1 -1
  713. package/dist/tools/settings-get-physics.d.ts +40 -2
  714. package/dist/tools/settings-get-physics.js +7 -12
  715. package/dist/tools/settings-get-physics.js.map +1 -1
  716. package/dist/tools/settings-get-player.d.ts +40 -2
  717. package/dist/tools/settings-get-player.js +7 -12
  718. package/dist/tools/settings-get-player.js.map +1 -1
  719. package/dist/tools/settings-get-quality.d.ts +40 -2
  720. package/dist/tools/settings-get-quality.js +7 -12
  721. package/dist/tools/settings-get-quality.js.map +1 -1
  722. package/dist/tools/settings-get-render-pipeline.d.ts +40 -2
  723. package/dist/tools/settings-get-render-pipeline.js +10 -15
  724. package/dist/tools/settings-get-render-pipeline.js.map +1 -1
  725. package/dist/tools/settings-get-time.d.ts +40 -2
  726. package/dist/tools/settings-get-time.js +9 -14
  727. package/dist/tools/settings-get-time.js.map +1 -1
  728. package/dist/tools/settings-set-lighting.d.ts +40 -2
  729. package/dist/tools/settings-set-lighting.js +33 -46
  730. package/dist/tools/settings-set-lighting.js.map +1 -1
  731. package/dist/tools/settings-set-physics.d.ts +40 -2
  732. package/dist/tools/settings-set-physics.js +30 -43
  733. package/dist/tools/settings-set-physics.js.map +1 -1
  734. package/dist/tools/settings-set-player.d.ts +40 -2
  735. package/dist/tools/settings-set-player.js +35 -53
  736. package/dist/tools/settings-set-player.js.map +1 -1
  737. package/dist/tools/settings-set-quality-level.d.ts +40 -2
  738. package/dist/tools/settings-set-quality-level.js +25 -38
  739. package/dist/tools/settings-set-quality-level.js.map +1 -1
  740. package/dist/tools/settings-set-quality.d.ts +40 -2
  741. package/dist/tools/settings-set-quality.js +29 -42
  742. package/dist/tools/settings-set-quality.js.map +1 -1
  743. package/dist/tools/settings-set-time.d.ts +40 -2
  744. package/dist/tools/settings-set-time.js +31 -44
  745. package/dist/tools/settings-set-time.js.map +1 -1
  746. package/dist/tools/shader-get-data.d.ts +40 -2
  747. package/dist/tools/shader-get-data.js +20 -25
  748. package/dist/tools/shader-get-data.js.map +1 -1
  749. package/dist/tools/shader-graph-create.d.ts +40 -2
  750. package/dist/tools/shader-graph-create.js +23 -32
  751. package/dist/tools/shader-graph-create.js.map +1 -1
  752. package/dist/tools/shader-graph-node-add.d.ts +40 -2
  753. package/dist/tools/shader-graph-node-add.js +34 -43
  754. package/dist/tools/shader-graph-node-add.js.map +1 -1
  755. package/dist/tools/shader-graph-node-connect.d.ts +40 -2
  756. package/dist/tools/shader-graph-node-connect.js +44 -53
  757. package/dist/tools/shader-graph-node-connect.js.map +1 -1
  758. package/dist/tools/shader-graph-open.d.ts +40 -2
  759. package/dist/tools/shader-graph-open.js +15 -20
  760. package/dist/tools/shader-graph-open.js.map +1 -1
  761. package/dist/tools/shader-list-all.d.ts +40 -2
  762. package/dist/tools/shader-list-all.js +12 -17
  763. package/dist/tools/shader-list-all.js.map +1 -1
  764. package/dist/tools/skybox-get.d.ts +40 -2
  765. package/dist/tools/skybox-get.js +5 -10
  766. package/dist/tools/skybox-get.js.map +1 -1
  767. package/dist/tools/skybox-set.d.ts +40 -2
  768. package/dist/tools/skybox-set.js +16 -27
  769. package/dist/tools/skybox-set.js.map +1 -1
  770. package/dist/tools/spatial-query.d.ts +40 -2
  771. package/dist/tools/spatial-query.js +110 -115
  772. package/dist/tools/spatial-query.js.map +1 -1
  773. package/dist/tools/splines-add-knot.d.ts +40 -2
  774. package/dist/tools/splines-add-knot.js +29 -38
  775. package/dist/tools/splines-add-knot.js.map +1 -1
  776. package/dist/tools/splines-container-create.d.ts +40 -2
  777. package/dist/tools/splines-container-create.js +23 -32
  778. package/dist/tools/splines-container-create.js.map +1 -1
  779. package/dist/tools/splines-evaluate.d.ts +40 -2
  780. package/dist/tools/splines-evaluate.js +21 -26
  781. package/dist/tools/splines-evaluate.js.map +1 -1
  782. package/dist/tools/splines-get-knots.d.ts +40 -2
  783. package/dist/tools/splines-get-knots.js +15 -20
  784. package/dist/tools/splines-get-knots.js.map +1 -1
  785. package/dist/tools/splines-modify.d.ts +40 -2
  786. package/dist/tools/splines-modify.js +20 -29
  787. package/dist/tools/splines-modify.js.map +1 -1
  788. package/dist/tools/splines-set-knot.d.ts +40 -2
  789. package/dist/tools/splines-set-knot.js +26 -35
  790. package/dist/tools/splines-set-knot.js.map +1 -1
  791. package/dist/tools/splines-set-tangent-mode.d.ts +40 -2
  792. package/dist/tools/splines-set-tangent-mode.js +28 -37
  793. package/dist/tools/splines-set-tangent-mode.js.map +1 -1
  794. package/dist/tools/spriteatlas-add-packable.d.ts +40 -2
  795. package/dist/tools/spriteatlas-add-packable.js +22 -34
  796. package/dist/tools/spriteatlas-add-packable.js.map +1 -1
  797. package/dist/tools/spriteatlas-create.d.ts +40 -2
  798. package/dist/tools/spriteatlas-create.js +22 -34
  799. package/dist/tools/spriteatlas-create.js.map +1 -1
  800. package/dist/tools/spriteatlas-delete.d.ts +40 -2
  801. package/dist/tools/spriteatlas-delete.js +14 -26
  802. package/dist/tools/spriteatlas-delete.js.map +1 -1
  803. package/dist/tools/spriteatlas-get.d.ts +40 -2
  804. package/dist/tools/spriteatlas-get.js +13 -18
  805. package/dist/tools/spriteatlas-get.js.map +1 -1
  806. package/dist/tools/spriteatlas-list.d.ts +40 -2
  807. package/dist/tools/spriteatlas-list.js +10 -15
  808. package/dist/tools/spriteatlas-list.js.map +1 -1
  809. package/dist/tools/spriteatlas-modify.d.ts +40 -2
  810. package/dist/tools/spriteatlas-modify.js +36 -48
  811. package/dist/tools/spriteatlas-modify.js.map +1 -1
  812. package/dist/tools/spriteatlas-remove-packable.d.ts +40 -2
  813. package/dist/tools/spriteatlas-remove-packable.js +21 -33
  814. package/dist/tools/spriteatlas-remove-packable.js.map +1 -1
  815. package/dist/tools/terrain-create.d.ts +40 -2
  816. package/dist/tools/terrain-create.js +48 -62
  817. package/dist/tools/terrain-create.js.map +1 -1
  818. package/dist/tools/terrain-paint-layer.d.ts +40 -2
  819. package/dist/tools/terrain-paint-layer.js +47 -61
  820. package/dist/tools/terrain-paint-layer.js.map +1 -1
  821. package/dist/tools/terrain-place-trees.d.ts +40 -2
  822. package/dist/tools/terrain-place-trees.js +56 -68
  823. package/dist/tools/terrain-place-trees.js.map +1 -1
  824. package/dist/tools/terrain-set-heights.d.ts +40 -2
  825. package/dist/tools/terrain-set-heights.js +31 -43
  826. package/dist/tools/terrain-set-heights.js.map +1 -1
  827. package/dist/tools/terrain-set-neighbors.d.ts +40 -2
  828. package/dist/tools/terrain-set-neighbors.js +22 -34
  829. package/dist/tools/terrain-set-neighbors.js.map +1 -1
  830. package/dist/tools/texture-get-importer.d.ts +40 -2
  831. package/dist/tools/texture-get-importer.js +15 -20
  832. package/dist/tools/texture-get-importer.js.map +1 -1
  833. package/dist/tools/texture-get.d.ts +40 -2
  834. package/dist/tools/texture-get.js +12 -17
  835. package/dist/tools/texture-get.js.map +1 -1
  836. package/dist/tools/texture-reimport.d.ts +40 -2
  837. package/dist/tools/texture-reimport.js +15 -27
  838. package/dist/tools/texture-reimport.js.map +1 -1
  839. package/dist/tools/texture-set-import.d.ts +40 -2
  840. package/dist/tools/texture-set-import.js +32 -44
  841. package/dist/tools/texture-set-import.js.map +1 -1
  842. package/dist/tools/tilemap-box-fill.d.ts +40 -2
  843. package/dist/tools/tilemap-box-fill.js +20 -29
  844. package/dist/tools/tilemap-box-fill.js.map +1 -1
  845. package/dist/tools/tilemap-create-rule-tile.d.ts +40 -2
  846. package/dist/tools/tilemap-create-rule-tile.js +22 -31
  847. package/dist/tools/tilemap-create-rule-tile.js.map +1 -1
  848. package/dist/tools/tilemap-create-tile-asset.d.ts +40 -2
  849. package/dist/tools/tilemap-create-tile-asset.js +21 -30
  850. package/dist/tools/tilemap-create-tile-asset.js.map +1 -1
  851. package/dist/tools/tilemap-create.d.ts +40 -2
  852. package/dist/tools/tilemap-create.js +17 -26
  853. package/dist/tools/tilemap-create.js.map +1 -1
  854. package/dist/tools/tilemap-set-tile.d.ts +40 -2
  855. package/dist/tools/tilemap-set-tile.js +20 -29
  856. package/dist/tools/tilemap-set-tile.js.map +1 -1
  857. package/dist/tools/timeline-clip-add.d.ts +40 -2
  858. package/dist/tools/timeline-clip-add.js +30 -39
  859. package/dist/tools/timeline-clip-add.js.map +1 -1
  860. package/dist/tools/timeline-create.d.ts +40 -2
  861. package/dist/tools/timeline-create.js +17 -26
  862. package/dist/tools/timeline-create.js.map +1 -1
  863. package/dist/tools/timeline-director-bind.d.ts +40 -2
  864. package/dist/tools/timeline-director-bind.js +20 -29
  865. package/dist/tools/timeline-director-bind.js.map +1 -1
  866. package/dist/tools/timeline-modify.d.ts +40 -2
  867. package/dist/tools/timeline-modify.js +30 -39
  868. package/dist/tools/timeline-modify.js.map +1 -1
  869. package/dist/tools/timeline-track-add.d.ts +40 -2
  870. package/dist/tools/timeline-track-add.js +24 -33
  871. package/dist/tools/timeline-track-add.js.map +1 -1
  872. package/dist/tools/type-schema.d.ts +40 -2
  873. package/dist/tools/type-schema.js +47 -52
  874. package/dist/tools/type-schema.js.map +1 -1
  875. package/dist/tools/ui-canvas-add.d.ts +40 -2
  876. package/dist/tools/ui-canvas-add.js +29 -41
  877. package/dist/tools/ui-canvas-add.js.map +1 -1
  878. package/dist/tools/ui-element-add.d.ts +40 -2
  879. package/dist/tools/ui-element-add.js +47 -56
  880. package/dist/tools/ui-element-add.js.map +1 -1
  881. package/dist/tools/ui-element-modify.d.ts +40 -2
  882. package/dist/tools/ui-element-modify.js +41 -50
  883. package/dist/tools/ui-element-modify.js.map +1 -1
  884. package/dist/tools/ui-layout-group-add.d.ts +40 -2
  885. package/dist/tools/ui-layout-group-add.js +64 -73
  886. package/dist/tools/ui-layout-group-add.js.map +1 -1
  887. package/dist/tools/validate-edit.d.ts +40 -2
  888. package/dist/tools/validate-edit.js +56 -61
  889. package/dist/tools/validate-edit.js.map +1 -1
  890. package/dist/tools/vfx-block-edit.d.ts +40 -2
  891. package/dist/tools/vfx-block-edit.js +32 -41
  892. package/dist/tools/vfx-block-edit.js.map +1 -1
  893. package/dist/tools/vfx-list.d.ts +40 -2
  894. package/dist/tools/vfx-list.js +17 -22
  895. package/dist/tools/vfx-list.js.map +1 -1
  896. package/dist/tools/vfx-open.d.ts +40 -2
  897. package/dist/tools/vfx-open.js +14 -19
  898. package/dist/tools/vfx-open.js.map +1 -1
  899. package/package.json +1 -1
@@ -1,17 +1,44 @@
1
1
  import { AssetModelCache, isCompressible, routeCompressible } from "./compressible-router.js";
2
2
  import { listAssetsOffline, findReferencesOffline, dependenciesOffline } from "./offline.js";
3
3
  import { resolveEditorLogPath, readLogTail, DEFAULT_LOG_TAIL_BYTES, detectStaleLog } from "./unity-log.js";
4
- import { summarizeProjectHealth } from "./project-health.js";
4
+ import { summarizeProjectHealth, extractProjectHealthIssues } from "./project-health.js";
5
5
  import { buildCapabilities } from "./capabilities/build-capabilities.js";
6
6
  import { RULE_CATALOG, FIX_CATALOG } from "./capabilities/rule-catalog.js";
7
- import { GROUP_IDS, TOOL_GROUPS, AUTO_ACTIVATE_GROUPS, groupToTools, } from "./capabilities/tool-groups.js";
7
+ import { GROUP_IDS, TOOL_GROUPS, AUTO_ACTIVATE_GROUPS, groupToTools, getGroup, } from "./capabilities/tool-groups.js";
8
+ import { recommendGroups, } from "./capabilities/intent-groups.js";
8
9
  import { listRules } from "./capabilities/list-rules.js";
9
10
  import { generateSkill } from "./skill/generate-skill.js";
10
- import { knownClientKeys } from "./skill/client-paths.js";
11
+ import { getKnownClientKeys } from "./skill/client-paths.js";
11
12
  import { ALL_TOOLS } from "./tools/index.js";
12
13
  import { lockPath, readInstanceLock, classifyInstance, isPidAlive } from "./instance-discovery.js";
13
14
  import { PORT_ENV_VAR } from "./constants.js";
14
15
  import { findUnityForProject } from "./running-unity.js";
16
+ // M31-optimizations Plan 1 / L14 — opt-in route-logging gate. Resolved once at
17
+ // module load into a boolean; the per-dispatch log sites read the boolean
18
+ // (not process.env on every call) so the hot path stays a single branch.
19
+ // Default-off: silent in production; set UNITY_OPEN_MCP_DEBUG=1 (or pass
20
+ // --verbose to the server) to re-enable the [unity-open-mcp] Route: trace.
21
+ // Genuine error-path logging is unconditional and never gated by this flag.
22
+ //
23
+ // Exported (ROUTE_LOG_ENABLED + logRoute) so the test suite can pin both
24
+ // halves of the L14 contract: the env-resolution semantics (via
25
+ // resolveRouteLogEnabled, the pure helper) and the default-off posture (via
26
+ // the captured boolean, which reflects whatever the env was at module load).
27
+ export function resolveRouteLogEnabled(env = process.env) {
28
+ return env.UNITY_OPEN_MCP_DEBUG === "1" || env.UNITY_OPEN_MCP_VERBOSE === "1";
29
+ }
30
+ export const ROUTE_LOG_ENABLED = resolveRouteLogEnabled();
31
+ /** Log a happy-path route trace iff the opt-in env flag is set. No-op by
32
+ * default so high-throughput agents do not pay a console.error per dispatch. */
33
+ export function logRoute(message) {
34
+ if (ROUTE_LOG_ENABLED)
35
+ console.error(message);
36
+ }
37
+ // M31 Plan 3 — Editor fd-exhaustion auto-recovery (restart_editor) + prediction
38
+ // (resource_pressure). Both act on the OS process, not the bridge, so they
39
+ // share the local route classification with bridge_status.
40
+ import { killEditorProcess, DEFAULT_KILL_GRACE_MS, MAX_KILL_WAIT_MS, } from "./editor-process-control.js";
41
+ import { countFileDescriptors, computeFdHeadroom, analyzeFdTrend, LAUNCH_CONTEXT_CAVEAT, FD_CEILING, } from "./process-diagnostics.js";
15
42
  import { listInstalledEditors, fetchAvailableReleases, openInstallDeepLink, getInstallPath, setInstallPath, } from "./hub-control.js";
16
43
  /** Default Hub-control backend — calls the real hub-control functions. */
17
44
  const defaultHubBackend = {
@@ -23,6 +50,48 @@ const defaultHubBackend = {
23
50
  };
24
51
  import { BATCH_TOOL_NAMES, ALWAYS_BATCH_TOOLS } from "./batch-spawn.js";
25
52
  import { readProfileAndDetail, applyPaging, attachPagination, foldVerifyResult, parseResultBody, withResultBody, } from "./output-profile.js";
53
+ /**
54
+ * Single source of truth for the `_source` tag. Every route-tagging site goes
55
+ * through one of the two helpers below so live / offline / local stay
56
+ * symmetric — a new route adding `_source` inline (the omission that slipped
57
+ * through before T6.1) is caught by the "no inline `_source` outside the
58
+ * helper" rule and grep.
59
+ *
60
+ * - {@link withSource} stamps `_source` on a body object literal (the local /
61
+ * offline paths that build the JSON themselves).
62
+ * - {@link tagSource} stamps `_source` on an already-built {@link
63
+ * CallToolResult} (the live / offline-result paths that wrap a bridge or
64
+ * disk result).
65
+ */
66
+ function withSource(body, source) {
67
+ return { ...body, _source: source };
68
+ }
69
+ /**
70
+ * Tag a CallToolResult's JSON body with `_source` so callers switching on the
71
+ * field see a defined value for live-routed drill-downs (find_references /
72
+ * dependencies). A no-op when the first content block is not parseable JSON;
73
+ * preserves `isError` and other content blocks.
74
+ */
75
+ function tagSource(result, source) {
76
+ const body = parseResultBody(result);
77
+ if (body === null)
78
+ return result;
79
+ return withResultBody(result, withSource(body, source));
80
+ }
81
+ /**
82
+ * Build a single-block CallToolResult from a body object, tagging it with
83
+ * `_source`. The common shape for local/offline routes that synthesize the
84
+ * entire response in the MCP server (no bridge tool endpoint). Accepts the
85
+ * typed result shapes (ListAssetsResult, CapabilitiesResult, …) returned by
86
+ * the offline/local builders.
87
+ */
88
+ function sourceResult(body, source, isError = false) {
89
+ const tagged = withSource(body, source);
90
+ return {
91
+ content: [{ type: "text", text: JSON.stringify(tagged) }],
92
+ isError,
93
+ };
94
+ }
26
95
  function injectRouteMeta(result, meta) {
27
96
  if (result.content.length === 0)
28
97
  return result;
@@ -47,16 +116,70 @@ function injectRouteMeta(result, meta) {
47
116
  return result;
48
117
  }
49
118
  }
119
+ // ===========================================================================
120
+ // M31-optimizations Plan 1 / H2 — single parse+stringify for the live result
121
+ // post-processors (fold + _source + _route).
122
+ //
123
+ // The live find_references / dependencies paths previously chained THREE
124
+ // CallToolResult transforms — foldFindReferencesLive → tagSource →
125
+ // injectRouteMeta — each doing its own JSON.parse + JSON.stringify on the
126
+ // same payload (3 cycles per call). The helpers below collapse that to ONE
127
+ // parse and ONE stringify by operating on the parsed body object directly.
128
+ // `transformLiveResult` is the single entry point; it parses once, applies a
129
+ // caller-supplied body transform (fold / paging / nothing), stamps `_source`
130
+ // and `_route`, and stringifies exactly once.
131
+ //
132
+ // The legacy `tagSource` / `injectRouteMeta` helpers stay for the many call
133
+ // sites that only need ONE of the two stamps (so they incur just one
134
+ // parse+stringify each — not the triple-cycle chain the live routes had).
135
+ // ===========================================================================
136
+ /**
137
+ * Apply a body-level transform pipeline to a {@link CallToolResult} in ONE
138
+ * parse + ONE stringify cycle. Used by the live find_references /
139
+ * dependencies / verify routes that previously chained
140
+ * fold→tagSource→injectRouteMeta (three parse+stringify cycles each).
141
+ *
142
+ * Steps:
143
+ * 1. Parse the first text content block ONCE.
144
+ * 2. Hand the parsed body to `transform` (may return null to signal "leave
145
+ * the body as-is" — the error case; the transform has nothing useful to
146
+ * do on an error body).
147
+ * 3. Stamp `_source` and `_route` on the (possibly transformed) body — also
148
+ * when the transform returned null, falling back to the original body.
149
+ * This preserves the pre-change chain's contract (`tagSource` +
150
+ * `injectRouteMeta` always stamped a parseable body, error or not), so
151
+ * error responses still carry `_source` / `_route` for agent routing.
152
+ * 4. Stringify ONCE into the result's first text block; preserve isError
153
+ * and any other content blocks (e.g. an MCP image block).
154
+ *
155
+ * `transform` defaults to identity. When the body fails to parse, the result
156
+ * is returned unchanged (no stamps — there is no JSON object to stamp).
157
+ */
158
+ function transformLiveResult(result, source, meta, transform) {
159
+ const body = parseResultBody(result);
160
+ // parseResultBody returns null when there is no text block OR the block is
161
+ // not a JSON object. In either case there is nothing to stamp — return the
162
+ // result verbatim, matching tagSource/injectRouteMeta's no-op behavior on
163
+ // an unparsable body.
164
+ if (body === null)
165
+ return result;
166
+ // A null transform signals "leave the body as-is" (e.g. the fold has
167
+ // nothing to do on an error body). Fall through to identity so the stamps
168
+ // still land — matching the pre-change chain, where tagSource/injectRouteMeta
169
+ // stamped any parseable body regardless of an `error` field.
170
+ const transformed = transform ? transform(body) : body;
171
+ const stamped = {
172
+ ...(transformed ?? body),
173
+ _source: source,
174
+ _route: meta,
175
+ };
176
+ return withResultBody(result, stamped);
177
+ }
50
178
  // M26 Plan 2 — local-routed error result (used by the Hub control tools for
51
179
  // missing-parameter refusals before any side effect runs). Tagged _source=local
52
180
  // because it is resolved entirely in the MCP server.
53
181
  function localError(code, message) {
54
- return {
55
- content: [
56
- { type: "text", text: JSON.stringify({ error: { code, message }, _source: "local" }) },
57
- ],
58
- isError: true,
59
- };
182
+ return sourceResult({ error: { code, message } }, "local", true);
60
183
  }
61
184
  // M26 Plan 2 — gate-consistent envelope shape for the mutating Hub control
62
185
  // tools (install_editor / install_modules / set_install_path). These are
@@ -64,7 +187,7 @@ function localError(code, message) {
64
187
  // gate is skipped (gate.skipped=true). The shape matches MutationEnvelope so
65
188
  // agents parse it uniformly alongside bridge-routed mutating tools.
66
189
  function hubMutationEnvelope(opts) {
67
- const body = {
190
+ return sourceResult({
68
191
  mutation: {
69
192
  success: opts.success,
70
193
  output: opts.output,
@@ -77,12 +200,7 @@ function hubMutationEnvelope(opts) {
77
200
  delta: null,
78
201
  },
79
202
  agentNextSteps: opts.nextSteps,
80
- _source: "local",
81
- };
82
- return {
83
- content: [{ type: "text", text: JSON.stringify(body) }],
84
- isError: opts.isError,
85
- };
203
+ }, "local", opts.isError);
86
204
  }
87
205
  function activeGroupsEqual(a, b) {
88
206
  if (a.length !== b.length)
@@ -142,16 +260,22 @@ function pageFindReferencesResult(result, pageSize, cursor) {
142
260
  return attachPagination({ ...result, referencedBy: page }, block);
143
261
  }
144
262
  /**
145
- * Fold + page the LIVE find_references result. The bridge returns a flat
263
+ * Fold + page the LIVE find_references result body. The bridge returns a flat
146
264
  * `referencedBy` path list (no byKind/byFolder groupings, no locations); we
147
265
  * derive the compact grouping server-side and page when requested.
266
+ *
267
+ * M31-optimizations Plan 1 / H2 — operates on a parsed body object (not a
268
+ * re-stringified {@link CallToolResult}) so it can be chained with
269
+ * {@link tagSourceBody} / {@link injectRouteMetaBody} in a single
270
+ * parse+stringify cycle via {@link transformLiveResult}.
271
+ *
272
+ * Returns null when the body should NOT be folded (it is not a parseable
273
+ * object, or it carries a top-level `error`), signalling the caller to leave
274
+ * the result untouched.
148
275
  */
149
- function foldFindReferencesLive(result, profile, wantPaging, args) {
150
- const body = parseResultBody(result);
151
- if (body === null)
152
- return result;
276
+ function foldFindReferencesLiveBody(body, profile, wantPaging, args) {
153
277
  if (body.error)
154
- return result;
278
+ return null;
155
279
  // Bridge shape: { referencedBy: string[], totalCount, ... } (flat paths).
156
280
  const rawList = Array.isArray(body.referencedBy) ? body.referencedBy : [];
157
281
  const pageSize = typeof args.page_size === "number" && args.page_size > 0 ? args.page_size : 0;
@@ -161,20 +285,19 @@ function foldFindReferencesLive(result, profile, wantPaging, args) {
161
285
  const { referencedBy: _dropped, ...rest } = body;
162
286
  void _dropped;
163
287
  const byKind = groupLiveRefsByKind(rawList);
164
- return withResultBody(result, {
288
+ return {
165
289
  ...rest,
166
290
  totalCount: rawList.length,
167
291
  byKind,
168
292
  referencedBy: [],
169
- });
293
+ };
170
294
  }
171
295
  // balanced / full: keep the path list (paged when requested).
172
296
  if (pageSize > 0) {
173
297
  const { page, block } = applyPaging(rawList, "find_references", { page_size: pageSize, cursor });
174
- const withPage = attachPagination({ ...body, referencedBy: page, totalCount: rawList.length }, block);
175
- return withResultBody(result, withPage);
298
+ return attachPagination({ ...body, referencedBy: page, totalCount: rawList.length }, block);
176
299
  }
177
- return withResultBody(result, { ...body, totalCount: rawList.length });
300
+ return { ...body, totalCount: rawList.length };
178
301
  }
179
302
  /** Derive a byKind grouping from flat referenced paths for the live compact view. */
180
303
  function groupLiveRefsByKind(paths) {
@@ -265,6 +388,13 @@ export class ToolRouter {
265
388
  ["unity_open_mcp_generate_skill", (_l, a) => this.routeGenerateSkill(a)],
266
389
  ["unity_open_mcp_manage_tools", (l, a) => this.routeManageTools(a, l)],
267
390
  ["unity_open_mcp_bridge_status", (l, a) => this.routeBridgeStatus(a, l)],
391
+ // M31 Plan 3 — Editor fd-exhaustion operator surfaces. restart_editor
392
+ // is the reactive kill half (acts AFTER the Editor is hung);
393
+ // resource_pressure is the proactive prediction half (samples fd usage
394
+ // BEFORE exhaustion). Both are local-routed: they act on the OS process,
395
+ // not the bridge, like bridge_status.
396
+ ["unity_open_mcp_restart_editor", (l, a) => this.routeRestartEditor(a, l)],
397
+ ["unity_open_mcp_resource_pressure", (_l, a) => this.routeResourcePressure(a)],
268
398
  // Hub control tools (local-routed; system-level ops).
269
399
  ["unity_open_mcp_hub_list_editors", () => this.routeHubListEditors()],
270
400
  ["unity_open_mcp_hub_available_releases", () => this.routeHubAvailableReleases()],
@@ -350,7 +480,7 @@ export class ToolRouter {
350
480
  // second pinned branch for a new always-batch tool — extend the map.
351
481
  const alwaysBatchReason = ALWAYS_BATCH_TOOLS.get(toolName);
352
482
  if (alwaysBatchReason !== undefined) {
353
- console.error(`[unity-open-mcp] Route: ${toolName} -> batch (always-batch: ${alwaysBatchReason})`);
483
+ logRoute(`[unity-open-mcp] Route: ${toolName} -> batch (always-batch: ${alwaysBatchReason})`);
354
484
  const result = await this.batch.route(toolName, args);
355
485
  return injectRouteMeta(result, {
356
486
  route: "batch",
@@ -363,11 +493,11 @@ export class ToolRouter {
363
493
  }
364
494
  const liveAvailable = await live.isLiveAvailable();
365
495
  if (liveAvailable) {
366
- console.error(`[unity-open-mcp] Route: ${toolName} -> live`);
496
+ logRoute(`[unity-open-mcp] Route: ${toolName} -> live`);
367
497
  const result = await live.route(toolName, args);
368
498
  return injectRouteMeta(result, { route: "live" });
369
499
  }
370
- console.error(`[unity-open-mcp] Route: ${toolName} -> batch (live bridge unavailable)`);
500
+ logRoute(`[unity-open-mcp] Route: ${toolName} -> batch (live bridge unavailable)`);
371
501
  if (isPing) {
372
502
  return this.batchPingResult();
373
503
  }
@@ -472,38 +602,29 @@ export class ToolRouter {
472
602
  if (stale.staleLogSuspected)
473
603
  staleLog = stale;
474
604
  }
475
- return {
476
- content: [
477
- {
478
- type: "text",
479
- text: JSON.stringify({
480
- status,
481
- unhealthy: health.unhealthy,
482
- headline: health.headline,
483
- errorCount: errors.length,
484
- errors,
485
- // Package / assembly issues from the same log tail. Empty when the
486
- // only red flags are compiler errors (the common case).
487
- issues: health.issues,
488
- issueCount: health.issues.length,
489
- logPath,
490
- tailBytes: tail.bytes,
491
- // Present ONLY when at least one cited source file is newer than
492
- // Editor.log — the log's most-recent error block may be stale and
493
- // the agent should force a recompile before trusting the errors.
494
- ...(staleLog
495
- ? {
496
- staleLogSuspected: true,
497
- staleLogHint: staleLog.hint,
498
- staleLogNewerFiles: staleLog.newerFiles,
499
- }
500
- : {}),
501
- _source: "offline",
502
- }),
503
- },
504
- ],
505
- isError: false,
506
- };
605
+ return sourceResult({
606
+ status,
607
+ unhealthy: health.unhealthy,
608
+ headline: health.headline,
609
+ errorCount: errors.length,
610
+ errors,
611
+ // Package / assembly issues from the same log tail. Empty when the
612
+ // only red flags are compiler errors (the common case).
613
+ issues: health.issues,
614
+ issueCount: health.issues.length,
615
+ logPath,
616
+ tailBytes: tail.bytes,
617
+ // Present ONLY when at least one cited source file is newer than
618
+ // Editor.log — the log's most-recent error block may be stale and
619
+ // the agent should force a recompile before trusting the errors.
620
+ ...(staleLog
621
+ ? {
622
+ staleLogSuspected: true,
623
+ staleLogHint: staleLog.hint,
624
+ staleLogNewerFiles: staleLog.newerFiles,
625
+ }
626
+ : {}),
627
+ }, "offline");
507
628
  }
508
629
  async routeListAssets(args) {
509
630
  try {
@@ -513,10 +634,7 @@ export class ToolRouter {
513
634
  maxPerFolder: typeof args.max_per_folder === "number" ? args.max_per_folder : 30,
514
635
  projectRoot: this.projectPath,
515
636
  });
516
- return {
517
- content: [{ type: "text", text: JSON.stringify({ ...result, _source: "offline" }) }],
518
- isError: false,
519
- };
637
+ return sourceResult(result, "offline");
520
638
  }
521
639
  catch (err) {
522
640
  const message = err instanceof Error ? err.message : String(err);
@@ -595,24 +713,14 @@ export class ToolRouter {
595
713
  fixes: FIX_CATALOG,
596
714
  availableBridgeTools,
597
715
  }, { kind, includePlanned });
598
- return {
599
- content: [
600
- { type: "text", text: JSON.stringify({ ...result, _source: "local" }) },
601
- ],
602
- isError: false,
603
- };
716
+ return sourceResult(result, "local");
604
717
  }
605
718
  async routeListRules(args) {
606
719
  const assetKind = typeof args.asset_kind === "string" ? args.asset_kind : undefined;
607
720
  const extension = typeof args.extension === "string" ? args.extension : undefined;
608
721
  const implementedOnly = args.implemented_only === true;
609
722
  const result = listRules({ rules: RULE_CATALOG, fixes: FIX_CATALOG }, { assetKind, extension, implementedOnly });
610
- return {
611
- content: [
612
- { type: "text", text: JSON.stringify({ ...result, _source: "local" }) },
613
- ],
614
- isError: false,
615
- };
723
+ return sourceResult(result, "local");
616
724
  }
617
725
  async routeGenerateSkill(args) {
618
726
  const write = args.write === true;
@@ -622,7 +730,11 @@ export class ToolRouter {
622
730
  const rawClients = Array.isArray(args.clients) ? args.clients : [];
623
731
  // Client allowlist comes from the single-source manifest at
624
732
  // `skills/client-paths.json`. Do not add a literal union here.
625
- const allowedClients = new Set(knownClientKeys());
733
+ // M31-optimizations Plan 4 / T4.4 (L6) — reuse the module-level
734
+ // `KNOWN_CLIENT_KEYS` singleton instead of allocating a fresh Set per
735
+ // call. The Set is built once on first access and re-derived only when
736
+ // the manifest cache is reset (tests).
737
+ const allowedClients = getKnownClientKeys();
626
738
  const clients = rawClients.filter((c) => typeof c === "string" && allowedClients.has(c));
627
739
  const caps = buildCapabilities({
628
740
  tools: ALL_TOOLS,
@@ -636,20 +748,11 @@ export class ToolRouter {
636
748
  clients: clients.length > 0 ? clients : undefined,
637
749
  includeWorkflow,
638
750
  });
639
- return {
640
- content: [
641
- {
642
- type: "text",
643
- text: JSON.stringify({
644
- skill: result.skill,
645
- project: result.project,
646
- written: result.written,
647
- _source: "local",
648
- }),
649
- },
650
- ],
651
- isError: false,
652
- };
751
+ return sourceResult({
752
+ skill: result.skill,
753
+ project: result.project,
754
+ written: result.written,
755
+ }, "local");
653
756
  }
654
757
  catch (err) {
655
758
  const message = err instanceof Error ? err.message : String(err);
@@ -684,6 +787,28 @@ export class ToolRouter {
684
787
  if (action === "list_groups") {
685
788
  return this.manageToolsListGroups(live);
686
789
  }
790
+ // M31 Plan 2 / T31.2 — intent-driven actions. `suggest` is the read-only
791
+ // path (returns recommendations without changing state); `activate_for`
792
+ // activates the recommended set in one call. Both share the recommend
793
+ // engine + the per-group compiled-state availability, so an agent sees
794
+ // the same honesty about unavailable groups as `list_groups` (the
795
+ // recommendation lists them as `unavailable` with `availableReason`
796
+ // instead of pretending activation succeeded).
797
+ if (action === "suggest" || action === "activate_for") {
798
+ const intent = typeof args.intent === "string" ? args.intent : "";
799
+ const tags = Array.isArray(args.tags)
800
+ ? args.tags.filter((t) => typeof t === "string")
801
+ : [];
802
+ // Recommend against an empty input is a structured empty result, not an
803
+ // error — the agent gets the `list_groups` hint and can retry. This
804
+ // matches the spec ("unmatched intent returns a structured empty
805
+ // recommendation + hint to list_groups (no hallucinated groups)").
806
+ const rec = recommendGroups({ intent, tags });
807
+ if (action === "suggest") {
808
+ return this.manageToolsSuggest(rec, live);
809
+ }
810
+ return this.manageToolsActivateFor(rec, live);
811
+ }
687
812
  if (action === "reset") {
688
813
  const before = this.sessionState.activeGroups();
689
814
  this.sessionState.reset();
@@ -691,8 +816,9 @@ export class ToolRouter {
691
816
  return this.manageToolsResult({
692
817
  reset: true,
693
818
  activeGroups: this.sessionState.activeGroups(),
694
- message: "Tool-group visibility restored to defaults (`core` only). " +
695
- "MCP clients that support listChanged will refresh ListTools automatically.",
819
+ message: "Tool-group visibility restored to the default-on groups (core + " +
820
+ "gate-and-verify). MCP clients that support listChanged will refresh " +
821
+ "ListTools automatically.",
696
822
  });
697
823
  }
698
824
  if (action === "activate" || action === "deactivate") {
@@ -724,7 +850,8 @@ export class ToolRouter {
724
850
  : `Group '${group}' was already inactive.`,
725
851
  });
726
852
  }
727
- return this.manageToolsError("unknown_action", `Unknown action '${action}'. Valid actions: list_groups, activate, deactivate, reset.`);
853
+ return this.manageToolsError("unknown_action", `Unknown action '${action}'. Valid actions: list_groups, activate, ` +
854
+ `deactivate, reset, suggest, activate_for.`);
728
855
  }
729
856
  async manageToolsListGroups(live) {
730
857
  // M20 Plan 7 / T20.7.0 — fetch the compiled-state inventory once and
@@ -768,25 +895,132 @@ export class ToolRouter {
768
895
  tools,
769
896
  };
770
897
  });
898
+ return sourceResult({
899
+ groups,
900
+ activeGroups: this.sessionState.activeGroups(),
901
+ note: "Activate a group to add its tools to your ListTools surface; " +
902
+ "deactivate to hide them. State is per-session and ephemeral — " +
903
+ "it resets to the default-on groups (core + gate-and-verify) when " +
904
+ "the MCP server restarts. Compiled-state availability (the " +
905
+ "`available` field) reflects whether the Unity domain dependency is " +
906
+ "compiled in; use unity_open_mcp_capabilities for the authoritative " +
907
+ "compiled-state report.",
908
+ }, "local");
909
+ }
910
+ // M31 Plan 2 / T31.2 — `suggest` handler. Read-only: returns the
911
+ // recommendation with per-group compiled-state availability so the agent
912
+ // sees the same honesty as `list_groups` (a recommended group whose domain
913
+ // dependency is missing surfaces with `unavailable: true` +
914
+ // `availableReason`, never as a silent success). Reconciles auto-activation
915
+ // first so the `alreadyActive` flags reflect packages that came online.
916
+ async manageToolsSuggest(rec, live) {
917
+ const inventory = await this.fetchInventoryAndReconcile(live);
918
+ const compiledAvailability = this.computeCompiledAvailability(inventory, groupToTools());
919
+ const groups = rec.groups.map((g) => this.augmentRecommendation(g, compiledAvailability));
920
+ return sourceResult({
921
+ action: "suggest",
922
+ intent: rec,
923
+ groups,
924
+ activeGroups: this.sessionState.activeGroups(),
925
+ // `empty` surfaces at the top level too so agents branching on a
926
+ // miss don't have to dig into `intent.empty`.
927
+ empty: rec.empty,
928
+ ...(rec.empty ? { hint: rec.hint } : {}),
929
+ note: "Read-only recommendation. Pass the same intent/tags to " +
930
+ "action=\"activate_for\" to activate the recommended groups in one " +
931
+ "call, or activate individual ids with action=\"activate\".",
932
+ }, "local");
933
+ }
934
+ // M31 Plan 2 / T31.2 — `activate_for` handler. Activates the recommended
935
+ // set (union with the current active groups — never deactivates anything).
936
+ // `unavailable` recommended groups are reported honestly: today's session
937
+ // model lets an agent activate a group whose domain dependency is missing
938
+ // (the tools appear in ListTools but error at call time), so we DO activate
939
+ // them but the response calls out the gap via `unavailable` + the standard
940
+ // `availableReason`. Emits `notifications/tools/list_changed` exactly once
941
+ // when the visible set changed (idempotent when already active).
942
+ async manageToolsActivateFor(rec, live) {
943
+ const inventory = await this.fetchInventoryAndReconcile(live);
944
+ const compiledAvailability = this.computeCompiledAvailability(inventory, groupToTools());
945
+ const before = this.sessionState.activeGroups();
946
+ const activated = [];
947
+ const skipped = [];
948
+ const unavailable = [];
949
+ for (const g of rec.groups) {
950
+ const changed = this.sessionState.activate(g.id);
951
+ if (changed) {
952
+ activated.push(g.id);
953
+ }
954
+ else {
955
+ skipped.push(g.id);
956
+ }
957
+ const avail = compiledAvailability.get(g.id);
958
+ if (avail && (avail.available === false || avail.available === null)) {
959
+ unavailable.push({ id: g.id, reason: avail.reason });
960
+ }
961
+ }
962
+ await this.maybeNotifyToolListChanged(before);
963
+ const groups = rec.groups.map((g) => this.augmentRecommendation(g, compiledAvailability));
964
+ const anyChange = activated.length > 0;
965
+ const message = rec.empty
966
+ ? rec.hint
967
+ : anyChange
968
+ ? `Activated ${activated.length} group(s) for the intent: ` +
969
+ `${activated.join(", ")}. MCP clients that support listChanged ` +
970
+ `will refresh ListTools automatically.`
971
+ : `All recommended groups were already active.`;
972
+ return sourceResult({
973
+ action: "activate_for",
974
+ intent: rec,
975
+ groups,
976
+ activated,
977
+ skipped,
978
+ unavailable,
979
+ activeGroups: this.sessionState.activeGroups(),
980
+ changed: anyChange,
981
+ empty: rec.empty,
982
+ message,
983
+ ...(unavailable.length > 0
984
+ ? {
985
+ unavailableNote: "One or more recommended groups have a missing Unity domain " +
986
+ "dependency — their tools will appear in ListTools but error " +
987
+ "at call time. Use unity_open_mcp_capabilities for the " +
988
+ "authoritative compiled-state report, or install the cited " +
989
+ "Unity package and reconcile via list_groups.",
990
+ }
991
+ : {}),
992
+ }, "local");
993
+ }
994
+ /**
995
+ * Fetch the live bridge inventory (or null when offline) and reconcile auto-
996
+ * activation against it. Shared by `suggest` / `activate_for` so both see the
997
+ * same compiled-state + auto-activated snapshot as `list_groups` without
998
+ * duplicating the GET /tools hop.
999
+ */
1000
+ async fetchInventoryAndReconcile(live) {
1001
+ const liveAvailable = await live.isLiveAvailable();
1002
+ const inventory = liveAvailable ? await live.listBridgeTools() : null;
1003
+ await this.reconcileAutoActivation(inventory ? { tools: inventory.tools } : null);
1004
+ return inventory;
1005
+ }
1006
+ /**
1007
+ * Augment a {@link RecommendedGroup} with the session + compiled-state
1008
+ * fields the agent needs to act on it: whether it is already active, its
1009
+ * availability, and its catalog description / Unity package dependency.
1010
+ */
1011
+ augmentRecommendation(g, compiledAvailability) {
1012
+ const entry = getGroup(g.id);
1013
+ const avail = compiledAvailability.get(g.id);
771
1014
  return {
772
- content: [
773
- {
774
- type: "text",
775
- text: JSON.stringify({
776
- groups,
777
- activeGroups: this.sessionState.activeGroups(),
778
- note: "Activate a group to add its tools to your ListTools surface; " +
779
- "deactivate to hide them. State is per-session and ephemeral — " +
780
- "it resets to `core`-only when the MCP server restarts. " +
781
- "Compiled-state availability (the `available` field) reflects " +
782
- "whether the Unity domain dependency is compiled in; use " +
783
- "unity_open_mcp_capabilities for the authoritative compiled-state " +
784
- "report.",
785
- _source: "local",
786
- }),
787
- },
788
- ],
789
- isError: false,
1015
+ id: g.id,
1016
+ reason: g.reason,
1017
+ matchedTags: g.matchedTags,
1018
+ ...(g.fromMutationSignal ? { fromMutationSignal: true } : {}),
1019
+ description: entry?.description ?? null,
1020
+ alreadyActive: this.sessionState.isGroupActive(g.id),
1021
+ available: avail?.available ?? null,
1022
+ availableReason: avail?.reason ?? null,
1023
+ unityPackage: entry?.unityPackage ?? null,
790
1024
  };
791
1025
  }
792
1026
  /**
@@ -899,23 +1133,10 @@ export class ToolRouter {
899
1133
  return out;
900
1134
  }
901
1135
  manageToolsResult(body) {
902
- return {
903
- content: [
904
- { type: "text", text: JSON.stringify({ ...body, _source: "local" }) },
905
- ],
906
- isError: false,
907
- };
1136
+ return sourceResult(body, "local");
908
1137
  }
909
1138
  manageToolsError(code, message) {
910
- return {
911
- content: [
912
- {
913
- type: "text",
914
- text: JSON.stringify({ error: { code, message }, _source: "local" }),
915
- },
916
- ],
917
- isError: true,
918
- };
1139
+ return sourceResult({ error: { code, message } }, "local", true);
919
1140
  }
920
1141
  // testsuite-tauri phase-3 — bridge_status. Combines the instance-lock
921
1142
  // classifier (the same pure function the LiveClient uses for dead-bridge
@@ -1061,15 +1282,334 @@ export class ToolRouter {
1061
1282
  }
1062
1283
  : { reachable: false },
1063
1284
  nextStep: bridgeStatusNextStep(status),
1064
- _source: "local",
1065
1285
  };
1066
1286
  // bridge_status never reports an error — even a stopped bridge is a
1067
1287
  // successful status read. _source=local because the synthesis happens in
1068
1288
  // the MCP server (no bridge tool endpoint, no batch Unity).
1069
- return {
1070
- content: [{ type: "text", text: JSON.stringify(body) }],
1071
- isError: false,
1072
- };
1289
+ return sourceResult(body, "local");
1290
+ }
1291
+ // ── M31 Plan 3 — Editor fd-exhaustion operator surfaces (local-routed) ──
1292
+ //
1293
+ // restart_editor (T31.3, reactive kill) + resource_pressure (T31.4,
1294
+ // proactive prediction). Both resolve entirely inside the MCP server: they
1295
+ // act on the OS process (kill / lsof / /proc), never on the bridge. The
1296
+ // bridge is the thing that dies on fd-exhaustion, so neither tool may
1297
+ // depend on it for its primary path. restart_editor still consults the
1298
+ // bridge opportunistically for the active-scene-dirty signal — the Editor
1299
+ // is hung, but the HTTP listener might still be up long enough to answer
1300
+ // a read-only status call before the kill.
1301
+ /**
1302
+ * T31.3 — terminate the hung Unity Editor after confirming the
1303
+ * `editor_fd_exhaustion` signature is present in Editor.log. Requires
1304
+ * explicit `confirm: true`. The relaunch half is intentionally deferred
1305
+ * (the Hub owns the interactive-Editor launch recipe); the response tells
1306
+ * the operator/agent to relaunch via the Hub.
1307
+ *
1308
+ * Safety contract (the plan's "explicit confirmation" requirement):
1309
+ * 1. Refuses unless `confirm: true` is passed. A dry-run call (confirm
1310
+ * false or absent) returns the PID + diagnosis it would act on, no
1311
+ * side effect.
1312
+ * 2. Refuses when the fd-exhaustion signature is ABSENT from Editor.log.
1313
+ * Never restart on a plain `dead_bridge` (usually a fixable compile
1314
+ * failure) or a merely offline bridge.
1315
+ * 3. Surfaces unsaved-scene risk when the bridge is still reachable
1316
+ * enough to report dirty scenes. Does NOT block the kill — the Editor
1317
+ * is hung — but makes the risk visible in the response.
1318
+ */
1319
+ async routeRestartEditor(args, live) {
1320
+ const confirm = args.confirm === true;
1321
+ const graceMs = typeof args.kill_grace_ms === "number" &&
1322
+ Number.isInteger(args.kill_grace_ms) &&
1323
+ args.kill_grace_ms >= 0 &&
1324
+ args.kill_grace_ms <= MAX_KILL_WAIT_MS
1325
+ ? args.kill_grace_ms
1326
+ : DEFAULT_KILL_GRACE_MS;
1327
+ // 1. Resolve the fd-exhaustion signature from Editor.log FIRST. This is
1328
+ // the gate: the tool must NEVER restart on a plain dead_bridge / a
1329
+ // fixable compile failure. We reuse the same offline log read +
1330
+ // health-issue extractor as read_compile_errors so the diagnosis is
1331
+ // identical to what the agent already saw.
1332
+ const logPath = resolveEditorLogPath(this.projectPath);
1333
+ const tail = readLogTail(logPath, DEFAULT_LOG_TAIL_BYTES);
1334
+ let signaturePresent = false;
1335
+ let logWarning = null;
1336
+ if (tail.error || !tail.exists) {
1337
+ // Without the log we cannot confirm the signature — refuse for safety.
1338
+ logWarning = tail.error
1339
+ ? `Editor.log unreadable at ${logPath}: ${tail.error}`
1340
+ : `No Editor.log found at ${logPath}.`;
1341
+ }
1342
+ else {
1343
+ const issues = extractProjectHealthIssues(tail.content);
1344
+ signaturePresent = issues.some((i) => i.kind === "editor_fd_exhaustion");
1345
+ if (!signaturePresent) {
1346
+ logWarning =
1347
+ "The editor_fd_exhaustion signature is NOT present in the recent " +
1348
+ "Editor.log tail. The Editor may be slow/stuck for a different " +
1349
+ "reason (a fixable compile failure, a modal, an unresponsive main " +
1350
+ "thread). Re-run unity_open_mcp_read_compile_errors to confirm " +
1351
+ "the diagnosis before killing the Editor.";
1352
+ }
1353
+ }
1354
+ // 2. Resolve the live Unity PID via the process scan (same primitive
1355
+ // bridge_status uses for cold-Safe-Mode detection). The bridge may
1356
+ // already be down (it dies on fd-exhaustion), so we cannot rely on
1357
+ // the instance lock's pid alone.
1358
+ let pid = null;
1359
+ try {
1360
+ const proc = findUnityForProject(this.projectPath);
1361
+ pid = proc ? proc.pid : null;
1362
+ }
1363
+ catch {
1364
+ pid = null;
1365
+ }
1366
+ // 3. Dry-run branch: confirm was false/absent. Return the diagnosis +
1367
+ // the PID the tool WOULD kill, with no side effect. Lets an agent
1368
+ // preview before committing.
1369
+ if (!confirm) {
1370
+ return sourceResult({
1371
+ action: "restart_editor",
1372
+ confirm: false,
1373
+ dryRun: true,
1374
+ signaturePresent,
1375
+ ...(pid !== null ? { wouldKillPid: pid } : {}),
1376
+ ...(logWarning !== null ? { warning: logWarning } : {}),
1377
+ projectPath: this.projectPath,
1378
+ message: "Dry-run preview. Pass confirm: true to actually terminate the " +
1379
+ "hung Unity Editor. Only do so after read_compile_errors " +
1380
+ "confirms an editor_fd_exhaustion issue — killing the Editor " +
1381
+ "can destroy unsaved scene work and in-flight asset imports.",
1382
+ }, "local");
1383
+ }
1384
+ // 4. Confirmed-path refusals. Each guard surfaces a structured code so
1385
+ // an agent can branch on why the kill did not happen.
1386
+ if (logWarning !== null && !signaturePresent) {
1387
+ return sourceResult({
1388
+ error: {
1389
+ code: "restart_signature_absent",
1390
+ message: logWarning,
1391
+ logPath,
1392
+ },
1393
+ }, "local", true);
1394
+ }
1395
+ if (pid === null) {
1396
+ return sourceResult({
1397
+ error: {
1398
+ code: "unity_process_not_found",
1399
+ message: "No live Unity process matches this project's path. The " +
1400
+ "Editor may have already exited, or it was launched without " +
1401
+ "-projectPath (the scanner cannot match a bare editor " +
1402
+ "launch). Relaunch Unity for this project via the Hub.",
1403
+ projectPath: this.projectPath,
1404
+ },
1405
+ }, "local", true);
1406
+ }
1407
+ // 5. Opportunistic active-scene-dirty check. The Editor is hung, but the
1408
+ // bridge HTTP listener might still be up long enough to answer a
1409
+ // read-only status call. If so, surface dirtyScenes[] as a warning so
1410
+ // the operator knows what unsaved work the kill will lose. This does
1411
+ // NOT block the kill — the Editor is hung, saving is not an option.
1412
+ let dirtyScenesWarning = null;
1413
+ try {
1414
+ const liveAvailable = await live.isLiveAvailable();
1415
+ if (liveAvailable) {
1416
+ const dirtyResult = await live.route("unity_open_mcp_scene_get_dirty_summary", {});
1417
+ const dirtyBody = parseResultBody(dirtyResult);
1418
+ if (dirtyBody && Array.isArray(dirtyBody.scenes)) {
1419
+ const dirty = dirtyBody.scenes
1420
+ .filter((s) => s.isDirty === true)
1421
+ .map((s) => ({
1422
+ name: typeof s.name === "string" ? s.name : "",
1423
+ path: typeof s.path === "string" ? s.path : "",
1424
+ isDirty: true,
1425
+ }));
1426
+ if (dirty.length > 0)
1427
+ dirtyScenesWarning = dirty;
1428
+ }
1429
+ }
1430
+ }
1431
+ catch {
1432
+ // The bridge is unreachable (expected on fd-exhaustion). Swallow — the
1433
+ // dirty-scene signal is opportunistic, not load-bearing.
1434
+ }
1435
+ // 6. Kill the Editor.
1436
+ const kill = await killEditorProcess(pid, graceMs);
1437
+ return this.restartEditorKillResponse(pid, graceMs, kill, dirtyScenesWarning);
1438
+ }
1439
+ /** Build the confirmed-kill response from a {@link KillResult}. */
1440
+ restartEditorKillResponse(pid, graceMs, kill, dirtyScenesWarning) {
1441
+ if (kill.terminated) {
1442
+ return sourceResult({
1443
+ action: "restart_editor",
1444
+ confirm: true,
1445
+ killed: true,
1446
+ pid: kill.pid,
1447
+ method: kill.method,
1448
+ elapsedMs: kill.elapsedMs,
1449
+ graceMs,
1450
+ ...(dirtyScenesWarning !== null
1451
+ ? {
1452
+ dirtyScenesWarning,
1453
+ dirtyScenesNote: "These scenes had unsaved changes when the Editor was " +
1454
+ "killed — that work is lost. Saving is not an option when " +
1455
+ "the Editor is hung mid-build; surface this to the operator.",
1456
+ }
1457
+ : {}),
1458
+ nextSteps: [
1459
+ "Editor terminated. Relaunch Unity for this project via the Hub " +
1460
+ "(the MCP server does not own the interactive-Editor launch " +
1461
+ "recipe — the flags the Hub used at original launch are not " +
1462
+ "knowable from here).",
1463
+ "After relaunch, poll unity_open_mcp_bridge_status until it " +
1464
+ "returns status: \"running\" to confirm the bridge reconnected " +
1465
+ "and wrote a fresh instance lock.",
1466
+ "Once running, call unity_open_mcp_resource_pressure to sample " +
1467
+ "the fresh Editor's fd baseline — the leak accumulates across " +
1468
+ "domain reloads, so a fresh process starts back near zero.",
1469
+ ],
1470
+ }, "local");
1471
+ }
1472
+ // Kill failed — the Editor is still alive (or its state is unknown).
1473
+ return sourceResult({
1474
+ action: "restart_editor",
1475
+ confirm: true,
1476
+ killed: false,
1477
+ pid: kill.pid,
1478
+ reason: kill.reason,
1479
+ message: kill.message,
1480
+ graceMs,
1481
+ nextSteps: [
1482
+ "The automated kill did not terminate the Editor. The operator " +
1483
+ "must force-quit Unity manually (Activity Monitor / Task " +
1484
+ "Manager / `kill -9 <pid>`).",
1485
+ kill.reason === "not_found"
1486
+ ? "The PID vanished between the scan and the kill — the Editor " +
1487
+ "may have exited on its own. Re-run unity_open_mcp_bridge_status " +
1488
+ "to confirm state before retrying."
1489
+ : "After a manual force-quit, relaunch Unity via the Hub and " +
1490
+ "poll unity_open_mcp_bridge_status until running.",
1491
+ ],
1492
+ }, "local", true);
1493
+ }
1494
+ /**
1495
+ * T31.4 — sample the live Unity process's file-descriptor usage and report
1496
+ * headroom against Mono's ~1024 fd ceiling (the real trip point for the Bee
1497
+ * build-driver hang). Proactive counterpart to restart_editor: lets an agent
1498
+ * warn the operator to save + restart BEFORE the Editor hangs, while the
1499
+ * bridge is still healthy. The probe runs server-side (lsof / /proc / Handle
1500
+ * Count) and does NOT require the bridge to be reachable — the bridge is
1501
+ * what dies on fd-exhaustion.
1502
+ *
1503
+ * Records the sample in the session-scoped in-memory ring so successive
1504
+ * calls build a trend (monotonic climb = leak in progress). No disk cache.
1505
+ */
1506
+ async routeResourcePressure(args) {
1507
+ // 1. Resolve the PID. An explicit pid arg wins; otherwise scan for the
1508
+ // live Unity process for this project (same primitive bridge_status
1509
+ // uses). The probe must NOT depend on the bridge.
1510
+ let pid = null;
1511
+ if (typeof args.pid === "number" && Number.isInteger(args.pid) && args.pid > 0) {
1512
+ pid = args.pid;
1513
+ }
1514
+ else {
1515
+ try {
1516
+ const proc = findUnityForProject(this.projectPath);
1517
+ pid = proc ? proc.pid : null;
1518
+ }
1519
+ catch {
1520
+ pid = null;
1521
+ }
1522
+ }
1523
+ if (pid === null) {
1524
+ return sourceResult({
1525
+ error: {
1526
+ code: "unity_process_not_found",
1527
+ message: "No live Unity process matches this project's path, and no " +
1528
+ "explicit pid was supplied. resource_pressure samples the OS " +
1529
+ "process directly (it does not depend on the bridge) — open " +
1530
+ "Unity for this project first, or pass an explicit pid.",
1531
+ projectPath: this.projectPath,
1532
+ },
1533
+ }, "local", true);
1534
+ }
1535
+ // 2. Probe + record the sample. A failed probe still records a sample
1536
+ // (count: null) so the trend detector sees the gap and does not
1537
+ // interpolate across it.
1538
+ const probe = countFileDescriptors(pid);
1539
+ const count = probe.count;
1540
+ const headroom = computeFdHeadroom(count, "approximate" in probe ? probe.approximate : false);
1541
+ const ts = Date.now();
1542
+ this.sessionState.recordFdSample({ ts, pid, count });
1543
+ const samples = this.sessionState.fdSamplesSnapshot();
1544
+ const trend = analyzeFdTrend(samples);
1545
+ // 3. Build the response. The launchContextCaveat is always present so an
1546
+ // agent (and the operator) understands the Mono-ceiling-vs-OS-soft-
1547
+ // limit nuance. warningState is non-null only when there is something
1548
+ // to surface (warn/critical/leaking); ok+stable stays silent.
1549
+ const fdMethod = probe.method;
1550
+ const approximate = "approximate" in probe ? probe.approximate : false;
1551
+ const probeReason = "reason" in probe ? probe.reason : null;
1552
+ const probeMessage = "message" in probe ? probe.message : null;
1553
+ const warningState = headroom.state === "warn" || headroom.state === "critical" || trend.state === "leaking"
1554
+ ? {
1555
+ level: headroom.state === "critical"
1556
+ ? "critical"
1557
+ : trend.state === "leaking"
1558
+ ? "leaking"
1559
+ : "warn",
1560
+ message: headroom.state === "critical"
1561
+ ? `Editor fd usage is at ${Math.round(headroom.pressureRatio * 100)}% of ` +
1562
+ `Mono's ${FD_CEILING}-descriptor ceiling — the next domain reload is ` +
1563
+ `likely to trip the Bee build-driver hang. Save scene work and restart ` +
1564
+ `Unity via the Hub now, before the Editor hangs.`
1565
+ : trend.state === "leaking"
1566
+ ? `Editor fd usage is climbing monotonically across samples (leak in ` +
1567
+ `progress): trend delta ${trend.delta} over ${trend.sampleCount} ` +
1568
+ `sample(s). Save scene work and plan a restart before the count ` +
1569
+ `crosses the ${FD_CEILING}-descriptor ceiling.`
1570
+ : `Editor fd usage is at ${Math.round(headroom.pressureRatio * 100)}% of ` +
1571
+ `Mono's ${FD_CEILING}-descriptor ceiling. Monitor the trend; if it ` +
1572
+ `keeps climbing across domain reloads, save scene work and restart ` +
1573
+ `Unity via the Hub before the Editor hangs.`,
1574
+ }
1575
+ : null;
1576
+ return sourceResult({
1577
+ pid,
1578
+ fdCount: count,
1579
+ fdMethod,
1580
+ approximate,
1581
+ ceiling: FD_CEILING,
1582
+ headroom: headroom.headroom,
1583
+ pressureRatio: headroom.pressureRatio,
1584
+ state: headroom.state,
1585
+ reliable: headroom.reliable,
1586
+ trend,
1587
+ samples: samples.map((s) => ({
1588
+ ts: s.ts,
1589
+ pid: s.pid,
1590
+ count: s.count,
1591
+ })),
1592
+ sampleCount: samples.length,
1593
+ launchContextCaveat: LAUNCH_CONTEXT_CAVEAT,
1594
+ ...(probeReason !== null ? { probeReason } : {}),
1595
+ ...(probeMessage !== null ? { probeMessage } : {}),
1596
+ ...(warningState !== null
1597
+ ? {
1598
+ warning: warningState,
1599
+ agentNextSteps: [
1600
+ "Surface this to the operator — the Editor is approaching " +
1601
+ "fd-exhaustion and the bridge (the thing that dies on " +
1602
+ "exhaustion) cannot recover on its own.",
1603
+ "If scene work is unsaved, recommend saving now while the " +
1604
+ "bridge is still healthy.",
1605
+ "When the operator is ready, restart Unity via the Hub. " +
1606
+ "After relaunch, call resource_pressure again to sample " +
1607
+ "the fresh Editor's fd baseline (a fresh process starts " +
1608
+ "back near zero).",
1609
+ ],
1610
+ }
1611
+ : {}),
1612
+ }, "local");
1073
1613
  }
1074
1614
  // ── M26 Plan 2 — Unity Hub control (local-routed) ────────────────
1075
1615
  //
@@ -1081,29 +1621,16 @@ export class ToolRouter {
1081
1621
  // level ops where the project-asset gate does not apply (paths_hint N/A).
1082
1622
  async routeHubListEditors() {
1083
1623
  const editors = this.hubBackend.listInstalledEditors();
1084
- const body = {
1085
- editors,
1086
- count: editors.length,
1087
- _source: "local",
1088
- };
1089
- return {
1090
- content: [{ type: "text", text: JSON.stringify(body) }],
1091
- isError: false,
1092
- };
1624
+ return sourceResult({ editors, count: editors.length }, "local");
1093
1625
  }
1094
1626
  async routeHubAvailableReleases() {
1095
1627
  const result = await this.hubBackend.fetchAvailableReleases();
1096
- const body = {
1628
+ return sourceResult({
1097
1629
  entries: result.entries,
1098
1630
  count: result.entries.length,
1099
1631
  stale: result.stale,
1100
1632
  fetchedAt: result.fetchedAt,
1101
- _source: "local",
1102
- };
1103
- return {
1104
- content: [{ type: "text", text: JSON.stringify(body) }],
1105
- isError: false,
1106
- };
1633
+ }, "local");
1107
1634
  }
1108
1635
  async routeHubInstallEditor(args) {
1109
1636
  const version = typeof args.version === "string" ? args.version : "";
@@ -1164,16 +1691,7 @@ export class ToolRouter {
1164
1691
  }
1165
1692
  async routeHubGetInstallPath() {
1166
1693
  const res = this.hubBackend.getInstallPath();
1167
- const body = {
1168
- path: res.path,
1169
- source: res.source,
1170
- error: res.error,
1171
- _source: "local",
1172
- };
1173
- return {
1174
- content: [{ type: "text", text: JSON.stringify(body) }],
1175
- isError: res.error !== null,
1176
- };
1694
+ return sourceResult({ path: res.path, source: res.source, error: res.error }, "local", res.error !== null);
1177
1695
  }
1178
1696
  async routeHubSetInstallPath(args) {
1179
1697
  const path = typeof args.path === "string" ? args.path : "";
@@ -1200,19 +1718,24 @@ export class ToolRouter {
1200
1718
  const wantPaging = typeof args.page_size === "number" && args.page_size > 0;
1201
1719
  const liveAvailable = await live.isLiveAvailable();
1202
1720
  if (liveAvailable) {
1203
- console.error("[unity-open-mcp] Route: find_references -> live");
1721
+ logRoute("[unity-open-mcp] Route: find_references -> live");
1204
1722
  // The live bridge only honors max_results (no detail/per-file/threshold).
1205
1723
  // Ask for the full set when paging so the cursor can walk it; otherwise
1206
- // honor the legacy max_results cap.
1724
+ // honor the legacy max_results cap. The 0 here is the server-internal
1725
+ // "unlimited" sentinel (documented in the find-references schema); callers
1726
+ // never pass it — the schema declares minimum: 1 for caller-facing use.
1207
1727
  const liveArgs = {
1208
1728
  ...args,
1209
1729
  max_results: wantPaging ? 0 : (typeof args.max_results === "number" ? args.max_results : 100),
1210
1730
  };
1211
1731
  const result = await live.route("unity_open_mcp_find_references", liveArgs);
1212
- const folded = foldFindReferencesLive(result, profile, wantPaging, args);
1213
- return injectRouteMeta(folded, { route: "live" });
1732
+ // M31-optimizations Plan 1 / H2 — fold + tag _source=live + stamp _route
1733
+ // in ONE parse + ONE stringify. Previously this was three cycles:
1734
+ // foldFindReferencesLive → tagSource → injectRouteMeta. T6.1's _source
1735
+ // contract is preserved (clients switching on _source still see "live").
1736
+ return transformLiveResult(result, "live", { route: "live" }, (body) => foldFindReferencesLiveBody(body, profile, wantPaging, args));
1214
1737
  }
1215
- console.error("[unity-open-mcp] Route: find_references -> offline (live bridge unavailable)");
1738
+ logRoute("[unity-open-mcp] Route: find_references -> offline (live bridge unavailable)");
1216
1739
  const assetPath = typeof args.asset_path === "string" ? args.asset_path : undefined;
1217
1740
  const guid = typeof args.guid === "string" ? args.guid : undefined;
1218
1741
  if (!assetPath && !guid) {
@@ -1237,6 +1760,8 @@ export class ToolRouter {
1237
1760
  guid,
1238
1761
  detail,
1239
1762
  // When paging, fetch the full set; otherwise honor the legacy cap.
1763
+ // 0 is the server-internal "unlimited" sentinel (see find-references
1764
+ // schema description); the schema's caller-facing minimum is 1.
1240
1765
  maxResults: wantPaging ? 0 : (typeof args.max_results === "number" ? args.max_results : 100),
1241
1766
  maxPerFile: typeof args.max_per_file === "number" ? args.max_per_file : 5,
1242
1767
  patternThreshold: typeof args.pattern_threshold === "number" ? args.pattern_threshold : 0,
@@ -1247,12 +1772,7 @@ export class ToolRouter {
1247
1772
  const withPaging = wantPaging
1248
1773
  ? pageFindReferencesResult(result, args.page_size, typeof args.cursor === "string" ? args.cursor : undefined)
1249
1774
  : result;
1250
- return {
1251
- content: [
1252
- { type: "text", text: JSON.stringify({ ...withPaging, _source: "offline" }) },
1253
- ],
1254
- isError: false,
1255
- };
1775
+ return sourceResult(withPaging, "offline");
1256
1776
  }
1257
1777
  catch (err) {
1258
1778
  const message = err instanceof Error ? err.message : String(err);
@@ -1301,7 +1821,7 @@ export class ToolRouter {
1301
1821
  // offline path even if the bridge is up — the live DependenciesTool has no
1302
1822
  // transitive-closure surface yet.
1303
1823
  if (!includeImpact && liveAvailable) {
1304
- console.error("[unity-open-mcp] Route: dependencies -> live");
1824
+ logRoute("[unity-open-mcp] Route: dependencies -> live");
1305
1825
  // The live tool honors asset_path/guid/detail/max_results only.
1306
1826
  const liveArgs = {
1307
1827
  asset_path: assetPath,
@@ -1310,9 +1830,12 @@ export class ToolRouter {
1310
1830
  max_results: typeof args.max_results === "number" ? args.max_results : 100,
1311
1831
  };
1312
1832
  const result = await live.route("unity_open_mcp_dependencies", liveArgs);
1313
- return injectRouteMeta(result, { route: "live" });
1833
+ // M31-optimizations Plan 1 / H2 — tag _source=live + stamp _route in ONE
1834
+ // parse + ONE stringify. Previously this was two cycles:
1835
+ // tagSource → injectRouteMeta. T6.1's _source=live contract preserved.
1836
+ return transformLiveResult(result, "live", { route: "live" });
1314
1837
  }
1315
- console.error(includeImpact && liveAvailable
1838
+ logRoute(includeImpact && liveAvailable
1316
1839
  ? "[unity-open-mcp] Route: dependencies -> offline (include_impact is offline-only)"
1317
1840
  : "[unity-open-mcp] Route: dependencies -> offline (live bridge unavailable)");
1318
1841
  try {
@@ -1355,28 +1878,42 @@ export class ToolRouter {
1355
1878
  // Forward to live/batch exactly as the generic path would. The bridge
1356
1879
  // ignores the unknown profile/page_size/cursor keys (JsonBody substring-
1357
1880
  // searches only for keys it asks for), so they pass through harmlessly.
1881
+ // M31-optimizations Plan 1 / H2 — defer the _route stamp to the single-
1882
+ // parse fold below (saves one parse+stringify per call vs. the previous
1883
+ // injectRouteMeta → parseResultBody → withResultBody chain).
1358
1884
  const canBatch = this.batch.isBatchTool(toolName);
1359
1885
  let raw;
1886
+ let routeMeta;
1360
1887
  if (!canBatch) {
1361
1888
  raw = await live.route(toolName, args);
1362
- raw = injectRouteMeta(raw, { route: "live" });
1889
+ routeMeta = { route: "live" };
1363
1890
  }
1364
1891
  else {
1365
1892
  const liveAvailable = await live.isLiveAvailable();
1366
1893
  if (liveAvailable) {
1367
1894
  raw = await live.route(toolName, args);
1368
- raw = injectRouteMeta(raw, { route: "live" });
1895
+ routeMeta = { route: "live" };
1369
1896
  }
1370
1897
  else {
1371
1898
  raw = await this.batch.route(toolName, args);
1372
- raw = injectRouteMeta(raw, { route: "batch", fallbackReason: "live_unavailable" });
1899
+ routeMeta = { route: "batch", fallbackReason: "live_unavailable" };
1373
1900
  }
1374
1901
  }
1375
1902
  const body = parseResultBody(raw);
1376
- if (body === null)
1377
- return raw;
1378
- if (body.error)
1379
- return raw;
1903
+ if (body === null) {
1904
+ // Body not parseable — fall back to the legacy injectRouteMeta path so
1905
+ // _route is still stamped (matches pre-change behavior on this edge).
1906
+ return injectRouteMeta(raw, routeMeta);
1907
+ }
1908
+ if (body.error) {
1909
+ return injectRouteMeta(raw, routeMeta);
1910
+ }
1911
+ // Stamp _route on the parsed body BEFORE folding so the key order matches
1912
+ // the pre-change chain (injectRouteMeta ran first, then foldVerifyResult
1913
+ // spread its result on top). foldVerifyResult's spreads (`...rest` /
1914
+ // `...result`) carry `_route` through unchanged, preserving byte-identical
1915
+ // output. Single stringify via withResultBody below.
1916
+ body._route = routeMeta;
1380
1917
  const folded = foldVerifyResult(body, toolName, profile, { page_size: pageSize, cursor });
1381
1918
  return withResultBody(raw, folded);
1382
1919
  }
@@ -1394,6 +1931,15 @@ export class ToolRouter {
1394
1931
  delete bridgeArgs.page_size;
1395
1932
  delete bridgeArgs.cursor;
1396
1933
  bridgeArgs.detail = detail;
1934
+ // M3 — when paging, request the full hierarchy from the bridge. The bridge
1935
+ // clamps max_nodes to >= 1 (ScenesTools.cs:387), so 0 is NOT an unlimited
1936
+ // sentinel there; without this override the default 200 would cap the
1937
+ // flattened stream and paging could never walk past node 200 even once the
1938
+ // field path is fixed. Use a large explicit cap so paging can walk the
1939
+ // whole tree; applyPaging enforces the per-page size.
1940
+ if (wantPaging) {
1941
+ bridgeArgs.max_nodes = SCENE_PAGING_MAX_NODES;
1942
+ }
1397
1943
  const canBatch = this.batch.isBatchTool("unity_open_mcp_scene_get_data");
1398
1944
  let raw;
1399
1945
  if (!canBatch) {
@@ -1436,17 +1982,51 @@ function pageSceneNodes(body, pageSize, cursor) {
1436
1982
  const { page, block } = applyPaging(flat, "scene_get_data", { page_size: pageSize, cursor });
1437
1983
  // Preserve scene-level metadata; replace the structural root/hierarchy fields
1438
1984
  // with the flat paged node list + a note explaining the page shape.
1439
- const { roots, rootGameObjects, nodes, truncated, pagination: _existing, ...meta } = body;
1985
+ // M3 — the bridge nests the hierarchy under `body.scene` (ScenesTools.cs:
1986
+ // 393-417 emits `{"status":"ok","scene":{...,"roots":[...],"truncated":N}}`),
1987
+ // so the structural fields live on `body.scene`, not `body`. The previous
1988
+ // destructure looked at the top level and silently dropped the bridge's
1989
+ // `truncated` count; we now pull it from `body.scene` and re-attach it on
1990
+ // the page so callers can tell paging-truncated (resumable via next_cursor)
1991
+ // from bridge-truncated (the source cap was hit).
1992
+ //
1993
+ // B-N20 — the previous rewrite built a fresh `{status, scene: {...}}` object,
1994
+ // silently discarding every OTHER top-level field. The most important of
1995
+ // those is `_route` (stamped at :2409/2414/2417 to signal live vs batch
1996
+ // fallback), which docs/api/routing-lifecycle.md documents as the agent's
1997
+ // data-origin signal: a paging agent would lose the live-vs-batch-fallback
1998
+ // indication whenever `page_size` is supplied, while the unpaged response
1999
+ // still carries it. Spread the rest of `body` (everything except `scene`)
2000
+ // so the page matches the unpaged response's top-level shape.
2001
+ const scene = (body.scene && typeof body.scene === "object")
2002
+ ? body.scene
2003
+ : {};
2004
+ const { roots, rootGameObjects, nodes, truncated, moreHidden, pagination: _existing, ...sceneMeta } = scene;
1440
2005
  void roots;
1441
2006
  void rootGameObjects;
1442
2007
  void nodes;
1443
2008
  void truncated;
2009
+ void moreHidden;
1444
2010
  void _existing;
1445
- return attachPagination({
1446
- ...meta,
1447
- nodes: page,
1448
- pagingNote: "page_size returns a flattened node stream; re-read without page_size for the structural root/hierarchy view",
1449
- }, block);
2011
+ // Pull the top-level meta (everything except `scene`, which we rebuild).
2012
+ const { scene: _s, ...topMeta } = body;
2013
+ void _s;
2014
+ const result = {
2015
+ ...topMeta,
2016
+ status: body.status ?? "ok",
2017
+ scene: {
2018
+ ...sceneMeta,
2019
+ nodes: page,
2020
+ pagingNote: "page_size returns a flattened node stream; re-read without page_size for the structural root/hierarchy view",
2021
+ },
2022
+ };
2023
+ // Carry the bridge's source-side truncation count through to the page so an
2024
+ // agent can distinguish "more pages" (pagination.truncated) from "the bridge
2025
+ // capped the hierarchy" (scene.truncated). Both can be non-zero at once.
2026
+ if (typeof truncated === "number" && truncated > 0) {
2027
+ result.scene.truncated = truncated;
2028
+ }
2029
+ return attachPagination(result, block);
1450
2030
  }
1451
2031
  /**
1452
2032
  * Flatten the scene body into a node stream for paging. Handles both the
@@ -1466,13 +2046,27 @@ function flattenSceneBody(body) {
1466
2046
  walk(child);
1467
2047
  }
1468
2048
  };
2049
+ // M3 — the bridge nests everything one level down under `body.scene`
2050
+ // (`{"status":"ok","scene":{...,"roots":[...]}}`, ScenesTools.cs:393-417).
2051
+ // The previous code read `body.roots` / `body.rootGameObjects` directly, so
2052
+ // `rootField` was always undefined and paging returned an empty node list
2053
+ // while claiming completeness. Read from `body.scene` first, then fall back
2054
+ // to the top level for any caller that hands us a pre-unwrapped body.
2055
+ const scene = (body.scene && typeof body.scene === "object")
2056
+ ? body.scene
2057
+ : body;
1469
2058
  // The bridge emits `roots` (summary) or `rootGameObjects` (normal/verbose);
1470
2059
  // accept either.
1471
- const rootField = Array.isArray(body.roots) ? body.roots : body.rootGameObjects;
2060
+ const rootField = Array.isArray(scene.roots) ? scene.roots : scene.rootGameObjects;
1472
2061
  if (Array.isArray(rootField)) {
1473
2062
  for (const root of rootField)
1474
2063
  walk(root);
1475
2064
  }
1476
2065
  return out;
1477
2066
  }
2067
+ // M3 — large explicit cap forwarded to the bridge when paging so the
2068
+ // flattened stream is not truncated at the default 200 before paging even
2069
+ // starts. applyPaging enforces the per-page size; this only lifts the
2070
+ // source-side ceiling.
2071
+ const SCENE_PAGING_MAX_NODES = 100_000;
1478
2072
  //# sourceMappingURL=tool-router.js.map