ue-mcp 1.2.4 → 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 (243) 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/lean-context.js +8 -3
  34. package/dist/lean-context.js.map +1 -1
  35. package/dist/locking.js +11 -2
  36. package/dist/locking.js.map +1 -1
  37. package/dist/project.d.ts +11 -0
  38. package/dist/project.js +23 -2
  39. package/dist/project.js.map +1 -1
  40. package/dist/python-gate.d.ts +95 -0
  41. package/dist/python-gate.js +175 -0
  42. package/dist/python-gate.js.map +1 -0
  43. package/dist/tool-counts.json +16 -16
  44. package/dist/tools/animation.js +288 -24
  45. package/dist/tools/animation.js.map +1 -1
  46. package/dist/tools/asset.js +79 -14
  47. package/dist/tools/asset.js.map +1 -1
  48. package/dist/tools/audio.js +59 -5
  49. package/dist/tools/audio.js.map +1 -1
  50. package/dist/tools/blueprint.js +29 -12
  51. package/dist/tools/blueprint.js.map +1 -1
  52. package/dist/tools/chooser.js +4 -1
  53. package/dist/tools/chooser.js.map +1 -1
  54. package/dist/tools/editor.js +81 -43
  55. package/dist/tools/editor.js.map +1 -1
  56. package/dist/tools/feedback.js +214 -48
  57. package/dist/tools/feedback.js.map +1 -1
  58. package/dist/tools/foliage.js +27 -1
  59. package/dist/tools/foliage.js.map +1 -1
  60. package/dist/tools/gameplay.js +38 -11
  61. package/dist/tools/gameplay.js.map +1 -1
  62. package/dist/tools/gas.js +17 -5
  63. package/dist/tools/gas.js.map +1 -1
  64. package/dist/tools/landscape.js +22 -7
  65. package/dist/tools/landscape.js.map +1 -1
  66. package/dist/tools/level.js +322 -51
  67. package/dist/tools/level.js.map +1 -1
  68. package/dist/tools/material.js +10 -4
  69. package/dist/tools/material.js.map +1 -1
  70. package/dist/tools/niagara.js +3 -2
  71. package/dist/tools/niagara.js.map +1 -1
  72. package/dist/tools/pcg.js +6 -5
  73. package/dist/tools/pcg.js.map +1 -1
  74. package/dist/tools/project.js +47 -20
  75. package/dist/tools/project.js.map +1 -1
  76. package/dist/types.d.ts +21 -0
  77. package/dist/types.js +46 -3
  78. package/dist/types.js.map +1 -1
  79. package/dist/ue-mcp.default.yml +493 -125
  80. package/package.json +2 -2
  81. package/plugin/ue_mcp_bridge/NATIVE_RUNTIME_VISIBILITY.md +53 -0
  82. package/plugin/ue_mcp_bridge/NATIVE_STATIC_MESH_USAGE_PROGRESS.md +115 -0
  83. package/plugin/ue_mcp_bridge/README_MassHandlers.md +97 -0
  84. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/BridgeServer.cpp +14 -0
  85. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.cpp +21 -4
  86. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/GameThreadExecutor.h +9 -0
  87. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/HandlerJsonProperty.h +395 -69
  88. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.cpp +79 -3
  89. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers.h +25 -0
  90. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_ControlRig.cpp +3 -3
  91. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_ControlRigSequencer.cpp +3061 -0
  92. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_IKRetargeterAuthoring.cpp +961 -0
  93. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_IKRigAuthoring.cpp +900 -0
  94. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Pose.cpp +769 -0
  95. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Sequence.cpp +44 -3
  96. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_SkeletalLive.cpp +217 -11
  97. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_StateMachine.cpp +551 -24
  98. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AnimationHandlers_Validation.cpp +735 -0
  99. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.cpp +352 -73
  100. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers.h +8 -0
  101. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkProperties.cpp +1 -1
  102. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkRead.cpp +503 -0
  103. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkRead.h +21 -0
  104. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_BulkUpsert.cpp +2 -2
  105. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Enum.cpp +2 -2
  106. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Geometry.cpp +902 -0
  107. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Geometry.h +33 -0
  108. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Import.cpp +478 -134
  109. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Mesh.cpp +5 -5
  110. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_MeshBoolean.cpp +933 -0
  111. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_MeshBoolean.h +35 -0
  112. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Redirectors.cpp +478 -0
  113. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_RenderTarget.cpp +1 -1
  114. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Sockets.cpp +4 -4
  115. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Struct.cpp +2 -2
  116. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AssetHandlers_Subobject.cpp +319 -0
  117. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/AudioHandlers_SoundCue.cpp +3 -3
  118. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.cpp +482 -35
  119. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers.h +10 -0
  120. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Collision.cpp +502 -0
  121. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Collision.h +43 -0
  122. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Functions.cpp +89 -7
  123. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Graph.cpp +17 -51
  124. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Internal.h +107 -0
  125. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Properties.cpp +10 -10
  126. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/BlueprintHandlers_Search.cpp +648 -0
  127. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DemoHandlers.cpp +5 -1
  128. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DiffHandlers.cpp +252 -1
  129. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/DiffHandlers.h +10 -2
  130. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.cpp +252 -41
  131. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers.h +4 -0
  132. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_Build.cpp +250 -27
  133. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_PIE.cpp +303 -125
  134. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_PIERuntime.cpp +73 -50
  135. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/EditorHandlers_RuntimeVisibility.cpp +757 -0
  136. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.cpp +11 -2
  137. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers.h +3 -0
  138. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/FoliageHandlers_Batch.cpp +419 -0
  139. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.cpp +39 -161
  140. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers.h +66 -1
  141. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers_BTAuthoring.cpp +1323 -0
  142. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GameplayHandlers_BehaviorTree.cpp +1211 -0
  143. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.cpp +2 -0
  144. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers.h +60 -0
  145. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/GasHandlers_Runtime.cpp +363 -12
  146. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/HandlerEditorState.h +84 -0
  147. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.cpp +1288 -36
  148. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers.h +3 -0
  149. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LandscapeHandlers_Sculpt.cpp +41 -16
  150. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.cpp +959 -213
  151. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers.h +66 -0
  152. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_BatchWrite.cpp +1571 -0
  153. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Convert.cpp +316 -0
  154. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Inspection.cpp +280 -0
  155. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_InstanceProjection.cpp +666 -0
  156. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_InstanceProjection_Internal.h +63 -0
  157. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Lights.cpp +43 -12
  158. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_MultiLevel.cpp +13 -47
  159. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_PostProcess.cpp +527 -0
  160. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Query.cpp +1169 -0
  161. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Refresh.cpp +723 -0
  162. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Save.cpp +325 -0
  163. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Spatial.cpp +360 -0
  164. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Trace.cpp +178 -58
  165. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Transient.cpp +337 -0
  166. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_Volumes.cpp +25 -12
  167. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_WorldPartition.cpp +10 -9
  168. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/LevelHandlers_WorldPartitionSettings.cpp +686 -0
  169. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MassHandlers.cpp +467 -0
  170. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MassHandlers.h +22 -0
  171. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.cpp +452 -175
  172. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers.h +5 -0
  173. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/MaterialHandlers_Build.cpp +597 -0
  174. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/NiagaraHandlers.cpp +17 -15
  175. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PCGHandlers.cpp +38 -168
  176. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/PhysicsHandlers.cpp +39 -30
  177. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.cpp +392 -78
  178. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers.h +2 -0
  179. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SequencerHandlers_Internal.h +83 -0
  180. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SkeletalMeshHandlers.cpp +200 -0
  181. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SkeletalMeshHandlers.h +15 -0
  182. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/SplineHandlers.cpp +19 -12
  183. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/StateTreeHandlers.cpp +31 -1
  184. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.cpp +307 -69
  185. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers.h +84 -0
  186. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers_Extraction.cpp +8 -41
  187. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Handlers/WidgetHandlers_Properties.cpp +33 -52
  188. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/ActorSelectorTests.cpp +344 -0
  189. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AnimationControlRigTimelineTests.cpp +60 -0
  190. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AnimationPoseTests.cpp +115 -0
  191. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetBulkReadTests.cpp +177 -0
  192. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetDeleteGuardTests.cpp +276 -0
  193. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetPathResolutionTests.cpp +243 -0
  194. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetPropertyPersistTests.cpp +213 -0
  195. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AssetSubobjectTests.cpp +235 -0
  196. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/AutomationRunnerTests.cpp +72 -0
  197. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BehaviorTreeAuthoringTests.cpp +526 -0
  198. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BehaviorTreeNodeTests.cpp +334 -0
  199. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BlueprintHandlerSurfaceTests.cpp +362 -0
  200. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/BridgeProtocolTests.cpp +14 -0
  201. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/CollisionQueryTests.cpp +288 -0
  202. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/DataTableRowWriteTests.cpp +453 -0
  203. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/EditorFunctionCallTests.cpp +223 -0
  204. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/FoliageBatchTests.cpp +147 -0
  205. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/GameThreadGateTests.cpp +82 -0
  206. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/GasLiveAttributeTests.cpp +183 -0
  207. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LandscapeSampleTests.cpp +119 -0
  208. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelBatchWriteTests.cpp +176 -0
  209. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelComponentTreeInstanceCountTests.cpp +189 -0
  210. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelConvertBrushesTests.cpp +100 -0
  211. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelInstanceProjectionTests.cpp +265 -0
  212. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelPostProcessOverrideTests.cpp +258 -0
  213. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelQueryComponentsTests.cpp +195 -0
  214. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelRefreshTests.cpp +142 -0
  215. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelSaveReportTests.cpp +125 -0
  216. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelScriptHandlersTests.cpp +42 -0
  217. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelStaticMeshUsageTests.cpp +412 -0
  218. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelTraceWorldScopeTests.cpp +133 -0
  219. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelTransientActorTests.cpp +205 -0
  220. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/LevelWorldPartitionSettingsTests.cpp +168 -0
  221. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MCPInstancedStructPathTestTypes.h +51 -0
  222. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MCPInstancedStructPathTests.cpp +379 -0
  223. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MaterialBuildTests.cpp +238 -0
  224. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MeshBooleanTests.cpp +170 -0
  225. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/MeshGeometryTests.cpp +116 -0
  226. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/PackageSaveExtensionTests.cpp +161 -0
  227. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/PackageWriteGuardTests.cpp +253 -0
  228. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/RuntimeVisibilityTests.cpp +143 -0
  229. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SequencerHandlerTests.cpp +660 -0
  230. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SequencerScrubTests.cpp +50 -0
  231. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/SkeletonDiffTests.cpp +685 -0
  232. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/Tests/WidgetBlueprintResolveTests.cpp +145 -0
  233. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Private/UE_MCP_Bridge.cpp +80 -0
  234. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerFunctionCall.h +509 -0
  235. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerQuery.h +407 -0
  236. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/Public/HandlerUtils.h +1008 -77
  237. package/plugin/ue_mcp_bridge/Source/UE_MCP_Bridge/UE_MCP_Bridge.Build.cs +87 -0
  238. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Private/MCPEngineStatus.cpp +152 -14
  239. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Private/Tests/MCPEngineStatusTests.cpp +65 -0
  240. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/Public/MCPEngineStatus.h +32 -1
  241. package/plugin/ue_mcp_bridge/Source/UE_MCP_BridgeStatus/UE_MCP_BridgeStatus.Build.cs +2 -0
  242. package/skills/ue-mcp-animation/SKILL.md +154 -0
  243. package/skills/ue-mcp-blueprint/SKILL.md +71 -0
