ue-mcp 1.2.3 → 1.3.0

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 (255) hide show
  1. package/README.md +4 -3
  2. package/dist/action-class.js +56 -3
  3. package/dist/action-class.js.map +1 -1
  4. package/dist/bridge-timeouts.d.ts +64 -0
  5. package/dist/bridge-timeouts.js +118 -0
  6. package/dist/bridge-timeouts.js.map +1 -0
  7. package/dist/bridge.js +10 -2
  8. package/dist/bridge.js.map +1 -1
  9. package/dist/editor-control.d.ts +72 -5
  10. package/dist/editor-control.js +164 -140
  11. package/dist/editor-control.js.map +1 -1
  12. package/dist/editor-target.d.ts +55 -1
  13. package/dist/editor-target.js +107 -10
  14. package/dist/editor-target.js.map +1 -1
  15. package/dist/engine-observer.d.ts +59 -5
  16. package/dist/engine-observer.js +249 -29
  17. package/dist/engine-observer.js.map +1 -1
  18. package/dist/engine-root.d.ts +91 -0
  19. package/dist/engine-root.js +448 -0
  20. package/dist/engine-root.js.map +1 -0
  21. package/dist/epic-enrich.js +16 -1
  22. package/dist/epic-enrich.js.map +1 -1
  23. package/dist/feedback-cli.js +4 -0
  24. package/dist/feedback-cli.js.map +1 -1
  25. package/dist/feedback-deferred.d.ts +9 -0
  26. package/dist/feedback-deferred.js +2 -0
  27. package/dist/feedback-deferred.js.map +1 -1
  28. package/dist/feedback-fallback.d.ts +99 -0
  29. package/dist/feedback-fallback.js +173 -0
  30. package/dist/feedback-fallback.js.map +1 -0
  31. package/dist/flow/write-methods.js +20 -0
  32. package/dist/flow/write-methods.js.map +1 -1
  33. package/dist/index.js +41 -2
  34. package/dist/index.js.map +1 -1
  35. package/dist/lean-context.js +8 -3
  36. package/dist/lean-context.js.map +1 -1
  37. package/dist/locking.js +11 -2
  38. package/dist/locking.js.map +1 -1
  39. package/dist/plugin/loader.d.ts +4 -0
  40. package/dist/plugin/loader.js +22 -8
  41. package/dist/plugin/loader.js.map +1 -1
  42. package/dist/plugin/manifest.d.ts +72 -52
  43. package/dist/plugin/manifest.js +118 -21
  44. package/dist/plugin/manifest.js.map +1 -1
  45. package/dist/plugin-cli.js +16 -3
  46. package/dist/plugin-cli.js.map +1 -1
  47. package/dist/project.d.ts +11 -0
  48. package/dist/project.js +23 -2
  49. package/dist/project.js.map +1 -1
  50. package/dist/python-gate.d.ts +95 -0
  51. package/dist/python-gate.js +175 -0
  52. package/dist/python-gate.js.map +1 -0
  53. package/dist/tool-counts.json +16 -16
  54. package/dist/tools/animation.js +288 -24
  55. package/dist/tools/animation.js.map +1 -1
  56. package/dist/tools/asset.js +79 -14
  57. package/dist/tools/asset.js.map +1 -1
  58. package/dist/tools/audio.js +59 -5
  59. package/dist/tools/audio.js.map +1 -1
  60. package/dist/tools/blueprint.js +29 -12
  61. package/dist/tools/blueprint.js.map +1 -1
  62. package/dist/tools/chooser.js +4 -1
  63. package/dist/tools/chooser.js.map +1 -1
  64. package/dist/tools/editor.js +81 -43
  65. package/dist/tools/editor.js.map +1 -1
  66. package/dist/tools/feedback.js +214 -48
  67. package/dist/tools/feedback.js.map +1 -1
  68. package/dist/tools/foliage.js +27 -1
  69. package/dist/tools/foliage.js.map +1 -1
  70. package/dist/tools/gameplay.js +38 -11
  71. package/dist/tools/gameplay.js.map +1 -1
  72. package/dist/tools/gas.js +17 -5
  73. package/dist/tools/gas.js.map +1 -1
  74. package/dist/tools/landscape.js +22 -7
  75. package/dist/tools/landscape.js.map +1 -1
  76. package/dist/tools/level.js +322 -51
  77. package/dist/tools/level.js.map +1 -1
  78. package/dist/tools/material.js +10 -4
  79. package/dist/tools/material.js.map +1 -1
  80. package/dist/tools/niagara.js +3 -2
  81. package/dist/tools/niagara.js.map +1 -1
  82. package/dist/tools/pcg.js +6 -5
  83. package/dist/tools/pcg.js.map +1 -1
  84. package/dist/tools/plugins.js +2 -0
  85. package/dist/tools/plugins.js.map +1 -1
  86. package/dist/tools/project.js +47 -20
  87. package/dist/tools/project.js.map +1 -1
  88. package/dist/types.d.ts +24 -0
  89. package/dist/types.js +46 -3
  90. package/dist/types.js.map +1 -1
  91. package/dist/ue-mcp.default.yml +493 -125
  92. package/package.json +2 -2
  93. package/plugin/ue_mcp_bridge/NATIVE_RUNTIME_VISIBILITY.md +53 -0
  94. package/plugin/ue_mcp_bridge/NATIVE_STATIC_MESH_USAGE_PROGRESS.md +115 -0
  95. package/plugin/ue_mcp_bridge/README_MassHandlers.md +97 -0
  96. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/BridgeServer.cpp +14 -0
  97. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.cpp +21 -4
  98. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.h +9 -0
  99. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerJsonProperty.h +395 -69
  100. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.cpp +79 -3
  101. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.h +25 -0
  102. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_ControlRig.cpp +3 -3
  103. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_ControlRigSequencer.cpp +3061 -0
  104. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_IKRetargeterAuthoring.cpp +961 -0
  105. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_IKRigAuthoring.cpp +900 -0
  106. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Pose.cpp +769 -0
  107. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Sequence.cpp +44 -3
  108. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_SkeletalLive.cpp +217 -11
  109. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_StateMachine.cpp +551 -24
  110. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Validation.cpp +735 -0
  111. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.cpp +352 -73
  112. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.h +8 -0
  113. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkProperties.cpp +1 -1
  114. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkRead.cpp +503 -0
  115. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkRead.h +21 -0
  116. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkUpsert.cpp +2 -2
  117. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Enum.cpp +2 -2
  118. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Geometry.cpp +902 -0
  119. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Geometry.h +33 -0
  120. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Import.cpp +478 -134
  121. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Mesh.cpp +5 -5
  122. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_MeshBoolean.cpp +933 -0
  123. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_MeshBoolean.h +35 -0
  124. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Redirectors.cpp +478 -0
  125. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_RenderTarget.cpp +1 -1
  126. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Sockets.cpp +4 -4
  127. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Struct.cpp +2 -2
  128. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Subobject.cpp +319 -0
  129. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AudioHandlers_SoundCue.cpp +3 -3
  130. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.cpp +482 -35
  131. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.h +10 -0
  132. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Collision.cpp +502 -0
  133. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Collision.h +43 -0
  134. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Functions.cpp +89 -7
  135. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Graph.cpp +17 -51
  136. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Internal.h +107 -0
  137. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Properties.cpp +10 -10
  138. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Search.cpp +648 -0
  139. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DemoHandlers.cpp +5 -1
  140. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DiffHandlers.cpp +252 -1
  141. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DiffHandlers.h +10 -2
  142. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.cpp +252 -41
  143. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.h +4 -0
  144. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_Build.cpp +250 -27
  145. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_PIE.cpp +303 -125
  146. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_PIERuntime.cpp +73 -50
  147. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_RuntimeVisibility.cpp +757 -0
  148. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.cpp +11 -2
  149. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.h +3 -0
  150. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers_Batch.cpp +419 -0
  151. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.cpp +39 -161
  152. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.h +66 -1
  153. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers_BTAuthoring.cpp +1323 -0
  154. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers_BehaviorTree.cpp +1211 -0
  155. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.cpp +2 -0
  156. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.h +60 -0
  157. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers_Runtime.cpp +363 -12
  158. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/HandlerEditorState.h +84 -0
  159. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.cpp +1288 -36
  160. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.h +3 -0
  161. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers_Sculpt.cpp +41 -16
  162. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.cpp +959 -213
  163. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.h +66 -0
  164. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_BatchWrite.cpp +1571 -0
  165. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Convert.cpp +316 -0
  166. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Inspection.cpp +280 -0
  167. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_InstanceProjection.cpp +666 -0
  168. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_InstanceProjection_Internal.h +63 -0
  169. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Lights.cpp +43 -12
  170. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_MultiLevel.cpp +13 -47
  171. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_PostProcess.cpp +527 -0
  172. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Query.cpp +1169 -0
  173. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Refresh.cpp +723 -0
  174. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Save.cpp +325 -0
  175. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Spatial.cpp +360 -0
  176. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Trace.cpp +178 -58
  177. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Transient.cpp +337 -0
  178. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Volumes.cpp +25 -12
  179. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_WorldPartition.cpp +10 -9
  180. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_WorldPartitionSettings.cpp +686 -0
  181. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MassHandlers.cpp +467 -0
  182. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MassHandlers.h +22 -0
  183. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.cpp +452 -175
  184. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.h +5 -0
  185. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers_Build.cpp +597 -0
  186. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NiagaraHandlers.cpp +17 -15
  187. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PCGHandlers.cpp +38 -168
  188. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PhysicsHandlers.cpp +39 -30
  189. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.cpp +392 -78
  190. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.h +2 -0
  191. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers_Internal.h +83 -0
  192. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SkeletalMeshHandlers.cpp +200 -0
  193. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SkeletalMeshHandlers.h +15 -0
  194. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.cpp +19 -12
  195. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/StateTreeHandlers.cpp +31 -1
  196. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.cpp +307 -69
  197. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.h +84 -0
  198. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers_Extraction.cpp +8 -41
  199. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers_Properties.cpp +33 -52
  200. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/ActorSelectorTests.cpp +344 -0
  201. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AnimationControlRigTimelineTests.cpp +60 -0
  202. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AnimationPoseTests.cpp +115 -0
  203. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetBulkReadTests.cpp +177 -0
  204. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetDeleteGuardTests.cpp +276 -0
  205. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetPathResolutionTests.cpp +243 -0
  206. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetPropertyPersistTests.cpp +213 -0
  207. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetSubobjectTests.cpp +235 -0
  208. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AutomationRunnerTests.cpp +72 -0
  209. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BehaviorTreeAuthoringTests.cpp +526 -0
  210. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BehaviorTreeNodeTests.cpp +334 -0
  211. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BlueprintHandlerSurfaceTests.cpp +362 -0
  212. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BridgeProtocolTests.cpp +14 -0
  213. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/CollisionQueryTests.cpp +288 -0
  214. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/DataTableRowWriteTests.cpp +453 -0
  215. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/EditorFunctionCallTests.cpp +223 -0
  216. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/FoliageBatchTests.cpp +147 -0
  217. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/GameThreadGateTests.cpp +82 -0
  218. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/GasLiveAttributeTests.cpp +183 -0
  219. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LandscapeSampleTests.cpp +119 -0
  220. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelBatchWriteTests.cpp +176 -0
  221. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelComponentTreeInstanceCountTests.cpp +189 -0
  222. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelConvertBrushesTests.cpp +100 -0
  223. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelInstanceProjectionTests.cpp +265 -0
  224. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelPostProcessOverrideTests.cpp +258 -0
  225. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelQueryComponentsTests.cpp +195 -0
  226. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelRefreshTests.cpp +142 -0
  227. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelSaveReportTests.cpp +125 -0
  228. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelScriptHandlersTests.cpp +42 -0
  229. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelStaticMeshUsageTests.cpp +412 -0
  230. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelTraceWorldScopeTests.cpp +133 -0
  231. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelTransientActorTests.cpp +205 -0
  232. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelWorldPartitionSettingsTests.cpp +168 -0
  233. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MCPInstancedStructPathTestTypes.h +51 -0
  234. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MCPInstancedStructPathTests.cpp +379 -0
  235. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MaterialBuildTests.cpp +238 -0
  236. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MeshBooleanTests.cpp +170 -0
  237. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MeshGeometryTests.cpp +116 -0
  238. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/PackageSaveExtensionTests.cpp +161 -0
  239. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/PackageWriteGuardTests.cpp +253 -0
  240. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/RuntimeVisibilityTests.cpp +143 -0
  241. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SequencerHandlerTests.cpp +660 -0
  242. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SequencerScrubTests.cpp +50 -0
  243. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SkeletonDiffTests.cpp +685 -0
  244. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/WidgetBlueprintResolveTests.cpp +145 -0
  245. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/UE_MCP_Bridge.cpp +80 -0
  246. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerFunctionCall.h +509 -0
  247. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerQuery.h +407 -0
  248. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerUtils.h +1008 -77
  249. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/UE_MCP_Bridge.Build.cs +87 -0
  250. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Private/MCPEngineStatus.cpp +152 -14
  251. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Private/Tests/MCPEngineStatusTests.cpp +65 -0
  252. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Public/MCPEngineStatus.h +32 -1
  253. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/UE_MCP_BridgeStatus.Build.cs +2 -0
  254. package/skills/ue-mcp-animation/SKILL.md +154 -0
  255. package/skills/ue-mcp-blueprint/SKILL.md +71 -0
