unreal-engine-mcp-server 0.5.4 → 0.5.5

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 (468) hide show
  1. package/dist/automation/bridge.d.ts.map +1 -0
  2. package/dist/automation/bridge.js.map +1 -0
  3. package/dist/automation/connection-manager.d.ts.map +1 -0
  4. package/dist/automation/connection-manager.js.map +1 -0
  5. package/dist/automation/handshake.d.ts.map +1 -0
  6. package/dist/automation/handshake.js.map +1 -0
  7. package/dist/automation/index.d.ts.map +1 -0
  8. package/dist/automation/index.js.map +1 -0
  9. package/dist/automation/message-handler.d.ts.map +1 -0
  10. package/dist/automation/message-handler.js.map +1 -0
  11. package/dist/automation/request-tracker.d.ts.map +1 -0
  12. package/dist/automation/request-tracker.js.map +1 -0
  13. package/dist/automation/types.d.ts.map +1 -0
  14. package/dist/automation/types.js.map +1 -0
  15. package/dist/cli.d.ts.map +1 -0
  16. package/dist/cli.js +4 -3
  17. package/dist/cli.js.map +1 -0
  18. package/dist/config/class-aliases.d.ts.map +1 -0
  19. package/dist/config/class-aliases.js.map +1 -0
  20. package/dist/config.d.ts.map +1 -0
  21. package/dist/config.js.map +1 -0
  22. package/dist/constants.d.ts.map +1 -0
  23. package/dist/constants.js.map +1 -0
  24. package/dist/graphql/loaders.d.ts.map +1 -0
  25. package/dist/graphql/loaders.js.map +1 -0
  26. package/dist/graphql/resolvers.d.ts.map +1 -0
  27. package/dist/graphql/resolvers.js +29 -29
  28. package/dist/graphql/resolvers.js.map +1 -0
  29. package/dist/graphql/schema.d.ts.map +1 -0
  30. package/dist/graphql/schema.js.map +1 -0
  31. package/dist/graphql/server.d.ts.map +1 -0
  32. package/dist/graphql/server.js.map +1 -0
  33. package/dist/graphql/types.d.ts.map +1 -0
  34. package/dist/graphql/types.js.map +1 -0
  35. package/dist/handlers/resource-handlers.d.ts.map +1 -0
  36. package/dist/handlers/resource-handlers.js.map +1 -0
  37. package/dist/index.d.ts +1 -0
  38. package/dist/index.d.ts.map +1 -0
  39. package/dist/index.js +64 -7
  40. package/dist/index.js.map +1 -0
  41. package/dist/resources/actors.d.ts.map +1 -0
  42. package/dist/resources/actors.js.map +1 -0
  43. package/dist/resources/assets.d.ts.map +1 -0
  44. package/dist/resources/assets.js +6 -4
  45. package/dist/resources/assets.js.map +1 -0
  46. package/dist/resources/levels.d.ts.map +1 -0
  47. package/dist/resources/levels.js.map +1 -0
  48. package/dist/server/resource-registry.d.ts.map +1 -0
  49. package/dist/server/resource-registry.js.map +1 -0
  50. package/dist/server/tool-registry.d.ts.map +1 -0
  51. package/dist/server/tool-registry.js.map +1 -0
  52. package/dist/server-setup.d.ts.map +1 -0
  53. package/dist/server-setup.js.map +1 -0
  54. package/dist/services/health-monitor.d.ts.map +1 -0
  55. package/dist/services/health-monitor.js.map +1 -0
  56. package/dist/services/metrics-server.d.ts.map +1 -0
  57. package/dist/services/metrics-server.js.map +1 -0
  58. package/dist/tools/actors.d.ts.map +1 -0
  59. package/dist/tools/actors.js +3 -1
  60. package/dist/tools/actors.js.map +1 -0
  61. package/dist/tools/animation.d.ts.map +1 -0
  62. package/dist/tools/animation.js +2 -2
  63. package/dist/tools/animation.js.map +1 -0
  64. package/dist/tools/assets.d.ts.map +1 -0
  65. package/dist/tools/assets.js.map +1 -0
  66. package/dist/tools/audio.d.ts.map +1 -0
  67. package/dist/tools/audio.js.map +1 -0
  68. package/dist/tools/base-tool.d.ts.map +1 -0
  69. package/dist/tools/base-tool.js.map +1 -0
  70. package/dist/tools/behavior-tree.d.ts.map +1 -0
  71. package/dist/tools/behavior-tree.js.map +1 -0
  72. package/dist/tools/blueprint.d.ts.map +1 -0
  73. package/dist/tools/blueprint.js +4 -2
  74. package/dist/tools/blueprint.js.map +1 -0
  75. package/dist/tools/consolidated-tool-definitions.d.ts.map +1 -0
  76. package/dist/tools/consolidated-tool-definitions.js.map +1 -0
  77. package/dist/tools/consolidated-tool-handlers.d.ts.map +1 -0
  78. package/dist/tools/consolidated-tool-handlers.js.map +1 -0
  79. package/dist/tools/debug.d.ts.map +1 -0
  80. package/dist/tools/debug.js +3 -1
  81. package/dist/tools/debug.js.map +1 -0
  82. package/dist/tools/dynamic-handler-registry.d.ts.map +1 -0
  83. package/dist/tools/dynamic-handler-registry.js +3 -1
  84. package/dist/tools/dynamic-handler-registry.js.map +1 -0
  85. package/dist/tools/editor.d.ts.map +1 -0
  86. package/dist/tools/editor.js +1 -1
  87. package/dist/tools/editor.js.map +1 -0
  88. package/dist/tools/engine.d.ts.map +1 -0
  89. package/dist/tools/engine.js.map +1 -0
  90. package/dist/tools/environment.d.ts.map +1 -0
  91. package/dist/tools/environment.js +2 -2
  92. package/dist/tools/environment.js.map +1 -0
  93. package/dist/tools/foliage.d.ts.map +1 -0
  94. package/dist/tools/foliage.js.map +1 -0
  95. package/dist/tools/handlers/actor-handlers.d.ts +1 -1
  96. package/dist/tools/handlers/actor-handlers.d.ts.map +1 -0
  97. package/dist/tools/handlers/actor-handlers.js +6 -5
  98. package/dist/tools/handlers/actor-handlers.js.map +1 -0
  99. package/dist/tools/handlers/animation-handlers.d.ts.map +1 -0
  100. package/dist/tools/handlers/animation-handlers.js.map +1 -0
  101. package/dist/tools/handlers/argument-helper.d.ts.map +1 -0
  102. package/dist/tools/handlers/argument-helper.js.map +1 -0
  103. package/dist/tools/handlers/asset-handlers.d.ts.map +1 -0
  104. package/dist/tools/handlers/asset-handlers.js +5 -1
  105. package/dist/tools/handlers/asset-handlers.js.map +1 -0
  106. package/dist/tools/handlers/audio-handlers.d.ts.map +1 -0
  107. package/dist/tools/handlers/audio-handlers.js.map +1 -0
  108. package/dist/tools/handlers/blueprint-handlers.d.ts.map +1 -0
  109. package/dist/tools/handlers/blueprint-handlers.js +2 -1
  110. package/dist/tools/handlers/blueprint-handlers.js.map +1 -0
  111. package/dist/tools/handlers/common-handlers.d.ts.map +1 -0
  112. package/dist/tools/handlers/common-handlers.js.map +1 -0
  113. package/dist/tools/handlers/editor-handlers.d.ts.map +1 -0
  114. package/dist/tools/handlers/editor-handlers.js +12 -2
  115. package/dist/tools/handlers/editor-handlers.js.map +1 -0
  116. package/dist/tools/handlers/effect-handlers.d.ts.map +1 -0
  117. package/dist/tools/handlers/effect-handlers.js.map +1 -0
  118. package/dist/tools/handlers/environment-handlers.d.ts.map +1 -0
  119. package/dist/tools/handlers/environment-handlers.js.map +1 -0
  120. package/dist/tools/handlers/graph-handlers.d.ts.map +1 -0
  121. package/dist/tools/handlers/graph-handlers.js +61 -1
  122. package/dist/tools/handlers/graph-handlers.js.map +1 -0
  123. package/dist/tools/handlers/input-handlers.d.ts.map +1 -0
  124. package/dist/tools/handlers/input-handlers.js.map +1 -0
  125. package/dist/tools/handlers/inspect-handlers.d.ts.map +1 -0
  126. package/dist/tools/handlers/inspect-handlers.js.map +1 -0
  127. package/dist/tools/handlers/level-handlers.d.ts.map +1 -0
  128. package/dist/tools/handlers/level-handlers.js.map +1 -0
  129. package/dist/tools/handlers/lighting-handlers.d.ts.map +1 -0
  130. package/dist/tools/handlers/lighting-handlers.js +23 -1
  131. package/dist/tools/handlers/lighting-handlers.js.map +1 -0
  132. package/dist/tools/handlers/performance-handlers.d.ts.map +1 -0
  133. package/dist/tools/handlers/performance-handlers.js +15 -2
  134. package/dist/tools/handlers/performance-handlers.js.map +1 -0
  135. package/dist/tools/handlers/pipeline-handlers.d.ts.map +1 -0
  136. package/dist/tools/handlers/pipeline-handlers.js.map +1 -0
  137. package/dist/tools/handlers/sequence-handlers.d.ts.map +1 -0
  138. package/dist/tools/handlers/sequence-handlers.js.map +1 -0
  139. package/dist/tools/handlers/system-handlers.d.ts.map +1 -0
  140. package/dist/tools/handlers/system-handlers.js +16 -1
  141. package/dist/tools/handlers/system-handlers.js.map +1 -0
  142. package/dist/tools/input.d.ts.map +1 -0
  143. package/dist/tools/input.js +3 -1
  144. package/dist/tools/input.js.map +1 -0
  145. package/dist/tools/introspection.d.ts.map +1 -0
  146. package/dist/tools/introspection.js.map +1 -0
  147. package/dist/tools/landscape.d.ts.map +1 -0
  148. package/dist/tools/landscape.js +3 -1
  149. package/dist/tools/landscape.js.map +1 -0
  150. package/dist/tools/level.d.ts.map +1 -0
  151. package/dist/tools/level.js.map +1 -0
  152. package/dist/tools/lighting.d.ts.map +1 -0
  153. package/dist/tools/lighting.js +3 -1
  154. package/dist/tools/lighting.js.map +1 -0
  155. package/dist/tools/logs.d.ts.map +1 -0
  156. package/dist/tools/logs.js.map +1 -0
  157. package/dist/tools/materials.d.ts.map +1 -0
  158. package/dist/tools/materials.js +3 -1
  159. package/dist/tools/materials.js.map +1 -0
  160. package/dist/tools/niagara.d.ts.map +1 -0
  161. package/dist/tools/niagara.js +7 -5
  162. package/dist/tools/niagara.js.map +1 -0
  163. package/dist/tools/performance.d.ts.map +1 -0
  164. package/dist/tools/performance.js.map +1 -0
  165. package/dist/tools/physics.d.ts.map +1 -0
  166. package/dist/tools/physics.js +9 -7
  167. package/dist/tools/physics.js.map +1 -0
  168. package/dist/tools/property-dictionary.d.ts.map +1 -0
  169. package/dist/tools/property-dictionary.js.map +1 -0
  170. package/dist/tools/sequence.d.ts.map +1 -0
  171. package/dist/tools/sequence.js +3 -1
  172. package/dist/tools/sequence.js.map +1 -0
  173. package/dist/tools/tool-definition-utils.d.ts.map +1 -0
  174. package/dist/tools/tool-definition-utils.js.map +1 -0
  175. package/dist/tools/ui.d.ts.map +1 -0
  176. package/dist/tools/ui.js +3 -1
  177. package/dist/tools/ui.js.map +1 -0
  178. package/dist/types/automation-responses.d.ts.map +1 -0
  179. package/dist/types/automation-responses.js.map +1 -0
  180. package/dist/types/env.d.ts.map +1 -0
  181. package/dist/types/env.js.map +1 -0
  182. package/dist/types/handler-types.d.ts.map +1 -0
  183. package/dist/types/handler-types.js.map +1 -0
  184. package/dist/types/tool-interfaces.d.ts.map +1 -0
  185. package/dist/types/tool-interfaces.js.map +1 -0
  186. package/dist/types/tool-types.d.ts.map +1 -0
  187. package/dist/types/tool-types.js.map +1 -0
  188. package/dist/unreal-bridge.d.ts +1 -0
  189. package/dist/unreal-bridge.d.ts.map +1 -0
  190. package/dist/unreal-bridge.js +8 -0
  191. package/dist/unreal-bridge.js.map +1 -0
  192. package/dist/utils/command-validator.d.ts.map +1 -0
  193. package/dist/utils/command-validator.js.map +1 -0
  194. package/dist/utils/elicitation.d.ts.map +1 -0
  195. package/dist/utils/elicitation.js.map +1 -0
  196. package/dist/utils/error-handler.d.ts.map +1 -0
  197. package/dist/utils/error-handler.js.map +1 -0
  198. package/dist/utils/ini-reader.d.ts.map +1 -0
  199. package/dist/utils/ini-reader.js.map +1 -0
  200. package/dist/utils/logger.d.ts.map +1 -0
  201. package/dist/utils/logger.js.map +1 -0
  202. package/dist/utils/normalize.d.ts.map +1 -0
  203. package/dist/utils/normalize.js.map +1 -0
  204. package/dist/utils/path-security.d.ts.map +1 -0
  205. package/dist/utils/path-security.js.map +1 -0
  206. package/dist/utils/response-factory.d.ts.map +1 -0
  207. package/dist/utils/response-factory.js +3 -1
  208. package/dist/utils/response-factory.js.map +1 -0
  209. package/dist/utils/response-validator.d.ts.map +1 -0
  210. package/dist/utils/response-validator.js.map +1 -0
  211. package/dist/utils/result-helpers.d.ts.map +1 -0
  212. package/dist/utils/result-helpers.js.map +1 -0
  213. package/dist/utils/safe-json.d.ts.map +1 -0
  214. package/dist/utils/safe-json.js.map +1 -0
  215. package/dist/utils/unreal-command-queue.d.ts.map +1 -0
  216. package/dist/utils/unreal-command-queue.js.map +1 -0
  217. package/dist/utils/validation.d.ts.map +1 -0
  218. package/dist/utils/validation.js.map +1 -0
  219. package/dist/wasm/index.d.ts.map +1 -0
  220. package/dist/wasm/index.js.map +1 -0
  221. package/package.json +12 -34
  222. package/server.json +2 -2
  223. package/.dockerignore +0 -57
  224. package/.env.example +0 -26
  225. package/.env.production +0 -61
  226. package/.eslintrc.json +0 -0
  227. package/.eslintrc.override.json +0 -8
  228. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -94
  229. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  230. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -56
  231. package/.github/copilot-instructions.md +0 -478
  232. package/.github/dependabot.yml +0 -19
  233. package/.github/labeler.yml +0 -24
  234. package/.github/labels.yml +0 -70
  235. package/.github/pull_request_template.md +0 -42
  236. package/.github/release-drafter-config.yml +0 -51
  237. package/.github/workflows/auto-merge.yml +0 -38
  238. package/.github/workflows/ci.yml +0 -38
  239. package/.github/workflows/dependency-review.yml +0 -17
  240. package/.github/workflows/gemini-issue-triage.yml +0 -172
  241. package/.github/workflows/greetings.yml +0 -27
  242. package/.github/workflows/labeler.yml +0 -17
  243. package/.github/workflows/links.yml +0 -80
  244. package/.github/workflows/pr-size-labeler.yml +0 -137
  245. package/.github/workflows/publish-mcp.yml +0 -79
  246. package/.github/workflows/release-drafter.yml +0 -24
  247. package/.github/workflows/release.yml +0 -112
  248. package/.github/workflows/semantic-pull-request.yml +0 -35
  249. package/.github/workflows/smoke-test.yml +0 -36
  250. package/.github/workflows/stale.yml +0 -28
  251. package/CONTRIBUTING.md +0 -140
  252. package/Dockerfile +0 -37
  253. package/GEMINI.md +0 -115
  254. package/Public/Plugin_setup_guide.mp4 +0 -0
  255. package/Public/icon.png +0 -0
  256. package/claude_desktop_config_example.json +0 -15
  257. package/dist/types/responses.d.ts +0 -249
  258. package/dist/types/responses.js +0 -2
  259. package/docs/GraphQL-API.md +0 -888
  260. package/docs/Migration-Guide-v0.5.0.md +0 -684
  261. package/docs/Roadmap.md +0 -53
  262. package/docs/WebAssembly-Integration.md +0 -628
  263. package/docs/editor-plugin-extension.md +0 -370
  264. package/docs/handler-mapping.md +0 -249
  265. package/docs/native-automation-progress.md +0 -128
  266. package/docs/testing-guide.md +0 -423
  267. package/eslint.config.mjs +0 -68
  268. package/mcp-config-example.json +0 -14
  269. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +0 -8
  270. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +0 -64
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +0 -189
  272. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +0 -22
  273. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +0 -30
  274. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +0 -1983
  275. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +0 -72
  276. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +0 -46
  277. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +0 -846
  278. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +0 -2393
  279. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +0 -300
  280. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +0 -2807
  281. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +0 -1087
  282. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +0 -488
  283. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +0 -643
  284. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +0 -31
  285. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +0 -1094
  286. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +0 -5750
  287. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +0 -152
  288. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +0 -2614
  289. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +0 -42
  290. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +0 -1237
  291. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +0 -1725
  292. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +0 -2265
  293. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +0 -954
  294. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +0 -209
  295. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +0 -41
  296. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +0 -1164
  297. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +0 -762
  298. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +0 -663
  299. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +0 -136
  300. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +0 -494
  301. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +0 -278
  302. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +0 -625
  303. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +0 -401
  304. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +0 -67
  305. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +0 -472
  306. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +0 -2634
  307. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +0 -189
  308. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +0 -917
  309. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +0 -39
  310. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +0 -2706
  311. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +0 -519
  312. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +0 -38
  313. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +0 -668
  314. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +0 -346
  315. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +0 -1345
  316. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +0 -149
  317. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -782
  318. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +0 -115
  319. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +0 -796
  320. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +0 -117
  321. package/scripts/check-unreal-connection.mjs +0 -19
  322. package/scripts/clean-tmp.js +0 -23
  323. package/scripts/patch-wasm.js +0 -26
  324. package/scripts/run-all-tests.mjs +0 -136
  325. package/scripts/smoke-test.ts +0 -94
  326. package/scripts/sync-mcp-plugin.js +0 -143
  327. package/scripts/test-no-plugin-alternates.mjs +0 -113
  328. package/scripts/validate-server.js +0 -46
  329. package/scripts/verify-automation-bridge.js +0 -200
  330. package/src/automation/bridge.ts +0 -630
  331. package/src/automation/connection-manager.ts +0 -148
  332. package/src/automation/handshake.ts +0 -99
  333. package/src/automation/index.ts +0 -2
  334. package/src/automation/message-handler.ts +0 -192
  335. package/src/automation/request-tracker.ts +0 -155
  336. package/src/automation/types.ts +0 -108
  337. package/src/cli.ts +0 -34
  338. package/src/config/class-aliases.ts +0 -65
  339. package/src/config.ts +0 -73
  340. package/src/constants.ts +0 -29
  341. package/src/graphql/loaders.ts +0 -244
  342. package/src/graphql/resolvers.ts +0 -1008
  343. package/src/graphql/schema.ts +0 -452
  344. package/src/graphql/server.ts +0 -156
  345. package/src/graphql/types.ts +0 -10
  346. package/src/handlers/resource-handlers.ts +0 -186
  347. package/src/index.ts +0 -243
  348. package/src/resources/actors.ts +0 -127
  349. package/src/resources/assets.ts +0 -286
  350. package/src/resources/levels.ts +0 -68
  351. package/src/server/resource-registry.ts +0 -47
  352. package/src/server/tool-registry.ts +0 -354
  353. package/src/server-setup.ts +0 -114
  354. package/src/services/health-monitor.ts +0 -132
  355. package/src/services/metrics-server.ts +0 -176
  356. package/src/tools/actors.ts +0 -564
  357. package/src/tools/animation.ts +0 -941
  358. package/src/tools/assets.ts +0 -394
  359. package/src/tools/audio.ts +0 -499
  360. package/src/tools/base-tool.ts +0 -52
  361. package/src/tools/behavior-tree.ts +0 -45
  362. package/src/tools/blueprint.ts +0 -940
  363. package/src/tools/consolidated-tool-definitions.ts +0 -1256
  364. package/src/tools/consolidated-tool-handlers.ts +0 -302
  365. package/src/tools/debug.ts +0 -622
  366. package/src/tools/dynamic-handler-registry.ts +0 -33
  367. package/src/tools/editor.ts +0 -435
  368. package/src/tools/engine.ts +0 -43
  369. package/src/tools/environment.ts +0 -281
  370. package/src/tools/foliage.ts +0 -596
  371. package/src/tools/handlers/actor-handlers.ts +0 -244
  372. package/src/tools/handlers/animation-handlers.ts +0 -237
  373. package/src/tools/handlers/argument-helper.ts +0 -142
  374. package/src/tools/handlers/asset-handlers.ts +0 -550
  375. package/src/tools/handlers/audio-handlers.ts +0 -194
  376. package/src/tools/handlers/blueprint-handlers.ts +0 -380
  377. package/src/tools/handlers/common-handlers.ts +0 -108
  378. package/src/tools/handlers/editor-handlers.ts +0 -124
  379. package/src/tools/handlers/effect-handlers.ts +0 -224
  380. package/src/tools/handlers/environment-handlers.ts +0 -183
  381. package/src/tools/handlers/graph-handlers.ts +0 -117
  382. package/src/tools/handlers/input-handlers.ts +0 -28
  383. package/src/tools/handlers/inspect-handlers.ts +0 -450
  384. package/src/tools/handlers/level-handlers.ts +0 -253
  385. package/src/tools/handlers/lighting-handlers.ts +0 -151
  386. package/src/tools/handlers/performance-handlers.ts +0 -132
  387. package/src/tools/handlers/pipeline-handlers.ts +0 -194
  388. package/src/tools/handlers/sequence-handlers.ts +0 -438
  389. package/src/tools/handlers/system-handlers.ts +0 -564
  390. package/src/tools/input.ts +0 -160
  391. package/src/tools/introspection.ts +0 -689
  392. package/src/tools/landscape.ts +0 -649
  393. package/src/tools/level.ts +0 -989
  394. package/src/tools/lighting.ts +0 -1052
  395. package/src/tools/logs.ts +0 -219
  396. package/src/tools/materials.ts +0 -295
  397. package/src/tools/niagara.ts +0 -485
  398. package/src/tools/performance.ts +0 -661
  399. package/src/tools/physics.ts +0 -679
  400. package/src/tools/property-dictionary.ts +0 -98
  401. package/src/tools/sequence.ts +0 -385
  402. package/src/tools/tool-definition-utils.ts +0 -35
  403. package/src/tools/ui.ts +0 -452
  404. package/src/types/automation-responses.ts +0 -119
  405. package/src/types/env.ts +0 -17
  406. package/src/types/handler-types.ts +0 -442
  407. package/src/types/responses.ts +0 -355
  408. package/src/types/tool-interfaces.ts +0 -250
  409. package/src/types/tool-types.ts +0 -575
  410. package/src/unreal-bridge.ts +0 -693
  411. package/src/utils/command-validator.ts +0 -139
  412. package/src/utils/elicitation.ts +0 -132
  413. package/src/utils/error-handler.ts +0 -287
  414. package/src/utils/ini-reader.ts +0 -86
  415. package/src/utils/logger.ts +0 -35
  416. package/src/utils/normalize.test.ts +0 -162
  417. package/src/utils/normalize.ts +0 -146
  418. package/src/utils/path-security.ts +0 -43
  419. package/src/utils/response-factory.ts +0 -44
  420. package/src/utils/response-validator.ts +0 -395
  421. package/src/utils/result-helpers.ts +0 -195
  422. package/src/utils/safe-json.test.ts +0 -90
  423. package/src/utils/safe-json.ts +0 -70
  424. package/src/utils/unreal-command-queue.ts +0 -166
  425. package/src/utils/validation.test.ts +0 -184
  426. package/src/utils/validation.ts +0 -312
  427. package/src/wasm/index.ts +0 -838
  428. package/test-server.mjs +0 -100
  429. package/tests/test-animation.mjs +0 -369
  430. package/tests/test-asset-advanced.mjs +0 -82
  431. package/tests/test-asset-graph.mjs +0 -311
  432. package/tests/test-audio.mjs +0 -417
  433. package/tests/test-automation-timeouts.mjs +0 -98
  434. package/tests/test-behavior-tree.mjs +0 -444
  435. package/tests/test-blueprint-graph.mjs +0 -410
  436. package/tests/test-blueprint.mjs +0 -577
  437. package/tests/test-client-mode.mjs +0 -86
  438. package/tests/test-console-command.mjs +0 -56
  439. package/tests/test-control-actor.mjs +0 -425
  440. package/tests/test-control-editor.mjs +0 -112
  441. package/tests/test-graphql.mjs +0 -372
  442. package/tests/test-input.mjs +0 -349
  443. package/tests/test-inspect.mjs +0 -302
  444. package/tests/test-landscape.mjs +0 -316
  445. package/tests/test-lighting.mjs +0 -428
  446. package/tests/test-manage-asset.mjs +0 -438
  447. package/tests/test-manage-level.mjs +0 -89
  448. package/tests/test-materials.mjs +0 -356
  449. package/tests/test-niagara.mjs +0 -185
  450. package/tests/test-no-inline-python.mjs +0 -122
  451. package/tests/test-performance.mjs +0 -539
  452. package/tests/test-plugin-handshake.mjs +0 -82
  453. package/tests/test-runner.mjs +0 -993
  454. package/tests/test-sequence.mjs +0 -104
  455. package/tests/test-system.mjs +0 -96
  456. package/tests/test-wasm.mjs +0 -283
  457. package/tests/test-world-partition.mjs +0 -215
  458. package/tsconfig.json +0 -56
  459. package/vitest.config.ts +0 -35
  460. package/wasm/Cargo.lock +0 -363
  461. package/wasm/Cargo.toml +0 -42
  462. package/wasm/LICENSE +0 -21
  463. package/wasm/README.md +0 -253
  464. package/wasm/src/dependency_resolver.rs +0 -377
  465. package/wasm/src/lib.rs +0 -153
  466. package/wasm/src/property_parser.rs +0 -271
  467. package/wasm/src/transform_math.rs +0 -396
  468. package/wasm/tests/integration.rs +0 -109