@@ -0,0 +1,319 @@
1
+ // asset(create_subobject) (#975).
2
+ //
3
+ // Some plugin data assets store their payload as named subobjects that live
4
+ // inside the asset's own package and are referenced from a struct array.
5
+ // Editing an existing entry already worked through set_property,
6
+ // bulk_set_properties and append_array_elements with dotted paths, but ADDING
7
+ // one needs a brand-new subobject and nothing native could make one:
8
+ // create_asset_by_class refuses component classes outright and otherwise puts
9
+ // the new object in a package of its own.
10
+ //
11
+ // Two things bit the reporter and both are handled here.
12
+ //
13
+ // 1. A freshly created object that nothing references is collected within
14
+ // roughly one bridge call, so they had to create one object and reference
15
+ // it in the very next call, and an intermediate read lost it. The new
16
+ // object is created RF_Standalone, which is the engine's own "keep this
17
+ // even though nothing points at it yet", and the owning package is written
18
+ // in the same call by default. RF_Standalone is also what makes
19
+ // UPackage::SavePackage harvest an otherwise unreferenced object as an
20
+ // export, so the subobject is on disk and reachable by path from the next
21
+ // call onwards whatever the collector decides to do in between.
22
+ //
23
+ // 2. Plugin classes are frequently absent from the Python `unreal` module, so
24
+ // the class has to be named by object path. className goes through the
25
+ // shared class resolver, which accepts /Script/Module.Class, the
26
+ // Module.Class shorthand and the bare name alike.
27
+
28
+ #include "AssetHandlers.h"
29
+ #include "HandlerRegistry.h"
30
+ #include "HandlerUtils.h"
31
+ #include "HandlerJsonProperty.h"
32
+
33
+ #include "Dom/JsonObject.h"
34
+ #include "Dom/JsonValue.h"
35
+ #include "GameFramework/Actor.h"
36
+ #include "Misc/PackageName.h"
37
+ #include "UObject/Package.h"
38
+ #include "UObject/UObjectGlobals.h"
39
+
40
+ namespace
41
+ {
42
+ /** Apply a properties object to one object, dotted paths and all. Returns
43
+ * the number applied; every failure lands in OutErrors. */
44
+ int32 MCPApplySubobjectProperties(
45
+ UObject* Target,
46
+ const TSharedPtr<FJsonObject>& Properties,
47
+ TArray<FString>& OutApplied,
48
+ TArray<FString>& OutErrors)
49
+ {
50
+ if (!Target || !Properties.IsValid()) return 0;
51
+
52
+ int32 Applied = 0;
53
+ for (const auto& Pair : Properties->Values)
54
+ {
55
+ // The key type is not FString on every engine the plugin builds
56
+ // against, so materialise it before it is used as one.
57
+ const FString PropertyPath(*Pair.Key);
58
+ FString SetError;
59
+ if (MCPJsonProperty::SetDottedPropertyFromJson(Target, PropertyPath, Pair.Value, SetError))
60
+ {
61
+ OutApplied.Add(PropertyPath);
62
+ ++Applied;
63
+ }
64
+ else
65
+ {
66
+ OutErrors.Add(FString::Printf(TEXT("%s: %s"), *PropertyPath, *SetError));
67
+ }
68
+ }
69
+ return Applied;
70
+ }
71
+
72
+ TArray<TSharedPtr<FJsonValue>> MCPSubobjectStringsToJson(const TArray<FString>& Values)
73
+ {
74
+ TArray<TSharedPtr<FJsonValue>> Out;
75
+ Out.Reserve(Values.Num());
76
+ for (const FString& Value : Values) Out.Add(MakeShared<FJsonValueString>(Value));
77
+ return Out;
78
+ }
79
+ }
80
+
81
+ TSharedPtr<FJsonValue> FAssetHandlers::CreateSubobject(const TSharedPtr<FJsonObject>& Params)
82
+ {
83
+ MCP_CHECK_GAME_THREAD();
84
+
85
+ FString AssetPath;
86
+ if (auto Err = RequireStringAlt(Params, TEXT("assetPath"), TEXT("path"), AssetPath)) return Err;
87
+ FString ClassName;
88
+ if (auto Err = RequireString(Params, TEXT("className"), ClassName)) return Err;
89
+ FString Name;
90
+ if (auto Err = RequireString(Params, TEXT("name"), Name)) return Err;
91
+ Name.TrimStartAndEndInline();
92
+ if (Name.IsEmpty())
93
+ {
94
+ return MCPError(TEXT("'name' must not be empty: the subobject is addressed by name from the next call onwards."));
95
+ }
96
+
97
+ // This writes into an existing package, so the mount guardrail applies
98
+ // before anything is resolved or created.
99
+ if (MCPIsProtectedAssetPath(AssetPath))
100
+ {
101
+ return MCPError(FString::Printf(
102
+ TEXT("'%s' is on a protected mount (/Engine/, /Script/, /Memory/, /Temp/), which the bridge never writes to."),
103
+ *AssetPath));
104
+ }
105
+
106
+ TSharedPtr<FJsonValue> LoadError;
107
+ UObject* OwnerAsset = MCPRequireAssetObject(AssetPath, LoadError);
108
+ if (!OwnerAsset) return LoadError;
109
+
110
+ UPackage* OwnerPackage = OwnerAsset->GetOutermost();
111
+ if (!OwnerPackage)
112
+ {
113
+ return MCPError(FString::Printf(TEXT("Asset '%s' has no package to own a subobject."), *AssetPath));
114
+ }
115
+
116
+ UClass* Class = MCPResolveClass(ClassName);
117
+ if (auto Err = MCPCheckClassUsable(ClassName, Class)) return Err;
118
+
119
+ // An Actor is created by spawning it into a level, and NewObject on one
120
+ // outside a level is not a supported construction. Say so rather than
121
+ // letting the engine decide how to fail. Components are deliberately NOT
122
+ // refused: they are the case this action exists for.
123
+ if (Class->IsChildOf(AActor::StaticClass()))
124
+ {
125
+ return MCPClassUnusableError(ClassName, Class, TEXT("actor_class"),
126
+ TEXT("an Actor is spawned into a level, not created inside an asset package. Use level(spawn_actor)."));
127
+ }
128
+ if (Class->IsChildOf(UClass::StaticClass()))
129
+ {
130
+ return MCPClassUnusableError(ClassName, Class, TEXT("class_object"),
131
+ TEXT("it is a class object rather than an instantiable type. Pass the class you want an INSTANCE of."));
132
+ }
133
+
134
+ // outer=asset gives "/Game/Foo/DA_Thing.DA_Thing:Name", the ordinary
135
+ // subobject-of-the-asset form. outer=package gives
136
+ // "/Game/Foo/DA_Thing.Name", which is what a plugin that keeps its payload
137
+ // as siblings of the asset inside one package expects.
138
+ const FString OuterSpec = OptionalString(Params, TEXT("outer"), TEXT("asset")).ToLower();
139
+ if (OuterSpec != TEXT("asset") && OuterSpec != TEXT("package"))
140
+ {
141
+ return MCPError(FString::Printf(
142
+ TEXT("'outer' must be 'asset' (default) or 'package', got '%s'."), *OuterSpec));
143
+ }
144
+ UObject* Outer = (OuterSpec == TEXT("package"))
145
+ ? static_cast<UObject*>(OwnerPackage)
146
+ : OwnerAsset;
147
+
148
+ // A class can declare the outer type it must live under. Checking it here
149
+ // turns an engine assertion into an answer.
150
+ if (Class->ClassWithin && !Outer->IsA(Class->ClassWithin))
151
+ {
152
+ return MCPClassUnusableError(ClassName, Class, TEXT("class_within"), FString::Printf(
153
+ TEXT("it must be created inside a %s, and the chosen outer '%s' is a %s. Try the other 'outer' value."),
154
+ *Class->ClassWithin->GetName(), *Outer->GetPathName(), *Outer->GetClass()->GetName()));
155
+ }
156
+
157
+ const FName SubobjectName(*Name);
158
+ const FString OnConflict = OptionalString(Params, TEXT("onConflict"), TEXT("reuse")).ToLower();
159
+ if (OnConflict != TEXT("reuse") && OnConflict != TEXT("error"))
160
+ {
161
+ return MCPError(FString::Printf(
162
+ TEXT("'onConflict' must be 'reuse' (default) or 'error', got '%s'."), *OnConflict));
163
+ }
164
+
165
+ const TSharedPtr<FJsonObject>* PropertiesField = nullptr;
166
+ TSharedPtr<FJsonObject> Properties;
167
+ if (Params->TryGetObjectField(TEXT("properties"), PropertiesField) && PropertiesField && (*PropertiesField).IsValid())
168
+ {
169
+ Properties = *PropertiesField;
170
+ }
171
+
172
+ // Every property is applied to a throwaway instance first, so a bad path or
173
+ // a bad value rejects the call before the target package is touched. This
174
+ // is the same preflight bulk_upsert_data_assets uses.
175
+ if (Properties.IsValid() && Properties->Values.Num() > 0)
176
+ {
177
+ UObject* Probe = NewObject<UObject>(GetTransientPackage(), Class, NAME_None, RF_Transient);
178
+ if (!Probe)
179
+ {
180
+ return MCPError(FString::Printf(
181
+ TEXT("Could not instantiate '%s' even in the transient package."), *Class->GetPathName()));
182
+ }
183
+ const FGCRootScope KeepProbeAlive(Probe);
184
+
185
+ TArray<FString> ProbeApplied;
186
+ TArray<FString> ProbeErrors;
187
+ MCPApplySubobjectProperties(Probe, Properties, ProbeApplied, ProbeErrors);
188
+ if (ProbeErrors.Num() > 0)
189
+ {
190
+ TSharedPtr<FJsonObject> Obj = MakeShared<FJsonObject>();
191
+ Obj->SetBoolField(TEXT("success"), false);
192
+ Obj->SetStringField(TEXT("error"), FString::Printf(
193
+ TEXT("%d of %d properties would not apply to a %s, so nothing was created: %s"),
194
+ ProbeErrors.Num(), Properties->Values.Num(), *Class->GetName(),
195
+ *FString::Join(ProbeErrors, TEXT("; "))));
196
+ Obj->SetStringField(TEXT("reason"), TEXT("property_preflight_failed"));
197
+ Obj->SetArrayField(TEXT("propertyErrors"), MCPSubobjectStringsToJson(ProbeErrors));
198
+ return MakeShared<FJsonValueObject>(Obj);
199
+ }
200
+ }
201
+
202
+ auto Result = MCPSuccess();
203
+ Result->SetStringField(TEXT("assetPath"), AssetPath);
204
+ Result->SetStringField(TEXT("name"), Name);
205
+ Result->SetStringField(TEXT("className"), Class->GetName());
206
+ Result->SetStringField(TEXT("classPath"), Class->GetPathName());
207
+ Result->SetStringField(TEXT("outer"), OuterSpec);
208
+ Result->SetStringField(TEXT("outerPath"), Outer->GetPathName());
209
+ Result->SetStringField(TEXT("packageName"), OwnerPackage->GetName());
210
+
211
+ UObject* Subobject = StaticFindObjectFast(UObject::StaticClass(), Outer, SubobjectName);
212
+ const bool bExisted = Subobject != nullptr;
213
+ if (bExisted)
214
+ {
215
+ if (OnConflict == TEXT("error"))
216
+ {
217
+ return MCPError(FString::Printf(
218
+ TEXT("A subobject named '%s' already exists at '%s' (a %s). Pass onConflict='reuse' to configure it in place."),
219
+ *Name, *Subobject->GetPathName(), *Subobject->GetClass()->GetName()));
220
+ }
221
+ if (Subobject->GetClass() != Class)
222
+ {
223
+ return MCPError(FString::Printf(
224
+ TEXT("'%s' already exists as a %s, not a %s. Pick another name, or address the existing object directly."),
225
+ *Subobject->GetPathName(), *Subobject->GetClass()->GetName(), *Class->GetName()));
226
+ }
227
+ MCPSetExisted(Result);
228
+ }
229
+ else
230
+ {
231
+ OwnerAsset->Modify();
232
+ // #975: RF_Standalone is what keeps the object alive with nothing
233
+ // referencing it yet, and what makes the save below harvest it as a
234
+ // package export. RF_Public lets the struct array that will reference
235
+ // it hold an ordinary object reference rather than an instanced one.
236
+ Subobject = NewObject<UObject>(
237
+ Outer, Class, SubobjectName, RF_Public | RF_Standalone | RF_Transactional);
238
+ if (!Subobject)
239
+ {
240
+ return MCPError(FString::Printf(
241
+ TEXT("Could not create a '%s' named '%s' inside '%s'."),
242
+ *Class->GetPathName(), *Name, *Outer->GetPathName()));
243
+ }
244
+ MCPSetCreated(Result);
245
+ }
246
+
247
+ // Belt and braces for the window between this call and the next one: the
248
+ // object is rooted for the rest of this handler, and standalone plus saved
249
+ // after it.
250
+ const FGCRootScope KeepSubobjectAlive(Subobject);
251
+
252
+ TArray<FString> Applied;
253
+ TArray<FString> PropertyErrors;
254
+ if (Properties.IsValid())
255
+ {
256
+ Subobject->Modify();
257
+ MCPApplySubobjectProperties(Subobject, Properties, Applied, PropertyErrors);
258
+ Subobject->PostEditChange();
259
+ }
260
+
261
+ Result->SetStringField(TEXT("objectPath"), Subobject->GetPathName());
262
+ Result->SetArrayField(TEXT("propertiesSet"), MCPSubobjectStringsToJson(Applied));
263
+ if (PropertyErrors.Num() > 0)
264
+ {
265
+ Result->SetArrayField(TEXT("propertyErrors"), MCPSubobjectStringsToJson(PropertyErrors));
266
+ }
267
+
268
+ OwnerAsset->PostEditChange();
269
+ OwnerPackage->MarkPackageDirty();
270
+
271
+ // Saving in the same call is what closes the garbage-collection window the
272
+ // issue is about: after this the subobject is an export on disk, so a later
273
+ // call resolves it by path even if the in-memory copy is collected.
274
+ const bool bSave = OptionalBool(Params, TEXT("save"), true);
275
+ bool bPersisted = false;
276
+ FString PersistReason;
277
+ if (bSave)
278
+ {
279
+ bPersisted = SaveAssetPackage(OwnerAsset);
280
+ if (!bPersisted)
281
+ {
282
+ PersistReason = FString::Printf(
283
+ TEXT("The editor refused to write '%s'. The subobject exists in memory and is kept alive, but it is not on disk yet."),
284
+ *OwnerPackage->GetName());
285
+ }
286
+ }
287
+ else
288
+ {
289
+ PersistReason = FString::Printf(
290
+ TEXT("save=false was requested, so '%s' is dirty in memory only. The subobject survives garbage collection while the editor runs, but it is not on disk until the package is saved."),
291
+ *OwnerPackage->GetName());
292
+ }
293
+ Result->SetBoolField(TEXT("persisted"), bPersisted);
294
+ Result->SetBoolField(TEXT("saved"), bPersisted);
295
+ Result->SetBoolField(TEXT("packageDirty"), OwnerPackage->IsDirty());
296
+ if (!bPersisted)
297
+ {
298
+ Result->SetStringField(TEXT("persistError"), PersistReason);
299
+ if (bSave)
300
+ {
301
+ Result->SetBoolField(TEXT("success"), false);
302
+ Result->SetStringField(TEXT("error"), PersistReason);
303
+ }
304
+ }
305
+
306
+ if (PropertyErrors.Num() > 0)
307
+ {
308
+ // The preflight passed and the write did not, which means the object is
309
+ // half configured. Loud, not a footnote.
310
+ Result->SetBoolField(TEXT("success"), false);
311
+ Result->SetStringField(TEXT("error"), FString::Printf(
312
+ TEXT("Created '%s' but %d propert%s would not apply: %s"),
313
+ *Subobject->GetPathName(), PropertyErrors.Num(),
314
+ PropertyErrors.Num() == 1 ? TEXT("y") : TEXT("ies"),
315
+ *FString::Join(PropertyErrors, TEXT("; "))));
316
+ }
317
+
318
+ return MCPResult(Result);
319
+ }
@@ -29,7 +29,7 @@
29
29
 