@@ -0,0 +1,407 @@
1
+ #pragma once
2
+
3
+ // Shared query machinery: typed property reads, dotted path resolution, and
4
+ // server-side predicates.
5
+ //
6
+ // Two handlers need exactly this and for the same reason. level
7
+ // (query_components) and asset(bulk_read_properties) both exist because a
8
+ // level-wide or library-wide question used to mean shipping every candidate to
9
+ // the client and filtering it there. Filtering in the editor needs a predicate
10
+ // language, and one predicate language is better than two that drift.
11
+ //
12
+ // It lives in a header rather than in either .cpp because the module is a
13
+ // unity build: a file-local helper copied into a second translation unit is a
14
+ // redefinition (C2084) as soon as UBT groups the two files, and the grouping is
15
+ // not stable across machines.
16
+
17
+ #include "CoreMinimal.h"
18
+ #include "Dom/JsonObject.h"
19
+ #include "Dom/JsonValue.h"
20
+ #include "UObject/EnumProperty.h"
21
+ #include "UObject/UnrealType.h"
22
+
23
+ namespace MCPQuery
24
+ {
25
+ /** "EComponentMobility::Movable" and "EComponentMobility.Movable" both
26
+ * reduce to "Movable". UEnum renders a namespaced enum either way
27
+ * depending on how it was declared, and a caller comparing against
28
+ * "Movable" should not have to know which. */
29
+ inline FString ShortEnumName(const FString& Raw)
30
+ {
31
+ int32 Index = INDEX_NONE;
32
+ if (Raw.FindLastChar(TEXT(':'), Index) || Raw.FindLastChar(TEXT('.'), Index))
33
+ {
34
+ return Raw.RightChop(Index + 1);
35
+ }
36
+ return Raw;
37
+ }
38
+
39
+ /**
40
+ * A UPROPERTY as typed JSON rather than as exported text.
41
+ *
42
+ * Typed matters: a predicate like `CullDistance.Max > 0` has to compare
43
+ * numbers, and the string "0.000000" is not a number. Anything without a
44
+ * natural JSON shape falls back to its exported text, so a value is never
45
+ * simply lost.
46
+ */
47
+ inline TSharedPtr<FJsonValue> PropertyToJson(FProperty* Property, const void* ValuePtr)
48
+ {
49
+ if (!Property || !ValuePtr)
50
+ {
51
+ return MakeShared<FJsonValueNull>();
52
+ }
53
+
54
+ if (const FBoolProperty* BoolProp = CastField<FBoolProperty>(Property))
55
+ {
56
+ return MakeShared<FJsonValueBoolean>(BoolProp->GetPropertyValue(ValuePtr));
57
+ }
58
+ if (const FEnumProperty* EnumProp = CastField<FEnumProperty>(Property))
59
+ {
60
+ const int64 Value = EnumProp->GetUnderlyingProperty()->GetSignedIntPropertyValue(ValuePtr);
61
+ UEnum* Enum = EnumProp->GetEnum();
62
+ return MakeShared<FJsonValueString>(
63
+ Enum ? ShortEnumName(Enum->GetNameStringByValue(Value)) : LexToString(Value));
64
+ }
65
+ if (const FNumericProperty* NumericProp = CastField<FNumericProperty>(Property))
66
+ {
67
+ if (UEnum* Enum = NumericProp->GetIntPropertyEnum())
68
+ {
69
+ const int64 Value = NumericProp->GetSignedIntPropertyValue(ValuePtr);
70
+ return MakeShared<FJsonValueString>(ShortEnumName(Enum->GetNameStringByValue(Value)));
71
+ }
72
+ if (NumericProp->IsFloatingPoint())
73
+ {
74
+ return MakeShared<FJsonValueNumber>(NumericProp->GetFloatingPointPropertyValue(ValuePtr));
75
+ }
76
+ return MakeShared<FJsonValueNumber>(
77
+ static_cast<double>(NumericProp->GetSignedIntPropertyValue(ValuePtr)));
78
+ }
79
+ if (const FStrProperty* StrProp = CastField<FStrProperty>(Property))
80
+ {
81
+ return MakeShared<FJsonValueString>(StrProp->GetPropertyValue(ValuePtr));
82
+ }
83
+ if (const FNameProperty* NameProp = CastField<FNameProperty>(Property))
84
+ {
85
+ return MakeShared<FJsonValueString>(NameProp->GetPropertyValue(ValuePtr).ToString());
86
+ }
87
+ if (const FSoftObjectProperty* SoftProp = CastField<FSoftObjectProperty>(Property))
88
+ {
89
+ const FString Path = SoftProp->GetPropertyValue(ValuePtr).ToString();
90
+ return Path.IsEmpty()
91
+ ? StaticCastSharedRef<FJsonValue>(MakeShared<FJsonValueNull>())
92
+ : StaticCastSharedRef<FJsonValue>(MakeShared<FJsonValueString>(Path));
93
+ }
94
+ if (const FObjectPropertyBase* ObjectProp = CastField<FObjectPropertyBase>(Property))
95
+ {
96
+ UObject* Value = ObjectProp->GetObjectPropertyValue(ValuePtr);
97
+ return Value
98
+ ? StaticCastSharedRef<FJsonValue>(MakeShared<FJsonValueString>(Value->GetPathName()))
99
+ : StaticCastSharedRef<FJsonValue>(MakeShared<FJsonValueNull>());
100
+ }
101
+
102
+ FString Exported;
103
+ Property->ExportText_Direct(Exported, ValuePtr, ValuePtr, nullptr, PPF_None);
104
+ return MakeShared<FJsonValueString>(Exported);
105
+ }
106
+
107
+ /**
108
+ * Resolve a dotted UPROPERTY path such as `CullDistance.Max` on a UObject,
109
+ * walking nested structs. Returns an invalid pointer when any segment does
110
+ * not exist, which is how a caller distinguishes "the property is null"
111
+ * from "this class does not have that property".
112
+ */
113
+ inline TSharedPtr<FJsonValue> ReadDottedProperty(UObject* Object, const FString& Path, FString& OutResolvedType)
114
+ {
115
+ OutResolvedType.Reset();
116
+ if (!Object || Path.IsEmpty())
117
+ {
118
+ return nullptr;
119
+ }
120
+
121
+ TArray<FString> Segments;
122
+ Path.ParseIntoArray(Segments, TEXT("."), true);
123
+
124
+ UStruct* CurrentStruct = Object->GetClass();
125
+ const void* CurrentContainer = Object;
126
+ for (int32 Index = 0; Index < Segments.Num(); ++Index)
127
+ {
128
+ if (!CurrentStruct || !CurrentContainer)
129
+ {
130
+ return nullptr;
131
+ }
132
+ FProperty* Property = CurrentStruct->FindPropertyByName(FName(*Segments[Index]));
133
+ if (!Property)
134
+ {
135
+ return nullptr;
136
+ }
137
+ const void* ValuePtr = Property->ContainerPtrToValuePtr<void>(CurrentContainer);
138
+ if (Index == Segments.Num() - 1)
139
+ {
140
+ OutResolvedType = Property->GetCPPType();
141
+ return PropertyToJson(Property, ValuePtr);
142
+ }
143
+ const FStructProperty* StructProp = CastField<FStructProperty>(Property);
144
+ if (!StructProp)
145
+ {
146
+ // Only structs are walked. Following an object reference would
147
+ // silently read a different asset than the one asked about.
148
+ return nullptr;
149
+ }
150
+ CurrentStruct = StructProp->Struct;
151
+ CurrentContainer = ValuePtr;
152
+ }
153
+ return nullptr;
154
+ }
155
+
156
+ /** Resolve a dotted field path inside an already-built JSON row. Returns an
157
+ * invalid pointer when the path does not exist, which is what the `exists`
158
+ * and `notExists` operators test. */
159
+ inline TSharedPtr<FJsonValue> ResolvePath(const TSharedPtr<FJsonObject>& Row, const FString& Path)
160
+ {
161
+ if (!Row.IsValid() || Path.IsEmpty())
162
+ {
163
+ return nullptr;
164
+ }
165
+
166
+ TArray<FString> Segments;
167
+ Path.ParseIntoArray(Segments, TEXT("."), true);
168
+ TSharedPtr<FJsonObject> Current = Row;
169
+ for (int32 Index = 0; Index < Segments.Num(); ++Index)
170
+ {
171
+ if (!Current.IsValid())
172
+ {
173
+ return nullptr;
174
+ }
175
+ // FJsonObject::Values is not keyed by FString on UE 5.8, so Find(FString)
176
+ // does not resolve. TryGetField takes an FStringView and is the
177
+ // supported lookup regardless of the map's key type.
178
+ const TSharedPtr<FJsonValue> Found = Current->TryGetField(Segments[Index]);
179
+ if (!Found.IsValid())
180
+ {
181
+ return nullptr;
182
+ }
183
+ if (Index == Segments.Num() - 1)
184
+ {
185
+ return Found;
186
+ }
187
+ if (Found->Type != EJson::Object)
188
+ {
189
+ return nullptr;
190
+ }
191
+ Current = Found->AsObject();
192
+ }
193
+ return nullptr;
194
+ }
195
+
196
+ /** One value rendered as the string a group key or a histogram bucket uses. */
197
+ inline FString ValueKey(const TSharedPtr<FJsonValue>& Value)
198
+ {
199
+ if (!Value.IsValid())
200
+ {
201
+ return TEXT("<absent>");
202
+ }
203
+ switch (Value->Type)
204
+ {
205
+ case EJson::Null: return TEXT("<null>");
206
+ case EJson::Boolean: return Value->AsBool() ? TEXT("true") : TEXT("false");
207
+ case EJson::Number: return FString::SanitizeFloat(Value->AsNumber());
208
+ case EJson::String: return Value->AsString();
209
+ default: return TEXT("<complex>");
210
+ }
211
+ }
212
+
213
+ struct FPredicate
214
+ {
215
+ FString Field;
216
+ FString Op;
217
+ TSharedPtr<FJsonValue> Value;
218
+ };
219
+
220
+ inline bool ValuesEqual(const TSharedPtr<FJsonValue>& Left, const TSharedPtr<FJsonValue>& Right)
221
+ {
222
+ if (!Left.IsValid() || !Right.IsValid())
223
+ {
224
+ return false;
225
+ }
226
+ if (Left->Type == EJson::Number && Right->Type == EJson::Number)
227
+ {
228
+ return FMath::IsNearlyEqual(Left->AsNumber(), Right->AsNumber(), UE_KINDA_SMALL_NUMBER);
229
+ }
230
+ if (Left->Type == EJson::Boolean || Right->Type == EJson::Boolean)
231
+ {
232
+ return Left->AsBool() == Right->AsBool();
233
+ }
234
+ // Strings compare case-insensitively. An agent that types "movable"
235
+ // should not silently match nothing, which is the exact shape of the
236
+ // client-side filter bug this machinery replaces.
237
+ return ValueKey(Left).Equals(ValueKey(Right), ESearchCase::IgnoreCase);
238
+ }
239
+
240
+ /** Every operator this vocabulary understands. Anything else is rejected by
241
+ * name rather than evaluated to false. */
242
+ inline bool IsKnownOp(const FString& Op)
243
+ {
244
+ static const TCHAR* const Known[] = {
245
+ TEXT("eq"), TEXT("ne"), TEXT("lt"), TEXT("lte"), TEXT("gt"), TEXT("gte"),
246
+ TEXT("contains"), TEXT("notContains"), TEXT("startsWith"), TEXT("endsWith"),
247
+ TEXT("in"), TEXT("notIn"), TEXT("exists"), TEXT("notExists"),
248
+ TEXT("isNull"), TEXT("isNotNull"), TEXT("isTrue"), TEXT("isFalse"),
249
+ };
250
+ for (const TCHAR* Candidate : Known)
251
+ {
252
+ if (Op.Equals(Candidate, ESearchCase::CaseSensitive))
253
+ {
254
+ return true;
255
+ }
256
+ }
257
+ return false;
258
+ }
259
+
260
+ /** The operator list, for an error message that tells the caller what it
261
+ * could have said instead. */
262
+ inline const TCHAR* KnownOpList()
263
+ {
264
+ return TEXT("eq, ne, lt, lte, gt, gte, contains, notContains, startsWith, endsWith, in, notIn, exists, notExists, isNull, isNotNull, isTrue, isFalse");
265
+ }
266
+
267
+ inline bool Evaluate(const FPredicate& Predicate, const TSharedPtr<FJsonObject>& Row)
268
+ {
269
+ const TSharedPtr<FJsonValue> Actual = ResolvePath(Row, Predicate.Field);
270
+
271
+ if (Predicate.Op == TEXT("exists")) return Actual.IsValid();
272
+ if (Predicate.Op == TEXT("notExists")) return !Actual.IsValid();
273
+ if (Predicate.Op == TEXT("isNull")) return !Actual.IsValid() || Actual->Type == EJson::Null;
274
+ if (Predicate.Op == TEXT("isNotNull")) return Actual.IsValid() && Actual->Type != EJson::Null;
275
+ if (Predicate.Op == TEXT("isTrue")) return Actual.IsValid() && Actual->Type == EJson::Boolean && Actual->AsBool();
276
+ if (Predicate.Op == TEXT("isFalse")) return Actual.IsValid() && Actual->Type == EJson::Boolean && !Actual->AsBool();
277
+
278
+ if (!Actual.IsValid())
279
+ {
280
+ // Every remaining operator compares against a value, and an absent
281
+ // field has none. `notExists` above is how a caller asks for that.
282
+ return false;
283
+ }
284
+
285
+ if (Predicate.Op == TEXT("eq")) return ValuesEqual(Actual, Predicate.Value);
286
+ if (Predicate.Op == TEXT("ne")) return !ValuesEqual(Actual, Predicate.Value);
287
+
288
+ if (Predicate.Op == TEXT("lt") || Predicate.Op == TEXT("lte") ||
289
+ Predicate.Op == TEXT("gt") || Predicate.Op == TEXT("gte"))
290
+ {
291
+ if (Actual->Type != EJson::Number || !Predicate.Value.IsValid() || Predicate.Value->Type != EJson::Number)
292
+ {
293
+ return false;
294
+ }
295
+ const double A = Actual->AsNumber();
296
+ const double B = Predicate.Value->AsNumber();
297
+ if (Predicate.Op == TEXT("lt")) return A < B;
298
+ if (Predicate.Op == TEXT("lte")) return A <= B;
299
+ if (Predicate.Op == TEXT("gt")) return A > B;
300
+ return A >= B;
301
+ }
302
+
303
+ if (Predicate.Op == TEXT("contains") || Predicate.Op == TEXT("notContains") ||
304
+ Predicate.Op == TEXT("startsWith") || Predicate.Op == TEXT("endsWith"))
305
+ {
306
+ const FString Haystack = ValueKey(Actual);
307
+ const FString Needle = ValueKey(Predicate.Value);
308
+ if (Predicate.Op == TEXT("contains")) return Haystack.Contains(Needle, ESearchCase::IgnoreCase);
309
+ if (Predicate.Op == TEXT("notContains")) return !Haystack.Contains(Needle, ESearchCase::IgnoreCase);
310
+ if (Predicate.Op == TEXT("startsWith")) return Haystack.StartsWith(Needle, ESearchCase::IgnoreCase);
311
+ return Haystack.EndsWith(Needle, ESearchCase::IgnoreCase);
312
+ }
313
+
314
+ if (Predicate.Op == TEXT("in") || Predicate.Op == TEXT("notIn"))
315
+ {
316
+ bool bFound = false;
317
+ if (Predicate.Value.IsValid() && Predicate.Value->Type == EJson::Array)
318
+ {
319
+ for (const TSharedPtr<FJsonValue>& Candidate : Predicate.Value->AsArray())
320
+ {
321
+ if (ValuesEqual(Actual, Candidate))
322
+ {
323
+ bFound = true;
324
+ break;
325
+ }
326
+ }
327
+ }
328
+ return Predicate.Op == TEXT("in") ? bFound : !bFound;
329
+ }
330
+
331
+ return false;
332
+ }
333
+
334
+ /**
335
+ * Parse a `where` array. Returns false and fills OutError with a message
336
+ * naming the offending index, so a caller with twenty predicates learns
337
+ * which one is wrong rather than that something is.
338
+ */
339
+ inline bool ParsePredicates(
340
+ const TArray<TSharedPtr<FJsonValue>>* WhereValues,
341
+ int32 MaxPredicates,
342
+ TArray<FPredicate>& OutPredicates,
343
+ FString& OutError)
344
+ {
345
+ OutPredicates.Reset();
346
+ if (!WhereValues)
347
+ {
348
+ return true;
349
+ }
350
+ if (WhereValues->Num() > MaxPredicates)
351
+ {
352
+ OutError = FString::Printf(TEXT("'where' exceeds the maximum of %d predicates"), MaxPredicates);
353
+ return false;
354
+ }
355
+ for (int32 Index = 0; Index < WhereValues->Num(); ++Index)
356
+ {
357
+ const TSharedPtr<FJsonValue>& Entry = (*WhereValues)[Index];
358
+ if (!Entry.IsValid() || Entry->Type != EJson::Object)
359
+ {
360
+ OutError = FString::Printf(TEXT("'where[%d]' must be an object"), Index);
361
+ return false;
362
+ }
363
+ const TSharedPtr<FJsonObject> EntryObject = Entry->AsObject();
364
+ FPredicate Predicate;
365
+ if (!EntryObject->TryGetStringField(TEXT("field"), Predicate.Field) || Predicate.Field.IsEmpty())
366
+ {
367
+ OutError = FString::Printf(TEXT("'where[%d].field' is required"), Index);
368
+ return false;
369
+ }
370
+ Predicate.Op = EntryObject->HasField(TEXT("op"))
371
+ ? EntryObject->GetStringField(TEXT("op"))
372
+ : FString(TEXT("eq"));
373
+ if (!IsKnownOp(Predicate.Op))
374
+ {
375
+ OutError = FString::Printf(
376
+ TEXT("'where[%d].op' is '%s'. Valid: %s"), Index, *Predicate.Op, KnownOpList());
377
+ return false;
378
+ }
379
+ const TSharedPtr<FJsonValue>* Value = EntryObject->Values.Find(TEXT("value"));
380
+ Predicate.Value = Value ? *Value : nullptr;
381
+ OutPredicates.Add(MoveTemp(Predicate));
382
+ }
383
+ return true;
384
+ }
385
+
386
+ /** Run a predicate set over one row. `bAll` is the AND/OR switch. */
387
+ inline bool EvaluateAll(const TArray<FPredicate>& Predicates, const TSharedPtr<FJsonObject>& Row, bool bAll)
388
+ {
389
+ if (Predicates.Num() == 0)
390
+ {
391
+ return true;
392
+ }
393
+ for (const FPredicate& Predicate : Predicates)
394
+ {
395
+ const bool bResult = Evaluate(Predicate, Row);
396
+ if (bAll)
397
+ {
398
+ if (!bResult) return false;
399
+ }
400
+ else if (bResult)
401
+ {
402
+ return true;
403
+ }
404
+ }
405
+ return bAll;
406
+ }
407
+ }