unreal-engine-mcp-server 0.4.7 → 0.5.1

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 (454) hide show
  1. package/.env.example +26 -0
  2. package/.env.production +38 -7
  3. package/.eslintrc.json +0 -54
  4. package/.eslintrc.override.json +8 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +94 -0
  6. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +56 -0
  8. package/.github/copilot-instructions.md +478 -45
  9. package/.github/dependabot.yml +19 -0
  10. package/.github/labeler.yml +24 -0
  11. package/.github/labels.yml +70 -0
  12. package/.github/pull_request_template.md +42 -0
  13. package/.github/release-drafter-config.yml +51 -0
  14. package/.github/workflows/auto-merge.yml +38 -0
  15. package/.github/workflows/ci.yml +38 -0
  16. package/.github/workflows/dependency-review.yml +17 -0
  17. package/.github/workflows/gemini-issue-triage.yml +172 -0
  18. package/.github/workflows/greetings.yml +27 -0
  19. package/.github/workflows/labeler.yml +17 -0
  20. package/.github/workflows/links.yml +80 -0
  21. package/.github/workflows/pr-size-labeler.yml +137 -0
  22. package/.github/workflows/publish-mcp.yml +13 -7
  23. package/.github/workflows/release-drafter.yml +23 -0
  24. package/.github/workflows/release.yml +112 -0
  25. package/.github/workflows/semantic-pull-request.yml +35 -0
  26. package/.github/workflows/smoke-test.yml +36 -0
  27. package/.github/workflows/stale.yml +28 -0
  28. package/CHANGELOG.md +338 -31
  29. package/CONTRIBUTING.md +140 -0
  30. package/GEMINI.md +115 -0
  31. package/Public/Plugin_setup_guide.mp4 +0 -0
  32. package/README.md +189 -128
  33. package/claude_desktop_config_example.json +7 -6
  34. package/dist/automation/bridge.d.ts +50 -0
  35. package/dist/automation/bridge.js +452 -0
  36. package/dist/automation/connection-manager.d.ts +23 -0
  37. package/dist/automation/connection-manager.js +107 -0
  38. package/dist/automation/handshake.d.ts +11 -0
  39. package/dist/automation/handshake.js +89 -0
  40. package/dist/automation/index.d.ts +3 -0
  41. package/dist/automation/index.js +3 -0
  42. package/dist/automation/message-handler.d.ts +12 -0
  43. package/dist/automation/message-handler.js +149 -0
  44. package/dist/automation/request-tracker.d.ts +25 -0
  45. package/dist/automation/request-tracker.js +98 -0
  46. package/dist/automation/types.d.ts +130 -0
  47. package/dist/automation/types.js +2 -0
  48. package/dist/cli.js +32 -5
  49. package/dist/config.d.ts +26 -0
  50. package/dist/config.js +59 -0
  51. package/dist/constants.d.ts +16 -0
  52. package/dist/constants.js +16 -0
  53. package/dist/graphql/loaders.d.ts +64 -0
  54. package/dist/graphql/loaders.js +117 -0
  55. package/dist/graphql/resolvers.d.ts +268 -0
  56. package/dist/graphql/resolvers.js +746 -0
  57. package/dist/graphql/schema.d.ts +5 -0
  58. package/dist/graphql/schema.js +437 -0
  59. package/dist/graphql/server.d.ts +26 -0
  60. package/dist/graphql/server.js +117 -0
  61. package/dist/graphql/types.d.ts +9 -0
  62. package/dist/graphql/types.js +2 -0
  63. package/dist/handlers/resource-handlers.d.ts +20 -0
  64. package/dist/handlers/resource-handlers.js +180 -0
  65. package/dist/index.d.ts +33 -18
  66. package/dist/index.js +130 -619
  67. package/dist/resources/actors.d.ts +17 -12
  68. package/dist/resources/actors.js +56 -76
  69. package/dist/resources/assets.d.ts +6 -14
  70. package/dist/resources/assets.js +115 -147
  71. package/dist/resources/levels.d.ts +13 -13
  72. package/dist/resources/levels.js +25 -34
  73. package/dist/server/resource-registry.d.ts +20 -0
  74. package/dist/server/resource-registry.js +37 -0
  75. package/dist/server/tool-registry.d.ts +23 -0
  76. package/dist/server/tool-registry.js +322 -0
  77. package/dist/server-setup.d.ts +20 -0
  78. package/dist/server-setup.js +71 -0
  79. package/dist/services/health-monitor.d.ts +34 -0
  80. package/dist/services/health-monitor.js +105 -0
  81. package/dist/services/metrics-server.d.ts +11 -0
  82. package/dist/services/metrics-server.js +105 -0
  83. package/dist/tools/actors.d.ts +163 -9
  84. package/dist/tools/actors.js +356 -311
  85. package/dist/tools/animation.d.ts +135 -4
  86. package/dist/tools/animation.js +510 -411
  87. package/dist/tools/assets.d.ts +75 -29
  88. package/dist/tools/assets.js +265 -284
  89. package/dist/tools/audio.d.ts +102 -42
  90. package/dist/tools/audio.js +272 -685
  91. package/dist/tools/base-tool.d.ts +17 -0
  92. package/dist/tools/base-tool.js +46 -0
  93. package/dist/tools/behavior-tree.d.ts +94 -0
  94. package/dist/tools/behavior-tree.js +39 -0
  95. package/dist/tools/blueprint.d.ts +208 -126
  96. package/dist/tools/blueprint.js +685 -832
  97. package/dist/tools/consolidated-tool-definitions.d.ts +5462 -1781
  98. package/dist/tools/consolidated-tool-definitions.js +829 -496
  99. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  100. package/dist/tools/consolidated-tool-handlers.js +198 -1027
  101. package/dist/tools/debug.d.ts +143 -85
  102. package/dist/tools/debug.js +234 -180
  103. package/dist/tools/dynamic-handler-registry.d.ts +13 -0
  104. package/dist/tools/dynamic-handler-registry.js +23 -0
  105. package/dist/tools/editor.d.ts +30 -83
  106. package/dist/tools/editor.js +247 -244
  107. package/dist/tools/engine.d.ts +10 -4
  108. package/dist/tools/engine.js +13 -5
  109. package/dist/tools/environment.d.ts +30 -0
  110. package/dist/tools/environment.js +267 -0
  111. package/dist/tools/foliage.d.ts +65 -99
  112. package/dist/tools/foliage.js +221 -331
  113. package/dist/tools/handlers/actor-handlers.d.ts +3 -0
  114. package/dist/tools/handlers/actor-handlers.js +227 -0
  115. package/dist/tools/handlers/animation-handlers.d.ts +3 -0
  116. package/dist/tools/handlers/animation-handlers.js +185 -0
  117. package/dist/tools/handlers/argument-helper.d.ts +16 -0
  118. package/dist/tools/handlers/argument-helper.js +80 -0
  119. package/dist/tools/handlers/asset-handlers.d.ts +3 -0
  120. package/dist/tools/handlers/asset-handlers.js +496 -0
  121. package/dist/tools/handlers/audio-handlers.d.ts +3 -0
  122. package/dist/tools/handlers/audio-handlers.js +166 -0
  123. package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
  124. package/dist/tools/handlers/blueprint-handlers.js +358 -0
  125. package/dist/tools/handlers/common-handlers.d.ts +14 -0
  126. package/dist/tools/handlers/common-handlers.js +56 -0
  127. package/dist/tools/handlers/editor-handlers.d.ts +3 -0
  128. package/dist/tools/handlers/editor-handlers.js +119 -0
  129. package/dist/tools/handlers/effect-handlers.d.ts +3 -0
  130. package/dist/tools/handlers/effect-handlers.js +171 -0
  131. package/dist/tools/handlers/environment-handlers.d.ts +3 -0
  132. package/dist/tools/handlers/environment-handlers.js +170 -0
  133. package/dist/tools/handlers/graph-handlers.d.ts +3 -0
  134. package/dist/tools/handlers/graph-handlers.js +90 -0
  135. package/dist/tools/handlers/input-handlers.d.ts +3 -0
  136. package/dist/tools/handlers/input-handlers.js +21 -0
  137. package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
  138. package/dist/tools/handlers/inspect-handlers.js +383 -0
  139. package/dist/tools/handlers/level-handlers.d.ts +3 -0
  140. package/dist/tools/handlers/level-handlers.js +237 -0
  141. package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
  142. package/dist/tools/handlers/lighting-handlers.js +144 -0
  143. package/dist/tools/handlers/performance-handlers.d.ts +3 -0
  144. package/dist/tools/handlers/performance-handlers.js +130 -0
  145. package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
  146. package/dist/tools/handlers/pipeline-handlers.js +110 -0
  147. package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
  148. package/dist/tools/handlers/sequence-handlers.js +376 -0
  149. package/dist/tools/handlers/system-handlers.d.ts +4 -0
  150. package/dist/tools/handlers/system-handlers.js +506 -0
  151. package/dist/tools/input.d.ts +19 -0
  152. package/dist/tools/input.js +89 -0
  153. package/dist/tools/introspection.d.ts +103 -40
  154. package/dist/tools/introspection.js +425 -568
  155. package/dist/tools/landscape.d.ts +54 -93
  156. package/dist/tools/landscape.js +284 -409
  157. package/dist/tools/level.d.ts +66 -27
  158. package/dist/tools/level.js +647 -675
  159. package/dist/tools/lighting.d.ts +77 -38
  160. package/dist/tools/lighting.js +445 -943
  161. package/dist/tools/logs.d.ts +3 -3
  162. package/dist/tools/logs.js +5 -57
  163. package/dist/tools/materials.d.ts +91 -24
  164. package/dist/tools/materials.js +194 -118
  165. package/dist/tools/niagara.d.ts +149 -39
  166. package/dist/tools/niagara.js +267 -182
  167. package/dist/tools/performance.d.ts +27 -13
  168. package/dist/tools/performance.js +203 -122
  169. package/dist/tools/physics.d.ts +32 -77
  170. package/dist/tools/physics.js +175 -582
  171. package/dist/tools/property-dictionary.d.ts +13 -0
  172. package/dist/tools/property-dictionary.js +82 -0
  173. package/dist/tools/sequence.d.ts +85 -60
  174. package/dist/tools/sequence.js +208 -747
  175. package/dist/tools/tool-definition-utils.d.ts +59 -0
  176. package/dist/tools/tool-definition-utils.js +35 -0
  177. package/dist/tools/ui.d.ts +64 -34
  178. package/dist/tools/ui.js +134 -214
  179. package/dist/types/automation-responses.d.ts +115 -0
  180. package/dist/types/automation-responses.js +2 -0
  181. package/dist/types/env.d.ts +0 -3
  182. package/dist/types/env.js +0 -7
  183. package/dist/types/responses.d.ts +249 -0
  184. package/dist/types/responses.js +2 -0
  185. package/dist/types/tool-interfaces.d.ts +898 -0
  186. package/dist/types/tool-interfaces.js +2 -0
  187. package/dist/types/tool-types.d.ts +183 -19
  188. package/dist/types/tool-types.js +0 -4
  189. package/dist/unreal-bridge.d.ts +24 -131
  190. package/dist/unreal-bridge.js +364 -1506
  191. package/dist/utils/command-validator.d.ts +9 -0
  192. package/dist/utils/command-validator.js +68 -0
  193. package/dist/utils/elicitation.d.ts +1 -1
  194. package/dist/utils/elicitation.js +12 -15
  195. package/dist/utils/error-handler.d.ts +2 -51
  196. package/dist/utils/error-handler.js +11 -87
  197. package/dist/utils/ini-reader.d.ts +3 -0
  198. package/dist/utils/ini-reader.js +69 -0
  199. package/dist/utils/logger.js +9 -6
  200. package/dist/utils/normalize.d.ts +3 -0
  201. package/dist/utils/normalize.js +56 -0
  202. package/dist/utils/path-security.d.ts +2 -0
  203. package/dist/utils/path-security.js +24 -0
  204. package/dist/utils/response-factory.d.ts +7 -0
  205. package/dist/utils/response-factory.js +27 -0
  206. package/dist/utils/response-validator.d.ts +3 -24
  207. package/dist/utils/response-validator.js +130 -81
  208. package/dist/utils/result-helpers.d.ts +4 -5
  209. package/dist/utils/result-helpers.js +15 -16
  210. package/dist/utils/safe-json.js +5 -11
  211. package/dist/utils/unreal-command-queue.d.ts +24 -0
  212. package/dist/utils/unreal-command-queue.js +120 -0
  213. package/dist/utils/validation.d.ts +0 -40
  214. package/dist/utils/validation.js +1 -78
  215. package/dist/wasm/index.d.ts +70 -0
  216. package/dist/wasm/index.js +535 -0
  217. package/docs/GraphQL-API.md +888 -0
  218. package/docs/Migration-Guide-v0.5.0.md +684 -0
  219. package/docs/Roadmap.md +53 -0
  220. package/docs/WebAssembly-Integration.md +628 -0
  221. package/docs/editor-plugin-extension.md +370 -0
  222. package/docs/handler-mapping.md +242 -0
  223. package/docs/native-automation-progress.md +128 -0
  224. package/docs/testing-guide.md +423 -0
  225. package/mcp-config-example.json +6 -6
  226. package/package.json +67 -28
  227. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
  228. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
  229. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
  230. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
  231. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
  232. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
  233. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
  234. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
  235. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
  236. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
  237. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
  238. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
  239. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
  240. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
  241. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
  242. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
  243. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
  244. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
  245. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
  246. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
  247. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
  248. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
  249. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
  250. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
  251. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
  252. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
  253. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
  254. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
  255. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
  256. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
  257. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
  258. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
  259. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
  260. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
  261. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
  262. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
  263. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
  264. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
  265. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
  266. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
  267. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
  268. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
  269. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
  270. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
  272. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
  273. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
  274. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
  275. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
  276. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
  277. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
  278. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
  279. package/scripts/check-unreal-connection.mjs +19 -0
  280. package/scripts/clean-tmp.js +23 -0
  281. package/scripts/patch-wasm.js +26 -0
  282. package/scripts/run-all-tests.mjs +136 -0
  283. package/scripts/smoke-test.ts +94 -0
  284. package/scripts/sync-mcp-plugin.js +143 -0
  285. package/scripts/test-no-plugin-alternates.mjs +113 -0
  286. package/scripts/validate-server.js +46 -0
  287. package/scripts/verify-automation-bridge.js +200 -0
  288. package/server.json +58 -21
  289. package/src/automation/bridge.ts +558 -0
  290. package/src/automation/connection-manager.ts +130 -0
  291. package/src/automation/handshake.ts +99 -0
  292. package/src/automation/index.ts +2 -0
  293. package/src/automation/message-handler.ts +167 -0
  294. package/src/automation/request-tracker.ts +123 -0
  295. package/src/automation/types.ts +107 -0
  296. package/src/cli.ts +33 -6
  297. package/src/config.ts +73 -0
  298. package/src/constants.ts +19 -0
  299. package/src/graphql/loaders.ts +244 -0
  300. package/src/graphql/resolvers.ts +1008 -0
  301. package/src/graphql/schema.ts +452 -0
  302. package/src/graphql/server.ts +156 -0
  303. package/src/graphql/types.ts +10 -0
  304. package/src/handlers/resource-handlers.ts +186 -0
  305. package/src/index.ts +166 -664
  306. package/src/resources/actors.ts +58 -76
  307. package/src/resources/assets.ts +148 -134
  308. package/src/resources/levels.ts +28 -33
  309. package/src/server/resource-registry.ts +47 -0
  310. package/src/server/tool-registry.ts +354 -0
  311. package/src/server-setup.ts +114 -0
  312. package/src/services/health-monitor.ts +132 -0
  313. package/src/services/metrics-server.ts +142 -0
  314. package/src/tools/actors.ts +426 -323
  315. package/src/tools/animation.ts +672 -461
  316. package/src/tools/assets.ts +364 -289
  317. package/src/tools/audio.ts +323 -766
  318. package/src/tools/base-tool.ts +52 -0
  319. package/src/tools/behavior-tree.ts +45 -0
  320. package/src/tools/blueprint.ts +792 -970
  321. package/src/tools/consolidated-tool-definitions.ts +993 -515
  322. package/src/tools/consolidated-tool-handlers.ts +258 -1146
  323. package/src/tools/debug.ts +292 -187
  324. package/src/tools/dynamic-handler-registry.ts +33 -0
  325. package/src/tools/editor.ts +329 -253
  326. package/src/tools/engine.ts +14 -3
  327. package/src/tools/environment.ts +281 -0
  328. package/src/tools/foliage.ts +330 -392
  329. package/src/tools/handlers/actor-handlers.ts +265 -0
  330. package/src/tools/handlers/animation-handlers.ts +237 -0
  331. package/src/tools/handlers/argument-helper.ts +142 -0
  332. package/src/tools/handlers/asset-handlers.ts +532 -0
  333. package/src/tools/handlers/audio-handlers.ts +194 -0
  334. package/src/tools/handlers/blueprint-handlers.ts +380 -0
  335. package/src/tools/handlers/common-handlers.ts +87 -0
  336. package/src/tools/handlers/editor-handlers.ts +123 -0
  337. package/src/tools/handlers/effect-handlers.ts +220 -0
  338. package/src/tools/handlers/environment-handlers.ts +183 -0
  339. package/src/tools/handlers/graph-handlers.ts +116 -0
  340. package/src/tools/handlers/input-handlers.ts +28 -0
  341. package/src/tools/handlers/inspect-handlers.ts +450 -0
  342. package/src/tools/handlers/level-handlers.ts +252 -0
  343. package/src/tools/handlers/lighting-handlers.ts +147 -0
  344. package/src/tools/handlers/performance-handlers.ts +132 -0
  345. package/src/tools/handlers/pipeline-handlers.ts +127 -0
  346. package/src/tools/handlers/sequence-handlers.ts +415 -0
  347. package/src/tools/handlers/system-handlers.ts +564 -0
  348. package/src/tools/input.ts +101 -0
  349. package/src/tools/introspection.ts +493 -584
  350. package/src/tools/landscape.ts +418 -507
  351. package/src/tools/level.ts +786 -708
  352. package/src/tools/lighting.ts +588 -984
  353. package/src/tools/logs.ts +9 -57
  354. package/src/tools/materials.ts +237 -121
  355. package/src/tools/niagara.ts +335 -168
  356. package/src/tools/performance.ts +320 -169
  357. package/src/tools/physics.ts +274 -613
  358. package/src/tools/property-dictionary.ts +98 -0
  359. package/src/tools/sequence.ts +276 -820
  360. package/src/tools/tool-definition-utils.ts +35 -0
  361. package/src/tools/ui.ts +205 -283
  362. package/src/types/automation-responses.ts +119 -0
  363. package/src/types/env.ts +0 -10
  364. package/src/types/responses.ts +355 -0
  365. package/src/types/tool-interfaces.ts +250 -0
  366. package/src/types/tool-types.ts +243 -21
  367. package/src/unreal-bridge.ts +460 -1550
  368. package/src/utils/command-validator.ts +76 -0
  369. package/src/utils/elicitation.ts +10 -7
  370. package/src/utils/error-handler.ts +14 -90
  371. package/src/utils/ini-reader.ts +86 -0
  372. package/src/utils/logger.ts +8 -3
  373. package/src/utils/normalize.test.ts +162 -0
  374. package/src/utils/normalize.ts +60 -0
  375. package/src/utils/path-security.ts +43 -0
  376. package/src/utils/response-factory.ts +44 -0
  377. package/src/utils/response-validator.ts +176 -56
  378. package/src/utils/result-helpers.ts +21 -19
  379. package/src/utils/safe-json.test.ts +90 -0
  380. package/src/utils/safe-json.ts +14 -11
  381. package/src/utils/unreal-command-queue.ts +152 -0
  382. package/src/utils/validation.test.ts +184 -0
  383. package/src/utils/validation.ts +4 -1
  384. package/src/wasm/index.ts +838 -0
  385. package/test-server.mjs +100 -0
  386. package/tests/run-unreal-tool-tests.mjs +242 -14
  387. package/tests/test-animation.mjs +369 -0
  388. package/tests/test-asset-advanced.mjs +82 -0
  389. package/tests/test-asset-errors.mjs +35 -0
  390. package/tests/test-asset-graph.mjs +311 -0
  391. package/tests/test-audio.mjs +417 -0
  392. package/tests/test-automation-timeouts.mjs +98 -0
  393. package/tests/test-behavior-tree.mjs +444 -0
  394. package/tests/test-blueprint-graph.mjs +410 -0
  395. package/tests/test-blueprint.mjs +577 -0
  396. package/tests/test-client-mode.mjs +86 -0
  397. package/tests/test-console-command.mjs +56 -0
  398. package/tests/test-control-actor.mjs +425 -0
  399. package/tests/test-control-editor.mjs +112 -0
  400. package/tests/test-graphql.mjs +372 -0
  401. package/tests/test-input.mjs +349 -0
  402. package/tests/test-inspect.mjs +302 -0
  403. package/tests/test-landscape.mjs +316 -0
  404. package/tests/test-lighting.mjs +428 -0
  405. package/tests/test-manage-asset.mjs +438 -0
  406. package/tests/test-manage-level.mjs +89 -0
  407. package/tests/test-materials.mjs +356 -0
  408. package/tests/test-niagara.mjs +185 -0
  409. package/tests/test-no-inline-python.mjs +122 -0
  410. package/tests/test-performance.mjs +539 -0
  411. package/tests/test-plugin-handshake.mjs +82 -0
  412. package/tests/test-runner.mjs +933 -0
  413. package/tests/test-sequence.mjs +104 -0
  414. package/tests/test-system.mjs +96 -0
  415. package/tests/test-wasm.mjs +283 -0
  416. package/tests/test-world-partition.mjs +215 -0
  417. package/tsconfig.json +3 -3
  418. package/vitest.config.ts +35 -0
  419. package/wasm/Cargo.lock +363 -0
  420. package/wasm/Cargo.toml +42 -0
  421. package/wasm/LICENSE +21 -0
  422. package/wasm/README.md +253 -0
  423. package/wasm/src/dependency_resolver.rs +377 -0
  424. package/wasm/src/lib.rs +153 -0
  425. package/wasm/src/property_parser.rs +271 -0
  426. package/wasm/src/transform_math.rs +396 -0
  427. package/wasm/tests/integration.rs +109 -0
  428. package/.github/workflows/smithery-build.yml +0 -29
  429. package/dist/prompts/index.d.ts +0 -21
  430. package/dist/prompts/index.js +0 -217
  431. package/dist/tools/build_environment_advanced.d.ts +0 -65
  432. package/dist/tools/build_environment_advanced.js +0 -633
  433. package/dist/tools/rc.d.ts +0 -110
  434. package/dist/tools/rc.js +0 -437
  435. package/dist/tools/visual.d.ts +0 -40
  436. package/dist/tools/visual.js +0 -282
  437. package/dist/utils/http.d.ts +0 -6
  438. package/dist/utils/http.js +0 -151
  439. package/dist/utils/python-output.d.ts +0 -18
  440. package/dist/utils/python-output.js +0 -290
  441. package/dist/utils/python.d.ts +0 -2
  442. package/dist/utils/python.js +0 -4
  443. package/dist/utils/stdio-redirect.d.ts +0 -2
  444. package/dist/utils/stdio-redirect.js +0 -20
  445. package/docs/unreal-tool-test-cases.md +0 -574
  446. package/smithery.yaml +0 -29
  447. package/src/prompts/index.ts +0 -249
  448. package/src/tools/build_environment_advanced.ts +0 -732
  449. package/src/tools/rc.ts +0 -515
  450. package/src/tools/visual.ts +0 -281
  451. package/src/utils/http.ts +0 -187
  452. package/src/utils/python-output.ts +0 -351
  453. package/src/utils/python.ts +0 -3
  454. package/src/utils/stdio-redirect.ts +0 -18