30
30
  namespace
31
31
  {
32
- USoundNode* FindNodeByName(USoundCue* Cue, const FString& NodeName)
32
+ USoundNode* FindSoundCueNodeByName(USoundCue* Cue, const FString& NodeName)
33
33
  {
34
34
  #if WITH_EDITORONLY_DATA
35
35
  for (USoundNode* N : Cue->AllNodes)
@@ -121,7 +121,7 @@ TSharedPtr<FJsonValue> FAudioHandlers::SoundCueConnect(const TSharedPtr<FJsonObj
121
121
  USoundCue* Cue = Cast<USoundCue>(UEditorAssetLibrary::LoadAsset(CuePath));
122
122
  if (!Cue) return MCPError(FString::Printf(TEXT("SoundCue not found: %s"), *CuePath));
123
123
 
124
- USoundNode* Child = FindNodeByName(Cue, ChildNodeId);
124
+ USoundNode* Child = FindSoundCueNodeByName(Cue, ChildNodeId);
125
125
  if (!Child) return MCPError(FString::Printf(TEXT("Child node '%s' not found in cue."), *ChildNodeId));
126
126
 
127
127
  const FString ParentNodeId = OptionalString(Params, TEXT("parentNodeId"));
@@ -132,7 +132,7 @@ TSharedPtr<FJsonValue> FAudioHandlers::SoundCueConnect(const TSharedPtr<FJsonObj
132
132
  }
133
133
  else
134
134
  {
135
- USoundNode* Parent = FindNodeByName(Cue, ParentNodeId);
135
+ USoundNode* Parent = FindSoundCueNodeByName(Cue, ParentNodeId);
136
136
  if (!Parent) return MCPError(FString::Printf(TEXT("Parent node '%s' not found in cue."), *ParentNodeId));
137
137
 
138
138
  int32 Index = Params->HasField(TEXT("childIndex"))