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
@@ -0,0 +1,383 @@
1
+ import { cleanObject } from '../../utils/safe-json.js';
2
+ import { executeAutomationRequest } from './common-handlers.js';
3
+ import { normalizeArgs, resolveObjectPath } from './argument-helper.js';
4
+ async function resolveComponentObjectPathFromArgs(args, tools) {
5
+ const componentName = typeof args.componentName === 'string' ? args.componentName.trim() : '';
6
+ const componentPath = typeof args.componentPath === 'string' ? args.componentPath.trim() : '';
7
+ const direct = componentPath || ((componentName.includes(':') || componentName.includes('.')) &&
8
+ (componentName.startsWith('/Game') || componentName.startsWith('/Script') || componentName.startsWith('/Engine'))
9
+ ? componentName
10
+ : '');
11
+ if (direct)
12
+ return direct;
13
+ const actorName = await resolveObjectPath(args, tools, { pathKeys: [], actorKeys: ['actorName', 'name', 'objectPath'] });
14
+ if (!actorName) {
15
+ throw new Error('Invalid actorName: required to resolve componentName');
16
+ }
17
+ if (!componentName) {
18
+ throw new Error('Invalid componentName: must be a non-empty string');
19
+ }
20
+ const compsRes = await executeAutomationRequest(tools, 'inspect', {
21
+ action: 'get_components',
22
+ actorName: actorName,
23
+ objectPath: actorName
24
+ }, 'Failed to get components');
25
+ let components = [];
26
+ if (compsRes.success) {
27
+ components = Array.isArray(compsRes?.components) ? compsRes.components : [];
28
+ }
29
+ const needle = componentName.toLowerCase();
30
+ if (components.length > 0) {
31
+ let match = components.find((c) => String(c?.name || '').toLowerCase() === needle)
32
+ ?? components.find((c) => String(c?.path || '').toLowerCase() === needle)
33
+ ?? components.find((c) => String(c?.path || '').toLowerCase().endsWith(`:${needle}`))
34
+ ?? components.find((c) => String(c?.path || '').toLowerCase().endsWith(`.${needle}`));
35
+ if (!match) {
36
+ match = components.find((c) => String(c?.name || '').toLowerCase().startsWith(needle));
37
+ }
38
+ if (match) {
39
+ if (typeof match.path === 'string' && match.path.trim().length > 0) {
40
+ return match.path.trim();
41
+ }
42
+ if (typeof match.name === 'string' && match.name.trim().length > 0) {
43
+ return `${actorName}.${match.name}`;
44
+ }
45
+ }
46
+ }
47
+ return `${actorName}.${componentName}`;
48
+ }
49
+ export async function handleInspectTools(action, args, tools) {
50
+ switch (action) {
51
+ case 'inspect_object': {
52
+ const objectPath = await resolveObjectPath(args, tools);
53
+ if (!objectPath) {
54
+ throw new Error('Invalid objectPath: must be a non-empty string');
55
+ }
56
+ const payload = {
57
+ ...args,
58
+ objectPath,
59
+ action: 'inspect_object',
60
+ detailed: true
61
+ };
62
+ const res = await executeAutomationRequest(tools, 'inspect', payload, 'Automation bridge not available for inspect operations');
63
+ if (res && res.success === false) {
64
+ const errorCode = String(res.error || '').toUpperCase();
65
+ const msg = String(res.message || '');
66
+ if (errorCode === 'OBJECT_NOT_FOUND' || msg.toLowerCase().includes('object not found')) {
67
+ return cleanObject({
68
+ success: false,
69
+ handled: true,
70
+ notFound: true,
71
+ error: res.error,
72
+ message: res.message || 'Object not found'
73
+ });
74
+ }
75
+ }
76
+ return cleanObject(res);
77
+ }
78
+ case 'get_property': {
79
+ const objectPath = await resolveObjectPath(args, tools);
80
+ const propertyName = normalizeArgs(args, [{ key: 'propertyName', aliases: ['propertyPath'], required: true }]).propertyName;
81
+ if (!objectPath) {
82
+ throw new Error('Invalid objectPath: must be a non-empty string');
83
+ }
84
+ const res = await tools.introspectionTools.getProperty({
85
+ objectPath,
86
+ propertyName
87
+ });
88
+ if (!res.success && (res.error === 'PROPERTY_NOT_FOUND' || String(res.error).includes('not found'))) {
89
+ const actorName = await resolveObjectPath(args, tools, { pathKeys: [], actorKeys: ['actorName', 'name', 'objectPath'] });
90
+ if (actorName) {
91
+ const triedPaths = [];
92
+ try {
93
+ const rootRes = await tools.introspectionTools.getProperty({
94
+ objectPath: actorName,
95
+ propertyName: 'RootComponent'
96
+ });
97
+ const rootPath = typeof rootRes.value === 'string' ? rootRes.value : (rootRes.value?.path || rootRes.value?.objectPath);
98
+ if (rootRes.success && rootPath && typeof rootPath === 'string' && rootPath.length > 0 && rootPath !== 'None') {
99
+ triedPaths.push(rootPath);
100
+ const propRes = await tools.introspectionTools.getProperty({
101
+ objectPath: rootPath,
102
+ propertyName
103
+ });
104
+ if (propRes.success) {
105
+ return cleanObject({
106
+ ...propRes,
107
+ message: `Resolved property '${propertyName}' on RootComponent (Smart Lookup)`,
108
+ foundOnComponent: 'RootComponent'
109
+ });
110
+ }
111
+ }
112
+ }
113
+ catch (_e) { }
114
+ try {
115
+ const shortName = String(args.objectPath || '').trim();
116
+ const compsRes = await tools.actorTools.getComponents(shortName);
117
+ if (compsRes.success && (Array.isArray(compsRes.components) || Array.isArray(compsRes))) {
118
+ const list = Array.isArray(compsRes.components) ? compsRes.components : (Array.isArray(compsRes) ? compsRes : []);
119
+ const triedPaths = [];
120
+ for (const comp of list) {
121
+ const compName = comp.name;
122
+ const compPath = comp.path || (compName ? `${actorName}.${compName}` : undefined);
123
+ if (!compPath)
124
+ continue;
125
+ triedPaths.push(compPath);
126
+ const compRes = await tools.introspectionTools.getProperty({
127
+ objectPath: compPath,
128
+ propertyName
129
+ });
130
+ if (compRes.success) {
131
+ return cleanObject({
132
+ ...compRes,
133
+ message: `Resolved property '${propertyName}' on component '${comp.name}' (Smart Lookup)`,
134
+ foundOnComponent: comp.name
135
+ });
136
+ }
137
+ }
138
+ return cleanObject({
139
+ ...res,
140
+ message: res.message + ` (Smart Lookup failed. Tried: ${triedPaths.length} paths. First: ${triedPaths[0]}. Components: ${list.map((c) => c.name).join(',')})`,
141
+ smartLookupTriedPaths: triedPaths
142
+ });
143
+ }
144
+ else {
145
+ return cleanObject({
146
+ ...res,
147
+ message: res.message + ' (Smart Lookup failed: get_components returned ' + (compsRes.success ? 'success but no list' : 'failure: ' + compsRes.error) + ' | Name: ' + shortName + ' Path: ' + actorName + ')',
148
+ smartLookupGetComponentsError: compsRes
149
+ });
150
+ }
151
+ }
152
+ catch (_e) {
153
+ return cleanObject({
154
+ ...res,
155
+ message: res.message + ' (Smart Lookup exception: ' + _e.message + ')',
156
+ error: _e
157
+ });
158
+ }
159
+ }
160
+ }
161
+ return cleanObject(res);
162
+ }
163
+ case 'set_property': {
164
+ const objectPath = await resolveObjectPath(args, tools);
165
+ const params = normalizeArgs(args, [
166
+ { key: 'propertyName', aliases: ['propertyPath'], required: true },
167
+ { key: 'value' }
168
+ ]);
169
+ if (!objectPath) {
170
+ throw new Error('Invalid objectPath: must be a non-empty string');
171
+ }
172
+ const res = await tools.introspectionTools.setProperty({
173
+ objectPath,
174
+ propertyName: params.propertyName,
175
+ value: params.value
176
+ });
177
+ if (res && res.success === false) {
178
+ const errorCode = String(res.error || '').toUpperCase();
179
+ if (errorCode === 'PROPERTY_NOT_FOUND') {
180
+ return cleanObject({
181
+ ...res,
182
+ error: 'UNKNOWN_PROPERTY'
183
+ });
184
+ }
185
+ }
186
+ return cleanObject(res);
187
+ }
188
+ case 'get_components': {
189
+ const actorName = await resolveObjectPath(args, tools, { pathKeys: [], actorKeys: ['actorName', 'name', 'objectPath'] });
190
+ if (!actorName) {
191
+ throw new Error('Invalid actorName');
192
+ }
193
+ const res = await executeAutomationRequest(tools, 'inspect', {
194
+ action: 'get_components',
195
+ actorName: actorName,
196
+ objectPath: actorName
197
+ }, 'Failed to get components');
198
+ return cleanObject(res);
199
+ }
200
+ case 'get_component_property': {
201
+ const componentObjectPath = await resolveComponentObjectPathFromArgs(args, tools);
202
+ const params = normalizeArgs(args, [
203
+ { key: 'propertyName', aliases: ['propertyPath'], required: true }
204
+ ]);
205
+ const res = await tools.introspectionTools.getProperty({
206
+ objectPath: componentObjectPath,
207
+ propertyName: params.propertyName
208
+ });
209
+ return cleanObject(res);
210
+ }
211
+ case 'set_component_property': {
212
+ const componentObjectPath = await resolveComponentObjectPathFromArgs(args, tools);
213
+ const params = normalizeArgs(args, [
214
+ { key: 'propertyName', aliases: ['propertyPath'], required: true },
215
+ { key: 'value' }
216
+ ]);
217
+ const res = await tools.introspectionTools.setProperty({
218
+ objectPath: componentObjectPath,
219
+ propertyName: params.propertyName,
220
+ value: params.value
221
+ });
222
+ return cleanObject(res);
223
+ }
224
+ case 'get_metadata': {
225
+ const actorName = await resolveObjectPath(args, tools);
226
+ if (!actorName)
227
+ throw new Error('Invalid actorName');
228
+ return cleanObject(await tools.actorTools.getMetadata(actorName));
229
+ }
230
+ case 'add_tag': {
231
+ const actorName = await resolveObjectPath(args, tools);
232
+ const params = normalizeArgs(args, [
233
+ { key: 'tag', required: true }
234
+ ]);
235
+ if (!actorName)
236
+ throw new Error('Invalid actorName');
237
+ return cleanObject(await tools.actorTools.addTag({
238
+ actorName,
239
+ tag: params.tag
240
+ }));
241
+ }
242
+ case 'find_by_tag':
243
+ const params = normalizeArgs(args, [{ key: 'tag' }]);
244
+ return cleanObject(await tools.actorTools.findByTag({
245
+ tag: params.tag
246
+ }));
247
+ case 'create_snapshot': {
248
+ const actorName = await resolveObjectPath(args, tools);
249
+ if (!actorName)
250
+ throw new Error('actorName is required for create_snapshot');
251
+ return cleanObject(await tools.actorTools.createSnapshot({
252
+ actorName,
253
+ snapshotName: args.snapshotName
254
+ }));
255
+ }
256
+ case 'restore_snapshot': {
257
+ const actorName = await resolveObjectPath(args, tools);
258
+ if (!actorName)
259
+ throw new Error('actorName is required for restore_snapshot');
260
+ return cleanObject(await tools.actorTools.restoreSnapshot({
261
+ actorName,
262
+ snapshotName: args.snapshotName
263
+ }));
264
+ }
265
+ case 'export': {
266
+ const actorName = await resolveObjectPath(args, tools);
267
+ if (!actorName)
268
+ throw new Error('actorName may be required for export depending on context (exporting actor requires it)');
269
+ const params = normalizeArgs(args, [
270
+ { key: 'destinationPath', aliases: ['outputPath'] }
271
+ ]);
272
+ return cleanObject(await tools.actorTools.exportActor({
273
+ actorName: actorName || '',
274
+ destinationPath: params.destinationPath
275
+ }));
276
+ }
277
+ case 'delete_object': {
278
+ const actorName = await resolveObjectPath(args, tools);
279
+ try {
280
+ if (!actorName)
281
+ throw new Error('actorName is required for delete_object');
282
+ const res = await tools.actorTools.delete({
283
+ actorName
284
+ });
285
+ return cleanObject(res);
286
+ }
287
+ catch (err) {
288
+ const msg = String(err?.message || err || '');
289
+ const lower = msg.toLowerCase();
290
+ if (lower.includes('actor not found')) {
291
+ return cleanObject({
292
+ success: false,
293
+ error: 'NOT_FOUND',
294
+ handled: true,
295
+ message: msg,
296
+ deleted: actorName,
297
+ notFound: true
298
+ });
299
+ }
300
+ throw err;
301
+ }
302
+ }
303
+ case 'list_objects':
304
+ return cleanObject(await tools.actorTools.listActors(args));
305
+ case 'find_by_class': {
306
+ const params = normalizeArgs(args, [
307
+ { key: 'className', aliases: ['classPath'], required: true }
308
+ ]);
309
+ const res = await tools.introspectionTools.findObjectsByClass(params.className);
310
+ if (!res || res.success === false) {
311
+ return cleanObject({
312
+ success: false,
313
+ error: res?.error || 'OPERATION_FAILED',
314
+ message: res?.message || 'find_by_class failed',
315
+ className: params.className,
316
+ objects: [],
317
+ count: 0
318
+ });
319
+ }
320
+ return cleanObject(res);
321
+ }
322
+ case 'get_bounding_box': {
323
+ const actorName = await resolveObjectPath(args, tools);
324
+ try {
325
+ if (!actorName)
326
+ throw new Error('actorName is required for get_bounding_box');
327
+ const res = await tools.actorTools.getBoundingBox(actorName);
328
+ return cleanObject(res);
329
+ }
330
+ catch (err) {
331
+ const msg = String(err?.message || err || '');
332
+ const lower = msg.toLowerCase();
333
+ if (lower.includes('actor not found')) {
334
+ return cleanObject({
335
+ success: false,
336
+ error: 'NOT_FOUND',
337
+ handled: true,
338
+ message: msg,
339
+ actorName,
340
+ notFound: true
341
+ });
342
+ }
343
+ throw err;
344
+ }
345
+ }
346
+ case 'inspect_class': {
347
+ const params = normalizeArgs(args, [
348
+ { key: 'className', aliases: ['classPath'], required: true }
349
+ ]);
350
+ let className = params.className;
351
+ if (className && !className.includes('/') && !className.includes('.')) {
352
+ if (className === 'Landscape') {
353
+ className = '/Script/Landscape.Landscape';
354
+ }
355
+ else if (['Actor', 'Pawn', 'Character', 'StaticMeshActor'].includes(className)) {
356
+ className = `/Script/Engine.${className}`;
357
+ }
358
+ }
359
+ const res = await tools.introspectionTools.getCDO(className);
360
+ if (!res || res.success === false) {
361
+ if (args.className && !args.className.includes('/') && !className.startsWith('/Script/')) {
362
+ const retryName = `/Script/Engine.${args.className}`;
363
+ const resRetry = await tools.introspectionTools.getCDO(retryName);
364
+ if (resRetry && resRetry.success) {
365
+ return cleanObject(resRetry);
366
+ }
367
+ }
368
+ return cleanObject({
369
+ success: false,
370
+ error: res?.error || 'OPERATION_FAILED',
371
+ message: res?.message || `inspect_class failed for '${className}'`,
372
+ className,
373
+ cdo: res?.cdo ?? null
374
+ });
375
+ }
376
+ return cleanObject(res);
377
+ }
378
+ default:
379
+ const res = await executeAutomationRequest(tools, 'inspect', args, 'Automation bridge not available for inspect operations');
380
+ return cleanObject(res);
381
+ }
382
+ }
383
+ //# sourceMappingURL=inspect-handlers.js.map
@@ -0,0 +1,3 @@
1
+ import { ITools } from '../../types/tool-interfaces.js';
2
+ export declare function handleLevelTools(action: string, args: any, tools: ITools): Promise<any>;
3
+ //# sourceMappingURL=level-handlers.d.ts.map
@@ -0,0 +1,237 @@
1
+ import { cleanObject } from '../../utils/safe-json.js';
2
+ import { executeAutomationRequest, requireNonEmptyString } from './common-handlers.js';
3
+ export async function handleLevelTools(action, args, tools) {
4
+ switch (action) {
5
+ case 'load':
6
+ case 'load_level': {
7
+ const levelPath = requireNonEmptyString(args.levelPath, 'levelPath', 'Missing required parameter: levelPath');
8
+ const res = await tools.levelTools.loadLevel({ levelPath, streaming: !!args.streaming });
9
+ return cleanObject(res);
10
+ }
11
+ case 'save': {
12
+ const targetPath = args.levelPath || args.savePath;
13
+ if (targetPath) {
14
+ const res = await tools.levelTools.saveLevelAs({ targetPath });
15
+ return cleanObject(res);
16
+ }
17
+ const res = await tools.levelTools.saveLevel({ levelName: args.levelName });
18
+ return cleanObject(res);
19
+ }
20
+ case 'save_as':
21
+ case 'save_level_as': {
22
+ const targetPath = args.savePath || args.destinationPath || args.levelPath;
23
+ if (!targetPath) {
24
+ return {
25
+ success: false,
26
+ error: 'INVALID_ARGUMENT',
27
+ message: 'savePath is required for save_as action',
28
+ action
29
+ };
30
+ }
31
+ const res = await tools.levelTools.saveLevelAs({ targetPath });
32
+ return cleanObject(res);
33
+ }
34
+ case 'create_level': {
35
+ const levelName = requireNonEmptyString(args.levelName || (args.levelPath ? args.levelPath.split('/').pop() : ''), 'levelName', 'Missing required parameter: levelName');
36
+ const res = await tools.levelTools.createLevel({ levelName, savePath: args.savePath || args.levelPath });
37
+ return cleanObject(res);
38
+ }
39
+ case 'add_sublevel': {
40
+ const subLevelPath = requireNonEmptyString(args.subLevelPath || args.levelPath, 'subLevelPath', 'Missing required parameter: subLevelPath');
41
+ const res = await tools.levelTools.addSubLevel({
42
+ subLevelPath,
43
+ parentLevel: args.parentLevel || args.parentPath,
44
+ streamingMethod: args.streamingMethod
45
+ });
46
+ return cleanObject(res);
47
+ }
48
+ case 'stream': {
49
+ const levelPath = typeof args.levelPath === 'string' ? args.levelPath : undefined;
50
+ const levelName = typeof args.levelName === 'string' ? args.levelName : undefined;
51
+ if (!levelPath && !levelName) {
52
+ return cleanObject({
53
+ success: false,
54
+ error: 'INVALID_ARGUMENT',
55
+ message: 'Missing required parameter: levelPath (or levelName)',
56
+ action
57
+ });
58
+ }
59
+ if (typeof args.shouldBeLoaded !== 'boolean') {
60
+ return cleanObject({
61
+ success: false,
62
+ error: 'INVALID_ARGUMENT',
63
+ message: 'Missing required parameter: shouldBeLoaded (boolean)',
64
+ action,
65
+ levelPath,
66
+ levelName
67
+ });
68
+ }
69
+ const res = await tools.levelTools.streamLevel({
70
+ levelPath,
71
+ levelName,
72
+ shouldBeLoaded: args.shouldBeLoaded,
73
+ shouldBeVisible: args.shouldBeVisible
74
+ });
75
+ return cleanObject(res);
76
+ }
77
+ case 'create_light': {
78
+ const res = await executeAutomationRequest(tools, 'manage_level', args);
79
+ return cleanObject(res);
80
+ }
81
+ case 'spawn_light': {
82
+ const lightClassMap = {
83
+ 'Point': '/Script/Engine.PointLight',
84
+ 'Directional': '/Script/Engine.DirectionalLight',
85
+ 'Spot': '/Script/Engine.SpotLight',
86
+ 'Sky': '/Script/Engine.SkyLight',
87
+ 'Rect': '/Script/Engine.RectLight'
88
+ };
89
+ const lightType = args.lightType || 'Point';
90
+ const classPath = lightClassMap[lightType] || '/Script/Engine.PointLight';
91
+ try {
92
+ const res = await tools.actorTools.spawn({
93
+ classPath,
94
+ actorName: args.name,
95
+ location: args.location,
96
+ rotation: args.rotation
97
+ });
98
+ return { ...cleanObject(res), action: 'spawn_light' };
99
+ }
100
+ catch (_e) {
101
+ return await executeAutomationRequest(tools, 'manage_level', args);
102
+ }
103
+ }
104
+ case 'build_lighting': {
105
+ return cleanObject(await tools.lightingTools.buildLighting({
106
+ quality: args.quality || 'Preview',
107
+ buildOnlySelected: false,
108
+ buildReflectionCaptures: false
109
+ }));
110
+ }
111
+ case 'export_level': {
112
+ const res = await tools.levelTools.exportLevel({
113
+ levelPath: args.levelPath,
114
+ exportPath: args.exportPath || args.destinationPath,
115
+ timeoutMs: typeof args.timeoutMs === 'number' ? args.timeoutMs : undefined
116
+ });
117
+ return cleanObject(res);
118
+ }
119
+ case 'import_level': {
120
+ const res = await tools.levelTools.importLevel({
121
+ packagePath: args.packagePath || args.sourcePath,
122
+ destinationPath: args.destinationPath,
123
+ timeoutMs: typeof args.timeoutMs === 'number' ? args.timeoutMs : undefined
124
+ });
125
+ return cleanObject(res);
126
+ }
127
+ case 'list_levels': {
128
+ const res = await tools.levelTools.listLevels();
129
+ return cleanObject(res);
130
+ }
131
+ case 'get_summary': {
132
+ const res = await tools.levelTools.getLevelSummary(args.levelPath);
133
+ return cleanObject(res);
134
+ }
135
+ case 'delete': {
136
+ const levelPaths = Array.isArray(args.levelPaths) ? args.levelPaths : [args.levelPath];
137
+ const res = await tools.levelTools.deleteLevels({ levelPaths });
138
+ return cleanObject(res);
139
+ }
140
+ case 'set_metadata': {
141
+ const levelPath = requireNonEmptyString(args.levelPath, 'levelPath', 'Missing required parameter: levelPath');
142
+ const metadata = (args.metadata && typeof args.metadata === 'object') ? args.metadata : {};
143
+ const res = await executeAutomationRequest(tools, 'set_metadata', { assetPath: levelPath, metadata });
144
+ return cleanObject(res);
145
+ }
146
+ case 'load_cells': {
147
+ let origin = args.origin;
148
+ let extent = args.extent;
149
+ if (!origin && args.min && args.max) {
150
+ const min = args.min;
151
+ const max = args.max;
152
+ origin = [(min[0] + max[0]) / 2, (min[1] + max[1]) / 2, (min[2] + max[2]) / 2];
153
+ extent = [(max[0] - min[0]) / 2, (max[1] - min[1]) / 2, (max[2] - min[2]) / 2];
154
+ }
155
+ const payload = {
156
+ subAction: 'load_cells',
157
+ origin: origin,
158
+ extent: extent,
159
+ ...args
160
+ };
161
+ const res = await executeAutomationRequest(tools, 'manage_world_partition', payload);
162
+ return cleanObject(res);
163
+ }
164
+ case 'set_datalayer': {
165
+ const dataLayerName = args.dataLayerName || args.dataLayerLabel;
166
+ if (!dataLayerName || typeof dataLayerName !== 'string' || dataLayerName.trim().length === 0) {
167
+ return cleanObject({
168
+ success: false,
169
+ error: 'INVALID_ARGUMENT',
170
+ message: 'Missing required parameter: dataLayerLabel (or dataLayerName)',
171
+ action
172
+ });
173
+ }
174
+ if (!args.dataLayerState || typeof args.dataLayerState !== 'string') {
175
+ return cleanObject({
176
+ success: false,
177
+ error: 'INVALID_ARGUMENT',
178
+ message: 'Missing required parameter: dataLayerState',
179
+ action,
180
+ dataLayerName
181
+ });
182
+ }
183
+ const res = await executeAutomationRequest(tools, 'manage_world_partition', {
184
+ subAction: 'set_datalayer',
185
+ actorPath: args.actorPath,
186
+ dataLayerName,
187
+ ...args
188
+ });
189
+ return cleanObject(res);
190
+ }
191
+ case 'cleanup_invalid_datalayers': {
192
+ const res = await executeAutomationRequest(tools, 'manage_world_partition', {
193
+ subAction: 'cleanup_invalid_datalayers'
194
+ }, 'World Partition support not available');
195
+ return cleanObject(res);
196
+ }
197
+ case 'validate_level': {
198
+ const levelPath = requireNonEmptyString(args.levelPath, 'levelPath', 'Missing required parameter: levelPath');
199
+ const automationBridge = tools.automationBridge;
200
+ if (!automationBridge || typeof automationBridge.sendAutomationRequest !== 'function' || !automationBridge.isConnected()) {
201
+ return cleanObject({
202
+ success: false,
203
+ error: 'BRIDGE_UNAVAILABLE',
204
+ message: 'Automation bridge not available; cannot validate level asset',
205
+ levelPath
206
+ });
207
+ }
208
+ try {
209
+ const resp = await automationBridge.sendAutomationRequest('execute_editor_function', {
210
+ functionName: 'ASSET_EXISTS_SIMPLE',
211
+ path: levelPath
212
+ });
213
+ const result = resp?.result ?? resp ?? {};
214
+ const exists = Boolean(result.exists);
215
+ return cleanObject({
216
+ success: true,
217
+ exists,
218
+ levelPath: result.path ?? levelPath,
219
+ classPath: result.class,
220
+ error: exists ? undefined : 'NOT_FOUND',
221
+ message: exists ? 'Level asset exists' : 'Level asset not found'
222
+ });
223
+ }
224
+ catch (err) {
225
+ return cleanObject({
226
+ success: false,
227
+ error: 'VALIDATION_FAILED',
228
+ message: `Level validation failed: ${err instanceof Error ? err.message : String(err)}`,
229
+ levelPath
230
+ });
231
+ }
232
+ }
233
+ default:
234
+ return await executeAutomationRequest(tools, 'manage_level', args);
235
+ }
236
+ }
237
+ //# sourceMappingURL=level-handlers.js.map
@@ -0,0 +1,3 @@
1
+ import { ITools } from '../../types/tool-interfaces.js';
2
+ export declare function handleLightingTools(action: string, args: any, tools: ITools): Promise<any>;
3
+ //# sourceMappingURL=lighting-handlers.d.ts.map