@@ -1,1052 +0,0 @@
1
- // Lighting tools for Unreal Engine using Automation Bridge
2
- import { UnrealBridge } from '../unreal-bridge.js';
3
- import { AutomationBridge } from '../automation/index.js';
4
- import { ensureVector3 } from '../utils/validation.js';
5
- import { wasmIntegration } from '../wasm/index.js';
6
-
7
- export class LightingTools {
8
- constructor(private bridge: UnrealBridge, private automationBridge?: AutomationBridge) { }
9
-
10
- setAutomationBridge(automationBridge?: AutomationBridge) { this.automationBridge = automationBridge; }
11
-
12
-
13
- private normalizeName(value: unknown, defaultName?: string): string {
14
- if (typeof value === 'string') {
15
- const trimmed = value.trim();
16
- if (trimmed.length > 0) {
17
- return trimmed;
18
- }
19
- }
20
-
21
- if (typeof defaultName === 'string') {
22
- const trimmedDefault = defaultName.trim();
23
- if (trimmedDefault.length > 0) {
24
- return trimmedDefault;
25
- }
26
- }
27
-
28
- // Auto-generate if no name is provided
29
- return `Light_${Date.now()}_${Math.floor(Math.random() * 1000)}`;
30
- }
31
-
32
- /**
33
- * List available light types (classes)
34
- */
35
- async listLightTypes() {
36
- if (!this.automationBridge) {
37
- throw new Error('Automation Bridge required to list light types');
38
- }
39
- const response = await this.automationBridge.sendAutomationRequest('list_light_types', {});
40
- return response;
41
- }
42
-
43
- /**
44
- * Spawn a light actor using the Automation Bridge.
45
- * @param lightClass The Unreal light class name (e.g. 'DirectionalLight', 'PointLight')
46
- * @param params Light spawn parameters
47
- */
48
- private async spawnLightViaAutomation(
49
- lightClass: string,
50
- params: {
51
- name: string;
52
- location?: [number, number, number];
53
- rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
54
- properties?: Record<string, unknown>;
55
- }
56
- ) {
57
- if (!this.automationBridge) {
58
- throw new Error('Automation Bridge not available. Cannot spawn lights without plugin support.');
59
- }
60
-
61
- try {
62
- const payload: Record<string, unknown> = {
63
- lightClass,
64
- name: params.name,
65
- };
66
-
67
- if (params.location) {
68
- // Use WASM vectorAdd for light location processing
69
- const zeroVector: [number, number, number] = [0, 0, 0];
70
- const processedLocation = wasmIntegration.vectorAdd(zeroVector, params.location);
71
- console.error('[WASM] Using vectorAdd for light positioning');
72
- payload.location = { x: processedLocation[0], y: processedLocation[1], z: processedLocation[2] };
73
- }
74
-
75
- if (params.rotation) {
76
- if (Array.isArray(params.rotation)) {
77
- payload.rotation = { pitch: params.rotation[0], yaw: params.rotation[1], roll: params.rotation[2] };
78
- } else {
79
- payload.rotation = params.rotation;
80
- }
81
- }
82
-
83
- if (params.properties) {
84
- payload.properties = params.properties;
85
- }
86
-
87
- const response = await this.automationBridge.sendAutomationRequest('spawn_light', payload, {
88
- timeoutMs: 60000
89
- });
90
-
91
- if (response.success === false) {
92
- throw new Error(response.error || response.message || 'Failed to spawn light');
93
- }
94
-
95
- return response;
96
- } catch (error) {
97
- throw new Error(
98
- `Failed to spawn ${lightClass}: ${error instanceof Error ? error.message : String(error)}`
99
- );
100
- }
101
- }
102
-
103
- // Create directional light
104
- async createDirectionalLight(params: {
105
- name: string;
106
- intensity?: number;
107
- color?: [number, number, number];
108
- rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
109
- castShadows?: boolean;
110
- temperature?: number;
111
- useAsAtmosphereSunLight?: boolean;
112
- properties?: Record<string, unknown>;
113
- }) {
114
- const name = this.normalizeName(params.name);
115
- if (!this.automationBridge) {
116
- throw new Error('Automation Bridge required for light spawning');
117
- }
118
-
119
- // Validate numeric parameters
120
- if (params.intensity !== undefined) {
121
- if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
122
- throw new Error(`Invalid intensity value: ${params.intensity}`);
123
- }
124
- if (params.intensity < 0) {
125
- throw new Error('Invalid intensity: must be non-negative');
126
- }
127
- }
128
-
129
- if (params.temperature !== undefined) {
130
- if (typeof params.temperature !== 'number' || !isFinite(params.temperature)) {
131
- throw new Error(`Invalid temperature value: ${params.temperature}`);
132
- }
133
- }
134
-
135
- // Validate arrays
136
- if (params.color !== undefined) {
137
- if (!Array.isArray(params.color) || params.color.length !== 3) {
138
- throw new Error('Invalid color: must be an array [r,g,b]');
139
- }
140
- for (const c of params.color) {
141
- if (typeof c !== 'number' || !isFinite(c)) {
142
- throw new Error('Invalid color component: must be finite numbers');
143
- }
144
- }
145
- }
146
-
147
- if (params.rotation !== undefined) {
148
- if (Array.isArray(params.rotation)) {
149
- if (params.rotation.length !== 3) {
150
- throw new Error('Invalid rotation: must be an array [pitch,yaw,roll]');
151
- }
152
- for (const r of params.rotation) {
153
- if (typeof r !== 'number' || !isFinite(r)) {
154
- throw new Error('Invalid rotation component: must be finite numbers');
155
- }
156
- }
157
- }
158
- }
159
-
160
- const rot = params.rotation || [0, 0, 0];
161
-
162
- // Build properties for the light
163
- const properties: Record<string, unknown> = params.properties || {};
164
- if (params.intensity !== undefined) {
165
- properties.intensity = params.intensity;
166
- }
167
- if (params.color) {
168
- properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
169
- }
170
- if (params.castShadows !== undefined) {
171
- properties.castShadows = params.castShadows;
172
- }
173
- if (params.temperature !== undefined) {
174
- properties.temperature = params.temperature;
175
- }
176
- if (params.useAsAtmosphereSunLight !== undefined) {
177
- properties.useAsAtmosphereSunLight = params.useAsAtmosphereSunLight;
178
- }
179
-
180
- try {
181
- await this.spawnLightViaAutomation('DirectionalLight', {
182
- name,
183
- location: [0, 0, 500],
184
- rotation: rot,
185
- properties
186
- });
187
-
188
- return { success: true, message: `Directional light '${name}' spawned` };
189
- } catch (e: unknown) {
190
- // Don't mask errors as "not implemented" - report the actual error from the bridge
191
- return { success: false, error: `Failed to create directional light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
192
- }
193
- }
194
-
195
- // Create point light
196
- async createPointLight(params: {
197
- name: string;
198
- location?: [number, number, number];
199
- intensity?: number;
200
- radius?: number;
201
- color?: [number, number, number];
202
- falloffExponent?: number;
203
- castShadows?: boolean;
204
- rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
205
- }) {
206
- const name = this.normalizeName(params.name);
207
- if (!this.automationBridge) {
208
- throw new Error('Automation Bridge required for light spawning');
209
- }
210
-
211
- // Validate location array
212
- // Validate location array
213
- if (params.location !== undefined) {
214
- // Ensure location is valid array [x,y,z]
215
- try {
216
- params.location = ensureVector3(params.location, 'location');
217
- } catch (e) {
218
- throw new Error(`Invalid location: ${e instanceof Error ? e.message : String(e)}`);
219
- }
220
- }
221
-
222
- // Default location if not provided
223
- const location = params.location || [0, 0, 0];
224
-
225
- // Validate numeric parameters
226
- if (params.intensity !== undefined) {
227
- if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
228
- throw new Error(`Invalid intensity value: ${params.intensity}`);
229
- }
230
- if (params.intensity < 0) {
231
- throw new Error('Invalid intensity: must be non-negative');
232
- }
233
- }
234
- if (params.radius !== undefined) {
235
- if (typeof params.radius !== 'number' || !isFinite(params.radius)) {
236
- throw new Error(`Invalid radius value: ${params.radius}`);
237
- }
238
- if (params.radius < 0) {
239
- throw new Error('Invalid radius: must be non-negative');
240
- }
241
- }
242
- if (params.falloffExponent !== undefined) {
243
- if (typeof params.falloffExponent !== 'number' || !isFinite(params.falloffExponent)) {
244
- throw new Error(`Invalid falloffExponent value: ${params.falloffExponent}`);
245
- }
246
- }
247
-
248
- // Validate color array
249
- if (params.color !== undefined) {
250
- if (!Array.isArray(params.color) || params.color.length !== 3) {
251
- throw new Error('Invalid color: must be an array [r,g,b]');
252
- }
253
- for (const c of params.color) {
254
- if (typeof c !== 'number' || !isFinite(c)) {
255
- throw new Error('Invalid color component: must be finite numbers');
256
- }
257
- }
258
- }
259
-
260
- // Build properties for the light
261
- const properties: Record<string, unknown> = {};
262
- if (params.intensity !== undefined) {
263
- properties.intensity = params.intensity;
264
- }
265
- if (params.radius !== undefined) {
266
- properties.attenuationRadius = params.radius;
267
- }
268
- if (params.color) {
269
- properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
270
- }
271
- if (params.castShadows !== undefined) {
272
- properties.castShadows = params.castShadows;
273
- }
274
- if (params.falloffExponent !== undefined) {
275
- properties.lightFalloffExponent = params.falloffExponent;
276
- }
277
-
278
- try {
279
- await this.spawnLightViaAutomation('PointLight', {
280
- name,
281
- location,
282
- rotation: params.rotation,
283
- properties
284
- });
285
-
286
- return { success: true, message: `Point light '${name}' spawned at ${location.join(', ')}` };
287
- } catch (e: unknown) {
288
- // Don't mask errors as "not implemented" - report the actual error from the bridge
289
- return { success: false, error: `Failed to create point light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
290
- }
291
- }
292
-
293
- // Create spot light
294
- async createSpotLight(params: {
295
- name: string;
296
- location: [number, number, number];
297
- rotation: [number, number, number] | { pitch: number, yaw: number, roll: number };
298
- intensity?: number;
299
- innerCone?: number;
300
- outerCone?: number;
301
- radius?: number;
302
- color?: [number, number, number];
303
- castShadows?: boolean;
304
- }) {
305
- const name = this.normalizeName(params.name);
306
- if (!this.automationBridge) {
307
- throw new Error('Automation Bridge required for light spawning');
308
- }
309
-
310
- // Validate required location and rotation arrays
311
- if (!params.location || !Array.isArray(params.location) || params.location.length !== 3) {
312
- throw new Error('Invalid location: must be an array [x,y,z]');
313
- }
314
- for (const l of params.location) {
315
- if (typeof l !== 'number' || !isFinite(l)) {
316
- throw new Error('Invalid location component: must be finite numbers');
317
- }
318
- }
319
-
320
- if (!params.rotation) {
321
- throw new Error('Rotation is required');
322
- }
323
- if (Array.isArray(params.rotation)) {
324
- if (params.rotation.length !== 3) {
325
- throw new Error('Invalid rotation: must be an array [pitch,yaw,roll]');
326
- }
327
- for (const r of params.rotation) {
328
- if (typeof r !== 'number' || !isFinite(r)) {
329
- throw new Error('Invalid rotation component: must be finite numbers');
330
- }
331
- }
332
- }
333
-
334
- // Validate optional numeric parameters
335
- if (params.intensity !== undefined) {
336
- if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
337
- throw new Error(`Invalid intensity value: ${params.intensity}`);
338
- }
339
- if (params.intensity < 0) {
340
- throw new Error('Invalid intensity: must be non-negative');
341
- }
342
- }
343
-
344
- if (params.innerCone !== undefined) {
345
- if (typeof params.innerCone !== 'number' || !isFinite(params.innerCone)) {
346
- throw new Error(`Invalid innerCone value: ${params.innerCone}`);
347
- }
348
- if (params.innerCone < 0 || params.innerCone > 180) {
349
- throw new Error('Invalid innerCone: must be between 0 and 180 degrees');
350
- }
351
- }
352
-
353
- if (params.outerCone !== undefined) {
354
- if (typeof params.outerCone !== 'number' || !isFinite(params.outerCone)) {
355
- throw new Error(`Invalid outerCone value: ${params.outerCone}`);
356
- }
357
- if (params.outerCone < 0 || params.outerCone > 180) {
358
- throw new Error('Invalid outerCone: must be between 0 and 180 degrees');
359
- }
360
- }
361
-
362
- if (params.radius !== undefined) {
363
- if (typeof params.radius !== 'number' || !isFinite(params.radius)) {
364
- throw new Error(`Invalid radius value: ${params.radius}`);
365
- }
366
- if (params.radius < 0) {
367
- throw new Error('Invalid radius: must be non-negative');
368
- }
369
- }
370
-
371
- // Validate color array
372
- if (params.color !== undefined) {
373
- if (!Array.isArray(params.color) || params.color.length !== 3) {
374
- throw new Error('Invalid color: must be an array [r,g,b]');
375
- }
376
- for (const c of params.color) {
377
- if (typeof c !== 'number' || !isFinite(c)) {
378
- throw new Error('Invalid color component: must be finite numbers');
379
- }
380
- }
381
- }
382
- // Build properties for the light
383
- const properties: Record<string, unknown> = {};
384
- if (params.intensity !== undefined) {
385
- properties.intensity = params.intensity;
386
- }
387
- if (params.innerCone !== undefined) {
388
- properties.innerConeAngle = params.innerCone;
389
- }
390
- if (params.outerCone !== undefined) {
391
- properties.outerConeAngle = params.outerCone;
392
- }
393
- if (params.radius !== undefined) {
394
- properties.attenuationRadius = params.radius;
395
- }
396
- if (params.color) {
397
- properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
398
- }
399
- if (params.castShadows !== undefined) {
400
- properties.castShadows = params.castShadows;
401
- }
402
-
403
- try {
404
- await this.spawnLightViaAutomation('SpotLight', {
405
- name,
406
- location: params.location,
407
- rotation: params.rotation,
408
- properties
409
- });
410
-
411
- return { success: true, message: `Spot light '${name}' spawned at ${params.location.join(', ')}` };
412
- } catch (e: unknown) {
413
- // Don't mask errors as "not implemented" - report the actual error from the bridge
414
- return { success: false, error: `Failed to create spot light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
415
- }
416
- }
417
-
418
- // Create rect light
419
- async createRectLight(params: {
420
- name: string;
421
- location: [number, number, number];
422
- rotation: [number, number, number] | { pitch: number, yaw: number, roll: number };
423
- width?: number;
424
- height?: number;
425
- intensity?: number;
426
- color?: [number, number, number];
427
- castShadows?: boolean;
428
- }) {
429
-
430
- const name = this.normalizeName(params.name);
431
- if (!this.automationBridge) {
432
- throw new Error('Automation Bridge required for light spawning');
433
- }
434
-
435
- // Validate required location and rotation arrays
436
- if (!params.location || !Array.isArray(params.location) || params.location.length !== 3) {
437
- throw new Error('Invalid location: must be an array [x,y,z]');
438
- }
439
- for (const l of params.location) {
440
- if (typeof l !== 'number' || !isFinite(l)) {
441
- throw new Error('Invalid location component: must be finite numbers');
442
- }
443
- }
444
-
445
- if (!params.rotation) {
446
- throw new Error('Rotation is required');
447
- }
448
- if (Array.isArray(params.rotation)) {
449
- if (params.rotation.length !== 3) {
450
- throw new Error('Invalid rotation: must be an array [pitch,yaw,roll]');
451
- }
452
- for (const r of params.rotation) {
453
- if (typeof r !== 'number' || !isFinite(r)) {
454
- throw new Error('Invalid rotation component: must be finite numbers');
455
- }
456
- }
457
- }
458
-
459
- // Validate optional numeric parameters
460
- if (params.width !== undefined) {
461
- if (typeof params.width !== 'number' || !isFinite(params.width)) {
462
- throw new Error(`Invalid width value: ${params.width}`);
463
- }
464
- if (params.width <= 0) {
465
- throw new Error('Invalid width: must be positive');
466
- }
467
- }
468
-
469
- if (params.height !== undefined) {
470
- if (typeof params.height !== 'number' || !isFinite(params.height)) {
471
- throw new Error(`Invalid height value: ${params.height}`);
472
- }
473
- if (params.height <= 0) {
474
- throw new Error('Invalid height: must be positive');
475
- }
476
- }
477
-
478
- if (params.intensity !== undefined) {
479
- if (typeof params.intensity !== 'number' || !isFinite(params.intensity)) {
480
- throw new Error(`Invalid intensity value: ${params.intensity}`);
481
- }
482
- if (params.intensity < 0) {
483
- throw new Error('Invalid intensity: must be non-negative');
484
- }
485
- }
486
-
487
- // Validate color array
488
- if (params.color !== undefined) {
489
- if (!Array.isArray(params.color) || params.color.length !== 3) {
490
- throw new Error('Invalid color: must be an array [r,g,b]');
491
- }
492
- for (const c of params.color) {
493
- if (typeof c !== 'number' || !isFinite(c)) {
494
- throw new Error('Invalid color component: must be finite numbers');
495
- }
496
- }
497
- }
498
- // Build properties for the light
499
- const properties: Record<string, unknown> = {};
500
- if (params.intensity !== undefined) {
501
- properties.intensity = params.intensity;
502
- }
503
- if (params.color) {
504
- properties.color = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
505
- }
506
- if (params.width !== undefined) {
507
- properties.sourceWidth = params.width;
508
- }
509
- if (params.height !== undefined) {
510
- properties.sourceHeight = params.height;
511
- }
512
-
513
- try {
514
- await this.spawnLightViaAutomation('RectLight', {
515
- name,
516
- location: params.location,
517
- rotation: params.rotation,
518
- properties
519
- });
520
-
521
- return { success: true, message: `Rect light '${name}' spawned at ${params.location.join(', ')}` };
522
- } catch (e: unknown) {
523
- // Don't mask errors as "not implemented" - report the actual error from the bridge
524
- return { success: false, error: `Failed to create rect light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
525
- }
526
- }
527
-
528
- /**
529
- * Create dynamic light
530
- */
531
- async createDynamicLight(params: {
532
- name?: string;
533
- lightType?: 'Point' | 'Spot' | 'Directional' | 'Rect' | string;
534
- location?: [number, number, number] | { x: number; y: number; z: number };
535
- rotation?: [number, number, number];
536
- intensity?: number;
537
- color?: [number, number, number, number] | { r: number; g: number; b: number; a?: number };
538
- pulse?: { enabled?: boolean; frequency?: number };
539
- }) {
540
- try {
541
- const name = typeof params.name === 'string' && params.name.trim().length > 0 ? params.name.trim() : `DynamicLight_${Date.now() % 10000}`;
542
- const lightTypeRaw = typeof params.lightType === 'string' && params.lightType.trim().length > 0 ? params.lightType.trim() : 'Point';
543
- const location = Array.isArray(params.location) ? { x: params.location[0], y: params.location[1], z: params.location[2] } : (params.location || { x: 0, y: 0, z: 100 });
544
-
545
- // C++ plugin does not strictly implement 'create_dynamic_light' action; it supports 'spawn_light'.
546
- // However, we rely on the specific helper methods below which correctly map to 'spawn_light'
547
- // with the appropriate class and properties.
548
-
549
- const toArray3 = (loc: any): [number, number, number] => Array.isArray(loc)
550
- ? [Number(loc[0]) || 0, Number(loc[1]) || 0, Number(loc[2]) || 0]
551
- : [Number(loc?.x) || 0, Number(loc?.y) || 0, Number(loc?.z) || 0];
552
- const locArr = toArray3(location);
553
- const typeNorm = (lightTypeRaw || 'Point').toLowerCase();
554
-
555
- switch (typeNorm) {
556
- case 'directional': case 'directionallight':
557
- return await this.createDirectionalLight({ name, intensity: params.intensity, color: Array.isArray(params.color) ? [params.color[0], params.color[1], params.color[2]] as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined), rotation: params.rotation as any });
558
- case 'spot': case 'spotlight':
559
- return await this.createSpotLight({ name, location: locArr, rotation: params.rotation as any, intensity: params.intensity, innerCone: undefined, outerCone: undefined, color: Array.isArray(params.color) ? params.color as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined) });
560
- case 'rect': case 'rectlight':
561
- return await this.createRectLight({ name, location: locArr, rotation: params.rotation as any, width: undefined, height: undefined, intensity: params.intensity, color: Array.isArray(params.color) ? params.color as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined) });
562
- case 'point': default:
563
- return await this.createPointLight({ name, location: locArr, intensity: params.intensity, radius: undefined, color: Array.isArray(params.color) ? params.color as any : (params.color ? [params.color.r, params.color.g, params.color.b] : undefined), castShadows: undefined });
564
- }
565
-
566
- } catch (err) {
567
- return { success: false, error: `Failed to create dynamic light: ${err}` };
568
- }
569
- }
570
-
571
- // Create sky light
572
- async createSkyLight(params: {
573
- name: string;
574
- sourceType?: 'CapturedScene' | 'SpecifiedCubemap';
575
- cubemapPath?: string;
576
- intensity?: number;
577
- recapture?: boolean;
578
- location?: [number, number, number];
579
- rotation?: [number, number, number] | { pitch: number, yaw: number, roll: number };
580
- realTimeCapture?: boolean;
581
- castShadows?: boolean;
582
- color?: [number, number, number];
583
- }) {
584
- const name = this.normalizeName(params.name);
585
- if (params.sourceType === 'SpecifiedCubemap' && (!params.cubemapPath || params.cubemapPath.trim().length === 0)) {
586
- const message = 'cubemapPath is required when sourceType is SpecifiedCubemap';
587
- return { success: false, error: message, message };
588
- }
589
-
590
- if (!this.automationBridge) {
591
- throw new Error('Automation Bridge required for sky light creation');
592
- }
593
-
594
- try {
595
- const properties: Record<string, unknown> = {};
596
- if (params.intensity !== undefined) properties.Intensity = params.intensity;
597
- if (params.castShadows !== undefined) properties.CastShadows = params.castShadows;
598
- if (params.realTimeCapture !== undefined) properties.RealTimeCapture = params.realTimeCapture;
599
- if (params.color) properties.LightColor = { r: params.color[0], g: params.color[1], b: params.color[2], a: 1.0 };
600
-
601
- const payload: Record<string, unknown> = {
602
- name,
603
- sourceType: params.sourceType || 'CapturedScene',
604
- location: params.location,
605
- rotation: params.rotation,
606
- properties
607
- };
608
-
609
- if (params.cubemapPath) {
610
- payload.cubemapPath = params.cubemapPath;
611
- }
612
- if (params.intensity !== undefined) {
613
- payload.intensity = params.intensity;
614
- }
615
- if (params.recapture) {
616
- payload.recapture = params.recapture;
617
- }
618
-
619
- const response = await this.automationBridge.sendAutomationRequest('spawn_sky_light', payload, {
620
- timeoutMs: 60000
621
- });
622
-
623
- if (response.success === false) {
624
- return {
625
- success: false,
626
- error: response.error || response.message || 'Failed to create sky light'
627
- };
628
- }
629
-
630
- return {
631
- success: true,
632
- message: response.message || 'Sky light created',
633
- ...(response.result || {})
634
- };
635
- } catch (error) {
636
- return {
637
- success: false,
638
- error: `Failed to create sky light: ${error instanceof Error ? error.message : String(error)}`
639
- };
640
- }
641
- }
642
-
643
- // Remove duplicate SkyLights and keep only one (named target label)
644
- async ensureSingleSkyLight(params?: { name?: string; recapture?: boolean }) {
645
- const defaultName = 'MCP_Test_Sky';
646
- const name = this.normalizeName(params?.name, defaultName);
647
- const recapture = !!params?.recapture;
648
-
649
- if (!this.automationBridge) {
650
- throw new Error('Automation Bridge required for sky light management');
651
- }
652
-
653
- try {
654
- const response = await this.automationBridge.sendAutomationRequest('ensure_single_sky_light', {
655
- name,
656
- recapture
657
- }, {
658
- timeoutMs: 60000
659
- });
660
-
661
- if (response.success === false) {
662
- return {
663
- success: false,
664
- error: response.error || response.message || 'Failed to ensure single sky light'
665
- };
666
- }
667
-
668
- return {
669
- success: true,
670
- message: response.message || `Ensured single SkyLight (removed ${(response.result as any)?.removed || 0})`,
671
- ...(response.result || {})
672
- };
673
- } catch (error) {
674
- return {
675
- success: false,
676
- error: `Failed to ensure single sky light: ${error instanceof Error ? error.message : String(error)}`
677
- };
678
- }
679
- }
680
-
681
- // Setup global illumination
682
- async setupGlobalIllumination(params: {
683
- method: 'Lightmass' | 'LumenGI' | 'ScreenSpace' | 'None';
684
- quality?: 'Low' | 'Medium' | 'High' | 'Epic';
685
- indirectLightingIntensity?: number;
686
- bounces?: number;
687
- }) {
688
- if (this.automationBridge) {
689
- try {
690
- const response = await this.automationBridge.sendAutomationRequest('setup_global_illumination', {
691
- method: params.method,
692
- quality: params.quality,
693
- indirectLightingIntensity: params.indirectLightingIntensity,
694
- bounces: params.bounces
695
- });
696
- if (response.success) return { success: true, message: 'Global illumination configured via bridge', ...(response.result || {}) };
697
- } catch (_e) {
698
- // Fallback to console commands
699
- }
700
- }
701
-
702
- const commands = [];
703
-
704
- switch (params.method) {
705
- case 'Lightmass':
706
- commands.push('r.DynamicGlobalIlluminationMethod 0');
707
- break;
708
- case 'LumenGI':
709
- commands.push('r.DynamicGlobalIlluminationMethod 1');
710
- break;
711
- case 'ScreenSpace':
712
- commands.push('r.DynamicGlobalIlluminationMethod 2');
713
- break;
714
- case 'None':
715
- commands.push('r.DynamicGlobalIlluminationMethod 3');
716
- break;
717
- }
718
-
719
- if (params.quality) {
720
- const qualityMap = { 'Low': 0, 'Medium': 1, 'High': 2, 'Epic': 3 };
721
- commands.push(`r.Lumen.Quality ${qualityMap[params.quality]}`);
722
- }
723
-
724
- if (params.indirectLightingIntensity !== undefined) {
725
- commands.push(`r.IndirectLightingIntensity ${params.indirectLightingIntensity}`);
726
- }
727
-
728
- if (params.bounces !== undefined) {
729
- commands.push(`r.Lumen.MaxReflectionBounces ${params.bounces}`);
730
- }
731
-
732
- for (const cmd of commands) {
733
- await this.bridge.executeConsoleCommand(cmd);
734
- }
735
-
736
- return { success: true, message: 'Global illumination configured (console)' };
737
- }
738
-
739
- // Configure shadows
740
- async configureShadows(params: {
741
- shadowQuality?: 'Low' | 'Medium' | 'High' | 'Epic';
742
- cascadedShadows?: boolean;
743
- shadowDistance?: number;
744
- contactShadows?: boolean;
745
- rayTracedShadows?: boolean;
746
- }) {
747
- if (this.automationBridge) {
748
- try {
749
- const response = await this.automationBridge.sendAutomationRequest('configure_shadows', {
750
- shadowQuality: params.shadowQuality,
751
- cascadedShadows: params.cascadedShadows,
752
- shadowDistance: params.shadowDistance,
753
- contactShadows: params.contactShadows,
754
- rayTracedShadows: params.rayTracedShadows,
755
- virtualShadowMaps: params.rayTracedShadows // Map to VSM for C++ handler
756
- });
757
- if (response.success) return { success: true, message: 'Shadow settings configured via bridge', ...(response.result || {}) };
758
- } catch (_e) {
759
- // Fallback
760
- }
761
- }
762
-
763
- const commands = [];
764
-
765
- if (params.shadowQuality) {
766
- const qualityMap = { 'Low': 0, 'Medium': 1, 'High': 2, 'Epic': 3 };
767
- commands.push(`r.ShadowQuality ${qualityMap[params.shadowQuality]}`);
768
- }
769
-
770
- if (params.cascadedShadows !== undefined) {
771
- commands.push(`r.Shadow.CSM.MaxCascades ${params.cascadedShadows ? 4 : 1}`);
772
- }
773
-
774
- if (params.shadowDistance !== undefined) {
775
- commands.push(`r.Shadow.DistanceScale ${params.shadowDistance}`);
776
- }
777
-
778
- if (params.contactShadows !== undefined) {
779
- commands.push(`r.ContactShadows ${params.contactShadows ? 1 : 0}`);
780
- }
781
-
782
- if (params.rayTracedShadows !== undefined) {
783
- commands.push(`r.RayTracing.Shadows ${params.rayTracedShadows ? 1 : 0}`);
784
- }
785
-
786
- for (const cmd of commands) {
787
- await this.bridge.executeConsoleCommand(cmd);
788
- }
789
-
790
- return { success: true, message: 'Shadow settings configured (console)' };
791
- }
792
-
793
- // Build lighting
794
- async buildLighting(params: {
795
- quality?: 'Preview' | 'Medium' | 'High' | 'Production';
796
- buildOnlySelected?: boolean;
797
- buildReflectionCaptures?: boolean;
798
- levelPath?: string;
799
- }) {
800
- if (!this.automationBridge) {
801
- throw new Error('Automation Bridge required for lighting build');
802
- }
803
-
804
- try {
805
- const response = await this.automationBridge.sendAutomationRequest('bake_lightmap', {
806
- quality: params.quality || 'High',
807
- buildOnlySelected: params.buildOnlySelected || false,
808
- buildReflectionCaptures: params.buildReflectionCaptures !== false,
809
- levelPath: params.levelPath
810
- }, {
811
- timeoutMs: 300000 // 5 minutes for lighting builds
812
- });
813
-
814
- if (response.success === false) {
815
- return {
816
- success: false,
817
- error: response.error || response.message || 'Failed to build lighting'
818
- };
819
- }
820
-
821
- return {
822
- success: true,
823
- message: response.message || 'Lighting build started',
824
- ...(response.result || {})
825
- };
826
- } catch (error) {
827
- return {
828
- success: false,
829
- error: `Failed to build lighting: ${error instanceof Error ? error.message : String(error)}`
830
- };
831
- }
832
- }
833
-
834
- // Create a new level with proper lighting settings
835
- async createLightingEnabledLevel(params?: {
836
- levelName?: string;
837
- copyActors?: boolean;
838
- useTemplate?: boolean;
839
- }) {
840
- const levelName = params?.levelName || 'LightingEnabledLevel';
841
-
842
- if (!this.automationBridge) {
843
- throw new Error('Automation Bridge not available. Level creation requires plugin support.');
844
- }
845
-
846
- try {
847
- const response = await this.automationBridge.sendAutomationRequest('create_lighting_enabled_level', {
848
- levelName,
849
- copyActors: params?.copyActors === true,
850
- useTemplate: params?.useTemplate === true,
851
- path: params?.levelName ? `/Game/Maps/${params.levelName}` : undefined // Ensure path is sent
852
- }, {
853
- timeoutMs: 120000 // 2 minutes for level creation
854
- });
855
-
856
- if (response.success === false) {
857
- return {
858
- success: false,
859
- error: response.error || response.message || 'Failed to create level'
860
- };
861
- }
862
-
863
- return {
864
- success: true,
865
- message: response.message || `Created new level "${levelName}" with lighting enabled`,
866
- ...(response.result || {})
867
- };
868
- } catch (error) {
869
- return {
870
- success: false,
871
- error: `Failed to create lighting-enabled level: ${error}`
872
- };
873
- }
874
- }
875
-
876
- // Create lightmass importance volume
877
- async createLightmassVolume(params: {
878
- name: string;
879
- location: [number, number, number];
880
- size: [number, number, number];
881
- }) {
882
- const name = this.normalizeName(params.name);
883
-
884
- if (!this.automationBridge) {
885
- throw new Error('Automation Bridge not available. Lightmass volume creation requires plugin support.');
886
- }
887
-
888
- try {
889
- const response = await this.automationBridge.sendAutomationRequest('create_lightmass_volume', {
890
- name,
891
- location: { x: params.location[0], y: params.location[1], z: params.location[2] },
892
- size: { x: params.size[0], y: params.size[1], z: params.size[2] }
893
- }, {
894
- timeoutMs: 60000
895
- });
896
-
897
- if (response.success === false) {
898
- return {
899
- success: false,
900
- error: response.error || response.message || 'Failed to create lightmass volume'
901
- };
902
- }
903
-
904
- return {
905
- success: true,
906
- message: `LightmassImportanceVolume '${name}' created`,
907
- ...(response.result || {})
908
- };
909
- } catch (error) {
910
- return {
911
- success: false,
912
- error: `Failed to create lightmass volume: ${error}`
913
- };
914
- }
915
- }
916
-
917
- // Set exposure
918
- async setExposure(params: {
919
- method: 'Manual' | 'Auto';
920
- compensationValue?: number;
921
- minBrightness?: number;
922
- maxBrightness?: number;
923
- }) {
924
- if (this.automationBridge) {
925
- try {
926
- const response = await this.automationBridge.sendAutomationRequest('set_exposure', {
927
- method: params.method,
928
- compensationValue: params.compensationValue,
929
- minBrightness: params.minBrightness,
930
- maxBrightness: params.maxBrightness
931
- });
932
- if (response.success) return { success: true, message: 'Exposure settings updated via bridge', ...(response.result || {}) };
933
- } catch (_e) {
934
- // Fallback
935
- }
936
- }
937
-
938
- const commands = [];
939
-
940
- commands.push(`r.EyeAdaptation.ExposureMethod ${params.method === 'Manual' ? 0 : 1}`);
941
-
942
- if (params.compensationValue !== undefined) {
943
- commands.push(`r.EyeAdaptation.ExposureCompensation ${params.compensationValue}`);
944
- }
945
-
946
- if (params.minBrightness !== undefined) {
947
- commands.push(`r.EyeAdaptation.MinBrightness ${params.minBrightness}`);
948
- }
949
-
950
- if (params.maxBrightness !== undefined) {
951
- commands.push(`r.EyeAdaptation.MaxBrightness ${params.maxBrightness}`);
952
- }
953
-
954
- for (const cmd of commands) {
955
- await this.bridge.executeConsoleCommand(cmd);
956
- }
957
-
958
- return { success: true, message: 'Exposure settings updated (console)' };
959
- }
960
-
961
- // Set ambient occlusion
962
- async setAmbientOcclusion(params: {
963
- enabled: boolean;
964
- intensity?: number;
965
- radius?: number;
966
- quality?: 'Low' | 'Medium' | 'High';
967
- }) {
968
- if (this.automationBridge) {
969
- try {
970
- const response = await this.automationBridge.sendAutomationRequest('set_ambient_occlusion', {
971
- enabled: params.enabled,
972
- intensity: params.intensity,
973
- radius: params.radius,
974
- quality: params.quality
975
- });
976
- if (response.success) return { success: true, message: 'Ambient occlusion configured via bridge', ...(response.result || {}) };
977
- } catch (_e) {
978
- // Fallback
979
- }
980
- }
981
-
982
- const commands = [];
983
-
984
- commands.push(`r.AmbientOcclusion.Enabled ${params.enabled ? 1 : 0}`);
985
-
986
- if (params.intensity !== undefined) {
987
- commands.push(`r.AmbientOcclusion.Intensity ${params.intensity}`);
988
- }
989
-
990
- if (params.radius !== undefined) {
991
- commands.push(`r.AmbientOcclusion.Radius ${params.radius}`);
992
- }
993
-
994
- if (params.quality) {
995
- const qualityMap = { 'Low': 0, 'Medium': 1, 'High': 2 };
996
- commands.push(`r.AmbientOcclusion.Quality ${qualityMap[params.quality]}`);
997
- }
998
-
999
- for (const cmd of commands) {
1000
- await this.bridge.executeConsoleCommand(cmd);
1001
- }
1002
-
1003
- return { success: true, message: 'Ambient occlusion configured (console)' };
1004
- }
1005
-
1006
- // Setup volumetric fog
1007
- async setupVolumetricFog(params: {
1008
- enabled: boolean;
1009
- density?: number;
1010
- scatteringIntensity?: number;
1011
- fogHeight?: number; // interpreted as Z location shift for ExponentialHeightFog actor
1012
- }) {
1013
- // Enable/disable global volumetric fog via CVar
1014
- await this.bridge.executeConsoleCommand(`r.VolumetricFog ${params.enabled ? 1 : 0}`);
1015
-
1016
- if (!this.automationBridge) {
1017
- return {
1018
- success: true,
1019
- message: 'Volumetric fog console setting applied (plugin required for fog actor adjustment)'
1020
- };
1021
- }
1022
-
1023
- try {
1024
- const response = await this.automationBridge.sendAutomationRequest('setup_volumetric_fog', {
1025
- enabled: params.enabled,
1026
- density: params.density,
1027
- scatteringIntensity: params.scatteringIntensity,
1028
- fogHeight: params.fogHeight
1029
- }, {
1030
- timeoutMs: 60000
1031
- });
1032
-
1033
- if (response.success === false) {
1034
- return {
1035
- success: false,
1036
- error: response.error || response.message || 'Failed to configure volumetric fog'
1037
- };
1038
- }
1039
-
1040
- return {
1041
- success: true,
1042
- message: 'Volumetric fog configured',
1043
- ...(response.result || {})
1044
- };
1045
- } catch (error) {
1046
- return {
1047
- success: false,
1048
- error: `Failed to setup volumetric fog: ${error}`
1049
- };
1050
- }
1051
- }
1052
- }