@@ -1,145 +1,284 @@
1
1
  import { sanitizeAssetName, validateAssetParams } from '../utils/validation.js';
2
- import { interpretStandardResult, coerceString } from '../utils/result-helpers.js';
2
+ import { wasmIntegration } from '../wasm/index.js';
3
3
  export class NiagaraTools {
4
4
  bridge;
5
- constructor(bridge) {
5
+ automationBridge;
6
+ constructor(bridge, automationBridge) {
6
7
  this.bridge = bridge;
8
+ this.automationBridge = automationBridge;
7
9
  }
8
- /**
9
- * Create Niagara System (real asset via Python)
10
- */
10
+ setAutomationBridge(automationBridge) { this.automationBridge = automationBridge; }
11
11
  async createSystem(params) {
12
12
  try {
13
+ if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
14
+ throw new Error('Automation Bridge not available. Niagara system creation requires plugin support.');
15
+ }
16
+ if (params.emitters) {
17
+ for (const emitter of params.emitters) {
18
+ if (emitter.shapeSize) {
19
+ const zeroVector = [0, 0, 0];
20
+ const processedSize = wasmIntegration.vectorAdd(zeroVector, emitter.shapeSize);
21
+ console.error('[WASM] Using vectorAdd for Niagara emitter shape size');
22
+ emitter.shapeSize = [processedSize[0], processedSize[1], processedSize[2]];
23
+ }
24
+ }
25
+ }
13
26
  const path = params.savePath || '/Game/Effects/Niagara';
14
- const python = `
15
- import unreal
16
- import json
17
-
18
- path = r"${path}"
19
- name = r"${params.name}"
20
- full_path = f"{path}/{name}"
21
-
22
- if unreal.EditorAssetLibrary.does_asset_exist(full_path):
23
- print('RESULT:' + json.dumps({'success': True, 'path': full_path, 'existing': True}))
24
- else:
25
- asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
26
- factory = None
27
- try:
28
- factory = unreal.NiagaraSystemFactoryNew()
29
- except Exception:
30
- factory = None
31
-
32
- if factory is None:
33
- print('RESULT:' + json.dumps({'success': False, 'error': 'NiagaraSystemFactoryNew unavailable'}))
34
- else:
35
- asset = asset_tools.create_asset(asset_name=name, package_path=path, asset_class=unreal.NiagaraSystem, factory=factory)
36
- if asset:
37
- unreal.EditorAssetLibrary.save_asset(full_path)
38
- print('RESULT:' + json.dumps({'success': True, 'path': full_path}))
39
- else:
40
- print('RESULT:' + json.dumps({'success': False, 'error': 'AssetTools create_asset failed'}))
41
- `.trim();
42
- const resp = await this.bridge.executePython(python);
43
- const interpreted = interpretStandardResult(resp, {
44
- successMessage: `Niagara system ${params.name} created`,
45
- failureMessage: `Failed to create Niagara system ${params.name}`
46
- });
47
- if (!interpreted.success) {
48
- return { success: false, error: interpreted.error ?? interpreted.message };
27
+ const response = await this.automationBridge.sendAutomationRequest('create_niagara_system', { name: params.name, savePath: path, template: params.template }, { timeoutMs: 60000 });
28
+ if (response && response.success !== false) {
29
+ const result = response.result ?? {};
30
+ const systemName = result.systemName ?? params.name;
31
+ const systemPath = response.path ?? result.systemPath ?? result.path ?? `${path}/${params.name}`;
32
+ return {
33
+ success: true,
34
+ systemName,
35
+ path: systemPath,
36
+ message: response.message || result.message || `Niagara system ${systemName} created`
37
+ };
49
38
  }
50
- const pathFromPayload = coerceString(interpreted.payload.path) ?? `${path}/${params.name}`;
51
39
  return {
52
- success: true,
53
- path: pathFromPayload,
54
- message: interpreted.message
40
+ success: false,
41
+ error: response?.error ?? 'CREATE_NIAGARA_SYSTEM_FAILED',
42
+ message: response?.message ?? 'Niagara system creation failed'
55
43
  };
56
44
  }
57
- catch (err) {
58
- return { success: false, error: `Failed to create Niagara system: ${err}` };
45
+ catch (error) {
46
+ const message = error instanceof Error ? error.message : String(error);
47
+ return { success: false, error: `Failed to create Niagara system: ${message}` };
48
+ }
49
+ }
50
+ async createEmitter(params) {
51
+ if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
52
+ return { success: false, error: 'AUTOMATION_BRIDGE_UNAVAILABLE', message: 'createEmitter requires automation bridge' };
53
+ }
54
+ const requestPayload = {
55
+ name: params.name,
56
+ savePath: params.savePath ?? '/Game/Effects/Niagara'
57
+ };
58
+ if (params.systemPath)
59
+ requestPayload.systemPath = params.systemPath;
60
+ if (params.template)
61
+ requestPayload.template = params.template;
62
+ try {
63
+ const response = await this.automationBridge.sendAutomationRequest('create_niagara_emitter', requestPayload, { timeoutMs: 60000 });
64
+ if (response && response.success !== false) {
65
+ const result = response.result ?? {};
66
+ return {
67
+ success: true,
68
+ emitterPath: response.emitterPath ?? result.emitterPath ?? result.path,
69
+ emitterName: result.emitterName ?? params.name,
70
+ message: response.message || result.message || `Niagara emitter ${params.name} created`
71
+ };
72
+ }
73
+ return {
74
+ success: false,
75
+ error: response?.error ?? 'CREATE_NIAGARA_EMITTER_FAILED',
76
+ message: response?.message ?? 'Niagara emitter creation failed'
77
+ };
78
+ }
79
+ catch (error) {
80
+ const message = error instanceof Error ? error.message : String(error);
81
+ return { success: false, error: `Failed to create Niagara emitter: ${message}` };
82
+ }
83
+ }
84
+ async createRibbon(params) {
85
+ if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
86
+ return { success: false, error: 'AUTOMATION_BRIDGE_UNAVAILABLE', message: 'createRibbon requires automation bridge' };
87
+ }
88
+ const toVector = (value) => {
89
+ if (!value)
90
+ return undefined;
91
+ if (Array.isArray(value))
92
+ return [value[0] ?? 0, value[1] ?? 0, value[2] ?? 0];
93
+ return [value.x ?? 0, value.y ?? 0, value.z ?? 0];
94
+ };
95
+ const requestPayload = { systemPath: params.systemPath };
96
+ let start = toVector(params.start);
97
+ let end = toVector(params.end);
98
+ const zeroVector = [0, 0, 0];
99
+ if (start) {
100
+ const processed = wasmIntegration.vectorAdd(zeroVector, start);
101
+ console.error('[WASM] Using vectorAdd for Niagara ribbon start');
102
+ start = [processed[0], processed[1], processed[2]];
103
+ }
104
+ if (end) {
105
+ const processed = wasmIntegration.vectorAdd(zeroVector, end);
106
+ console.error('[WASM] Using vectorAdd for Niagara ribbon end');
107
+ end = [processed[0], processed[1], processed[2]];
108
+ }
109
+ if (start)
110
+ requestPayload.start = start;
111
+ if (end)
112
+ requestPayload.end = end;
113
+ if (params.color)
114
+ requestPayload.color = params.color;
115
+ if (typeof params.width === 'number')
116
+ requestPayload.width = params.width;
117
+ try {
118
+ const response = await this.automationBridge.sendAutomationRequest('create_niagara_ribbon', requestPayload, { timeoutMs: 60000 });
119
+ if (response && response.success !== false) {
120
+ const result = response.result ?? {};
121
+ return {
122
+ success: true,
123
+ ribbonPath: response.ribbonPath ?? result.ribbonPath ?? result.path,
124
+ message: response.message || result.message || 'Niagara ribbon created'
125
+ };
126
+ }
127
+ return {
128
+ success: false,
129
+ error: response?.error ?? 'CREATE_NIAGARA_RIBBON_FAILED',
130
+ message: response?.message ?? 'Niagara ribbon creation failed'
131
+ };
132
+ }
133
+ catch (error) {
134
+ const message = error instanceof Error ? error.message : String(error);
135
+ return { success: false, error: `Failed to create Niagara ribbon: ${message}` };
136
+ }
137
+ }
138
+ async cleanupEffects(params) {
139
+ if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
140
+ return { success: false, error: 'AUTOMATION_BRIDGE_UNAVAILABLE', message: 'cleanupEffects requires automation bridge' };
141
+ }
142
+ if (!params.filter || typeof params.filter !== 'string') {
143
+ return { success: false, error: 'INVALID_ARGUMENT', message: 'filter is required' };
144
+ }
145
+ try {
146
+ const response = await this.automationBridge.sendAutomationRequest('cleanup', { filter: params.filter }, { timeoutMs: 60000 });
147
+ if (response && response.success !== false) {
148
+ const result = response.result ?? {};
149
+ const removedActors = result.removedActors ?? response.removedActors ?? [];
150
+ const removedCount = result.removed ?? removedActors.length;
151
+ return {
152
+ success: true,
153
+ removed: removedCount,
154
+ removedActors,
155
+ message: response.message || result.message || `Cleanup completed (removed=${removedCount})`
156
+ };
157
+ }
158
+ return {
159
+ success: false,
160
+ error: response?.error ?? 'CLEANUP_FAILED',
161
+ message: response?.message ?? 'Niagara cleanup failed'
162
+ };
163
+ }
164
+ catch (error) {
165
+ const message = error instanceof Error ? error.message : String(error);
166
+ return { success: false, error: `Failed to cleanup Niagara effects: ${message}` };
59
167
  }
60
168
  }
61
- /**
62
- * Add Emitter to System (left as-is; console commands may be placeholders)
63
- */
64
169
  async addEmitter(params) {
170
+ if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
171
+ return { success: false, error: 'AUTOMATION_BRIDGE_UNAVAILABLE', message: 'addEmitter requires automation bridge' };
172
+ }
173
+ if (params.properties) {
174
+ const zeroVector = [0, 0, 0];
175
+ if (params.properties.velocityMin) {
176
+ const processed = wasmIntegration.vectorAdd(zeroVector, params.properties.velocityMin);
177
+ console.error('[WASM] Using vectorAdd for Niagara velocity min');
178
+ params.properties.velocityMin = [processed[0], processed[1], processed[2]];
179
+ }
180
+ if (params.properties.velocityMax) {
181
+ const processed = wasmIntegration.vectorAdd(zeroVector, params.properties.velocityMax);
182
+ console.error('[WASM] Using vectorAdd for Niagara velocity max');
183
+ params.properties.velocityMax = [processed[0], processed[1], processed[2]];
184
+ }
185
+ }
65
186
  try {
66
- const commands = [
67
- `AddNiagaraEmitter ${params.systemName} ${params.emitterName} ${params.emitterType}`
68
- ];
69
- if (params.properties) {
70
- const props = params.properties;
71
- if (props.spawnRate !== undefined) {
72
- commands.push(`SetEmitterSpawnRate ${params.systemName} ${params.emitterName} ${props.spawnRate}`);
73
- }
74
- if (props.lifetime !== undefined) {
75
- commands.push(`SetEmitterLifetime ${params.systemName} ${params.emitterName} ${props.lifetime}`);
76
- }
77
- if (props.velocityMin && props.velocityMax) {
78
- const min = props.velocityMin;
79
- const max = props.velocityMax;
80
- commands.push(`SetEmitterVelocity ${params.systemName} ${params.emitterName} ${min[0]} ${min[1]} ${min[2]} ${max[0]} ${max[1]} ${max[2]}`);
81
- }
82
- if (props.size !== undefined) {
83
- commands.push(`SetEmitterSize ${params.systemName} ${params.emitterName} ${props.size}`);
84
- }
85
- if (props.color) {
86
- const color = props.color;
87
- commands.push(`SetEmitterColor ${params.systemName} ${params.emitterName} ${color[0]} ${color[1]} ${color[2]} ${color[3]}`);
88
- }
89
- if (props.material) {
90
- commands.push(`SetEmitterMaterial ${params.systemName} ${params.emitterName} ${props.material}`);
91
- }
92
- if (props.mesh && params.emitterType === 'Mesh') {
93
- commands.push(`SetEmitterMesh ${params.systemName} ${params.emitterName} ${props.mesh}`);
94
- }
187
+ const resp = await this.automationBridge.sendAutomationRequest('manage_niagara_graph', {
188
+ subAction: 'add_emitter',
189
+ systemName: params.systemName,
190
+ emitterName: params.emitterName,
191
+ emitterType: params.emitterType,
192
+ properties: params.properties
193
+ });
194
+ if (resp && resp.success !== false) {
195
+ return {
196
+ success: true,
197
+ message: resp.message || `Emitter ${params.emitterName} added to ${params.systemName}`,
198
+ emitterId: resp.result?.emitterId
199
+ };
95
200
  }
96
- await this.bridge.executeConsoleCommands(commands);
97
- return { success: true, message: `Emitter ${params.emitterName} added to ${params.systemName}` };
201
+ return {
202
+ success: false,
203
+ error: resp?.error || 'ADD_EMITTER_FAILED',
204
+ message: resp?.message || 'Failed to add emitter'
205
+ };
98
206
  }
99
- catch (err) {
100
- return { success: false, error: `Failed to add emitter: ${err}` };
207
+ catch (e) {
208
+ const message = e instanceof Error ? e.message : String(e);
209
+ return { success: false, error: 'ADD_EMITTER_FAILED', message };
101
210
  }
102
211
  }
212
+ async addModule(params) {
213
+ if (!params.systemPath)
214
+ return { success: false, error: 'INVALID_SYSTEM_PATH', message: 'System path is required' };
215
+ if (!params.modulePath)
216
+ return { success: false, error: 'INVALID_MODULE_PATH', message: 'Module path is required' };
217
+ const res = await this.automationBridge?.sendAutomationRequest('manage_niagara_graph', {
218
+ subAction: 'add_module',
219
+ assetPath: params.systemPath,
220
+ modulePath: params.modulePath,
221
+ emitterName: params.emitterName,
222
+ scriptType: params.scriptType
223
+ });
224
+ return res;
225
+ }
226
+ async connectPins(params) {
227
+ if (!params.systemPath)
228
+ return { success: false, error: 'INVALID_SYSTEM_PATH', message: 'System path is required' };
229
+ const res = await this.automationBridge?.sendAutomationRequest('manage_niagara_graph', {
230
+ subAction: 'connect_pins',
231
+ assetPath: params.systemPath,
232
+ fromNode: params.fromNodeId,
233
+ fromPin: params.fromPinName,
234
+ toNode: params.toNodeId,
235
+ toPin: params.toPinName,
236
+ emitterName: params.emitterName,
237
+ scriptType: params.scriptType
238
+ });
239
+ return res;
240
+ }
241
+ async removeNode(params) {
242
+ if (!params.systemPath)
243
+ return { success: false, error: 'INVALID_SYSTEM_PATH', message: 'System path is required' };
244
+ if (!params.nodeId)
245
+ return { success: false, error: 'INVALID_NODE_ID', message: 'Node ID is required' };
246
+ const res = await this.automationBridge?.sendAutomationRequest('manage_niagara_graph', {
247
+ subAction: 'remove_node',
248
+ assetPath: params.systemPath,
249
+ nodeId: params.nodeId,
250
+ emitterName: params.emitterName,
251
+ scriptType: params.scriptType
252
+ });
253
+ return res;
254
+ }
103
255
  async setParameter(params) {
104
256
  try {
105
- const paramType = params.isUserParameter ? 'User' : 'System';
106
- let valueStr = '';
107
- switch (params.parameterType) {
108
- case 'Float':
109
- case 'Int':
110
- case 'Bool':
111
- valueStr = String(params.value);
112
- break;
113
- case 'Vector': {
114
- const v = params.value;
115
- valueStr = `${v[0]} ${v[1]} ${v[2]}`;
116
- break;
117
- }
118
- case 'Color': {
119
- const c = params.value;
120
- valueStr = `${c[0]} ${c[1]} ${c[2]} ${c[3] || 1}`;
121
- break;
122
- }
257
+ const automationBridge = this.bridge.automationBridge;
258
+ if (!automationBridge) {
259
+ return { success: false, error: 'Automation bridge not available' };
123
260
  }
124
- const command = `SetNiagara${paramType}Parameter ${params.systemName} ${params.parameterName} ${params.parameterType} ${valueStr}`;
125
- await this.bridge.executeConsoleCommand(command);
126
- return { success: true, message: `Parameter ${params.parameterName} set on ${params.systemName}` };
261
+ const resp = await automationBridge.sendAutomationRequest('set_niagara_parameter', {
262
+ systemName: params.systemName,
263
+ parameterName: params.parameterName,
264
+ parameterType: params.parameterType,
265
+ value: params.value,
266
+ isUserParameter: params.isUserParameter === true
267
+ });
268
+ if (resp && resp.success !== false)
269
+ return { success: true, message: resp.message || `Parameter ${params.parameterName} set on ${params.systemName}`, applied: resp.applied ?? resp.result?.applied };
270
+ return { success: false, message: resp?.message ?? 'Set parameter failed', error: resp?.error ?? 'SET_PARAMETER_FAILED' };
127
271
  }
128
272
  catch (err) {
129
273
  return { success: false, error: `Failed to set parameter: ${err}` };
130
274
  }
131
275
  }
132
- /**
133
- * Create Preset Effect (now creates a real Niagara system asset)
134
- */
135
276
  async createEffect(params) {
136
277
  try {
137
- // Validate effect type at runtime (inputs can come from JSON)
138
- const allowedTypes = ['Fire', 'Smoke', 'Explosion', 'Water', 'Rain', 'Snow', 'Magic', 'Lightning', 'Dust', 'Steam'];
278
+ const allowedTypes = ['Fire', 'Smoke', 'Explosion', 'Water', 'Rain', 'Snow', 'Magic', 'Lightning', 'Dust', 'Steam', 'Default'];
139
279
  if (!params || !allowedTypes.includes(String(params.effectType))) {
140
280
  return { success: false, error: `Invalid effectType: ${String(params?.effectType)}` };
141
281
  }
142
- // Sanitize and validate name and path
143
282
  const defaultPath = '/Game/Effects/Niagara';
144
283
  const nameToUse = sanitizeAssetName(params.name);
145
284
  const validation = validateAssetParams({ name: nameToUse, savePath: defaultPath });
@@ -149,31 +288,10 @@ else:
149
288
  const safeName = validation.sanitized.name;
150
289
  const savePath = validation.sanitized.savePath || defaultPath;
151
290
  const fullPath = `${savePath}/${safeName}`;
152
- // Create or ensure the Niagara system asset exists
153
291
  const createRes = await this.createSystem({ name: safeName, savePath, template: 'Empty' });
154
292
  if (!createRes.success) {
155
293
  return { success: false, error: createRes.error || 'Failed creating Niagara system' };
156
294
  }
157
- // Verify existence via Python to avoid RC EditorAssetLibrary issues
158
- const verifyPy = `
159
- import unreal
160
- import json
161
-
162
- p = r"${fullPath}"
163
- exists = bool(unreal.EditorAssetLibrary.does_asset_exist(p))
164
- print('RESULT:' + json.dumps({'success': True, 'exists': exists}))
165
- `.trim();
166
- const verifyResp = await this.bridge.executePython(verifyPy);
167
- const verifyResult = interpretStandardResult(verifyResp, {
168
- successMessage: 'Niagara asset verification complete',
169
- failureMessage: `Failed to verify Niagara asset at ${fullPath}`
170
- });
171
- if (!verifyResult.success) {
172
- return { success: false, error: verifyResult.error ?? verifyResult.message };
173
- }
174
- if (verifyResult.payload.exists === false) {
175
- return { success: false, error: `Asset not found after creation: ${fullPath}` };
176
- }
177
295
  return { success: true, message: `${params.effectType} effect ${safeName} created`, path: fullPath };
178
296
  }
179
297
  catch (err) {
@@ -204,62 +322,29 @@ print('RESULT:' + json.dumps({'success': True, 'exists': exists}))
204
322
  return { success: false, error: `Failed to create GPU simulation: ${err}` };
205
323
  }
206
324
  }
207
- /**
208
- * Spawn Niagara Effect in Level using Python (NiagaraActor)
209
- */
210
325
  async spawnEffect(params) {
211
326
  try {
212
327
  const loc = Array.isArray(params.location) ? { x: params.location[0], y: params.location[1], z: params.location[2] } : params.location;
213
- const rot = params.rotation || [0, 0, 0];
214
- const scl = Array.isArray(params.scale) ? params.scale : (typeof params.scale === 'number' ? [params.scale, params.scale, params.scale] : [1, 1, 1]);
215
- const py = `
216
- import unreal
217
- import json
218
-
219
- loc = unreal.Vector(${loc.x || 0}, ${loc.y || 0}, ${loc.z || 0})
220
- rot = unreal.Rotator(${rot[0]}, ${rot[1]}, ${rot[2]})
221
- scale = unreal.Vector(${scl[0]}, ${scl[1]}, ${scl[2]})
222
- sys_path = r"${params.systemPath}"
223
-
224
- if unreal.EditorAssetLibrary.does_asset_exist(sys_path):
225
- sys = unreal.EditorAssetLibrary.load_asset(sys_path)
226
- actor_subsystem = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
227
- actor = actor_subsystem.spawn_actor_from_class(unreal.NiagaraActor, loc, rot)
228
- if actor:
229
- comp = actor.get_niagara_component()
230
- try:
231
- comp.set_asset(sys)
232
- except Exception:
233
- try:
234
- comp.set_editor_property('asset', sys)
235
- except Exception:
236
- pass
237
- comp.set_world_scale3d(scale)
238
- comp.activate(True)
239
- actor.set_actor_label(f"Niagara_{unreal.SystemLibrary.get_game_time_in_seconds(actor.get_world()):.0f}")
240
- print('RESULT:' + json.dumps({'success': True, 'actor': actor.get_actor_label()}))
241
- else:
242
- print('RESULT:' + json.dumps({'success': False, 'error': 'Failed to spawn NiagaraActor'}))
243
- else:
244
- print('RESULT:' + json.dumps({'success': False, 'error': 'System asset not found'}))
245
- `.trim();
246
- const resp = await this.bridge.executePython(py);
247
- const interpreted = interpretStandardResult(resp, {
248
- successMessage: 'Niagara effect spawned',
249
- failureMessage: 'Failed to spawn Niagara effect'
250
- });
251
- const actorLabel = coerceString(interpreted.payload.actor);
252
- if (!interpreted.success) {
253
- return { success: false, error: interpreted.error ?? interpreted.message };
254
- }
255
- const outcome = {
256
- success: true,
257
- message: interpreted.message
258
- };
259
- if (actorLabel) {
260
- outcome.actor = actorLabel;
328
+ if (this.automationBridge && typeof this.automationBridge.sendAutomationRequest === 'function') {
329
+ try {
330
+ const resp = await this.automationBridge.sendAutomationRequest('spawn_niagara', {
331
+ systemPath: params.systemPath,
332
+ location: [loc.x ?? 0, loc.y ?? 0, loc.z ?? 0],
333
+ rotation: params.rotation,
334
+ scale: params.scale,
335
+ autoDestroy: params.autoDestroy,
336
+ attachToActor: params.attachToActor
337
+ });
338
+ if (resp && resp.success !== false) {
339
+ return { success: true, message: resp.message || 'Niagara effect spawned', actor: resp.actor || resp.result?.actor || resp.result?.actorName };
340
+ }
341
+ return { success: false, message: resp?.message ?? 'Spawn failed', error: resp?.error ?? 'SPAWN_FAILED' };
342
+ }
343
+ catch (error) {
344
+ return { success: false, error: `Failed to spawn effect: ${error instanceof Error ? error.message : String(error)}` };
345
+ }
261
346
  }
262
- return outcome;
347
+ throw new Error('Automation Bridge not available. Niagara effect spawning requires plugin support.');
263
348
  }
264
349
  catch (err) {
265
350
  return { success: false, error: `Failed to spawn effect: ${err}` };
@@ -1,7 +1,11 @@
1
1
  import { UnrealBridge } from '../unreal-bridge.js';
2
+ import { AutomationBridge } from '../automation/index.js';
2
3
  export declare class PerformanceTools {
3
4
  private bridge;
4
- constructor(bridge: UnrealBridge);
5
+ private log;
6
+ private automationBridge?;
7
+ constructor(bridge: UnrealBridge, automationBridge?: AutomationBridge);
8
+ setAutomationBridge(automationBridge?: AutomationBridge): void;
5
9
  startProfiling(params: {
6
10
  type: 'CPU' | 'GPU' | 'Memory' | 'RenderThread' | 'GameThread' | 'All';
7
11
  duration?: number;
@@ -17,6 +21,12 @@ export declare class PerformanceTools {
17
21
  enabled: boolean;
18
22
  verbose?: boolean;
19
23
  }): Promise<{
24
+ success: boolean;
25
+ message: string;
26
+ fpsVisible: boolean;
27
+ command?: undefined;
28
+ error?: undefined;
29
+ } | {
20
30
  success: boolean;
21
31
  message: string;
22
32
  fpsVisible: boolean;
@@ -38,25 +48,19 @@ export declare class PerformanceTools {
38
48
  level: 0 | 1 | 2 | 3 | 4;
39
49
  }): Promise<{
40
50
  success: boolean;
41
- error: string;
42
- message?: undefined;
43
- verified?: undefined;
44
- readback?: undefined;
51
+ message: string;
52
+ error?: undefined;
45
53
  method?: undefined;
46
54
  } | {
47
55
  success: boolean;
48
- message: string;
49
- verified: boolean;
50
- readback: number;
51
- method: string;
52
- error?: undefined;
56
+ error: string;
57
+ message?: undefined;
58
+ method?: undefined;
53
59
  } | {
54
60
  success: boolean;
55
61
  message: string;
56
62
  method: string;
57
63
  error?: undefined;
58
- verified?: undefined;
59
- readback?: undefined;
60
64
  }>;
61
65
  setResolutionScale(params: {
62
66
  scale: number;
@@ -86,6 +90,11 @@ export declare class PerformanceTools {
86
90
  }): Promise<{
87
91
  success: boolean;
88
92
  message: string;
93
+ error?: undefined;
94
+ } | {
95
+ success: boolean;
96
+ error: string;
97
+ message?: undefined;
89
98
  }>;
90
99
  configureTextureStreaming(params: {
91
100
  enabled: boolean;
@@ -122,11 +131,16 @@ export declare class PerformanceTools {
122
131
  }>;
123
132
  optimizeDrawCalls(params: {
124
133
  enableInstancing?: boolean;
125
- enableBatching?: boolean;
126
134
  mergeActors?: boolean;
135
+ actors?: string[];
127
136
  }): Promise<{
137
+ success: boolean;
138
+ error: string;
139
+ message?: undefined;
140
+ } | {
128
141
  success: boolean;
129
142
  message: string;
143
+ error?: undefined;
130
144
  }>;
131
145
  configureOcclusionCulling(params: {
132
146
  enabled: boolean;