unreal-engine-mcp-server 0.4.7 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (438) 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.yml +148 -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 +23 -0
  19. package/.github/workflows/labeler.yml +16 -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 +12 -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 +267 -31
  29. package/CONTRIBUTING.md +140 -0
  30. package/README.md +166 -71
  31. package/claude_desktop_config_example.json +7 -6
  32. package/dist/automation/bridge.d.ts +50 -0
  33. package/dist/automation/bridge.js +452 -0
  34. package/dist/automation/connection-manager.d.ts +23 -0
  35. package/dist/automation/connection-manager.js +107 -0
  36. package/dist/automation/handshake.d.ts +11 -0
  37. package/dist/automation/handshake.js +89 -0
  38. package/dist/automation/index.d.ts +3 -0
  39. package/dist/automation/index.js +3 -0
  40. package/dist/automation/message-handler.d.ts +12 -0
  41. package/dist/automation/message-handler.js +149 -0
  42. package/dist/automation/request-tracker.d.ts +25 -0
  43. package/dist/automation/request-tracker.js +98 -0
  44. package/dist/automation/types.d.ts +130 -0
  45. package/dist/automation/types.js +2 -0
  46. package/dist/cli.js +32 -5
  47. package/dist/config.d.ts +27 -0
  48. package/dist/config.js +60 -0
  49. package/dist/constants.d.ts +12 -0
  50. package/dist/constants.js +12 -0
  51. package/dist/graphql/resolvers.d.ts +268 -0
  52. package/dist/graphql/resolvers.js +743 -0
  53. package/dist/graphql/schema.d.ts +5 -0
  54. package/dist/graphql/schema.js +437 -0
  55. package/dist/graphql/server.d.ts +26 -0
  56. package/dist/graphql/server.js +115 -0
  57. package/dist/graphql/types.d.ts +7 -0
  58. package/dist/graphql/types.js +2 -0
  59. package/dist/handlers/resource-handlers.d.ts +20 -0
  60. package/dist/handlers/resource-handlers.js +180 -0
  61. package/dist/index.d.ts +31 -18
  62. package/dist/index.js +119 -619
  63. package/dist/prompts/index.js +4 -4
  64. package/dist/resources/actors.d.ts +17 -12
  65. package/dist/resources/actors.js +56 -76
  66. package/dist/resources/assets.d.ts +6 -14
  67. package/dist/resources/assets.js +115 -147
  68. package/dist/resources/levels.d.ts +13 -13
  69. package/dist/resources/levels.js +25 -34
  70. package/dist/server/resource-registry.d.ts +20 -0
  71. package/dist/server/resource-registry.js +37 -0
  72. package/dist/server/tool-registry.d.ts +23 -0
  73. package/dist/server/tool-registry.js +322 -0
  74. package/dist/server-setup.d.ts +21 -0
  75. package/dist/server-setup.js +111 -0
  76. package/dist/services/health-monitor.d.ts +34 -0
  77. package/dist/services/health-monitor.js +105 -0
  78. package/dist/services/metrics-server.d.ts +11 -0
  79. package/dist/services/metrics-server.js +105 -0
  80. package/dist/tools/actors.d.ts +147 -9
  81. package/dist/tools/actors.js +350 -311
  82. package/dist/tools/animation.d.ts +135 -4
  83. package/dist/tools/animation.js +510 -411
  84. package/dist/tools/assets.d.ts +117 -19
  85. package/dist/tools/assets.js +259 -284
  86. package/dist/tools/audio.d.ts +102 -42
  87. package/dist/tools/audio.js +272 -685
  88. package/dist/tools/base-tool.d.ts +17 -0
  89. package/dist/tools/base-tool.js +46 -0
  90. package/dist/tools/behavior-tree.d.ts +94 -0
  91. package/dist/tools/behavior-tree.js +39 -0
  92. package/dist/tools/blueprint/helpers.d.ts +29 -0
  93. package/dist/tools/blueprint/helpers.js +182 -0
  94. package/dist/tools/blueprint.d.ts +228 -118
  95. package/dist/tools/blueprint.js +685 -832
  96. package/dist/tools/consolidated-tool-definitions.d.ts +5462 -1781
  97. package/dist/tools/consolidated-tool-definitions.js +829 -496
  98. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  99. package/dist/tools/consolidated-tool-handlers.js +211 -1026
  100. package/dist/tools/debug.d.ts +143 -85
  101. package/dist/tools/debug.js +234 -180
  102. package/dist/tools/dynamic-handler-registry.d.ts +11 -0
  103. package/dist/tools/dynamic-handler-registry.js +101 -0
  104. package/dist/tools/editor.d.ts +139 -18
  105. package/dist/tools/editor.js +239 -244
  106. package/dist/tools/engine.d.ts +10 -4
  107. package/dist/tools/engine.js +13 -5
  108. package/dist/tools/environment.d.ts +36 -0
  109. package/dist/tools/environment.js +267 -0
  110. package/dist/tools/foliage.d.ts +105 -14
  111. package/dist/tools/foliage.js +219 -331
  112. package/dist/tools/handlers/actor-handlers.d.ts +3 -0
  113. package/dist/tools/handlers/actor-handlers.js +232 -0
  114. package/dist/tools/handlers/animation-handlers.d.ts +3 -0
  115. package/dist/tools/handlers/animation-handlers.js +185 -0
  116. package/dist/tools/handlers/argument-helper.d.ts +16 -0
  117. package/dist/tools/handlers/argument-helper.js +80 -0
  118. package/dist/tools/handlers/asset-handlers.d.ts +3 -0
  119. package/dist/tools/handlers/asset-handlers.js +496 -0
  120. package/dist/tools/handlers/audio-handlers.d.ts +3 -0
  121. package/dist/tools/handlers/audio-handlers.js +166 -0
  122. package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
  123. package/dist/tools/handlers/blueprint-handlers.js +358 -0
  124. package/dist/tools/handlers/common-handlers.d.ts +14 -0
  125. package/dist/tools/handlers/common-handlers.js +56 -0
  126. package/dist/tools/handlers/editor-handlers.d.ts +3 -0
  127. package/dist/tools/handlers/editor-handlers.js +119 -0
  128. package/dist/tools/handlers/effect-handlers.d.ts +3 -0
  129. package/dist/tools/handlers/effect-handlers.js +171 -0
  130. package/dist/tools/handlers/environment-handlers.d.ts +3 -0
  131. package/dist/tools/handlers/environment-handlers.js +170 -0
  132. package/dist/tools/handlers/graph-handlers.d.ts +3 -0
  133. package/dist/tools/handlers/graph-handlers.js +90 -0
  134. package/dist/tools/handlers/input-handlers.d.ts +3 -0
  135. package/dist/tools/handlers/input-handlers.js +21 -0
  136. package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
  137. package/dist/tools/handlers/inspect-handlers.js +383 -0
  138. package/dist/tools/handlers/level-handlers.d.ts +3 -0
  139. package/dist/tools/handlers/level-handlers.js +237 -0
  140. package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
  141. package/dist/tools/handlers/lighting-handlers.js +144 -0
  142. package/dist/tools/handlers/performance-handlers.d.ts +3 -0
  143. package/dist/tools/handlers/performance-handlers.js +130 -0
  144. package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
  145. package/dist/tools/handlers/pipeline-handlers.js +110 -0
  146. package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
  147. package/dist/tools/handlers/sequence-handlers.js +376 -0
  148. package/dist/tools/handlers/system-handlers.d.ts +4 -0
  149. package/dist/tools/handlers/system-handlers.js +506 -0
  150. package/dist/tools/input.d.ts +19 -0
  151. package/dist/tools/input.js +89 -0
  152. package/dist/tools/introspection.d.ts +103 -40
  153. package/dist/tools/introspection.js +425 -568
  154. package/dist/tools/landscape.d.ts +97 -36
  155. package/dist/tools/landscape.js +280 -409
  156. package/dist/tools/level.d.ts +130 -10
  157. package/dist/tools/level.js +639 -675
  158. package/dist/tools/lighting.d.ts +77 -38
  159. package/dist/tools/lighting.js +441 -943
  160. package/dist/tools/logs.d.ts +3 -3
  161. package/dist/tools/logs.js +5 -57
  162. package/dist/tools/materials.d.ts +91 -24
  163. package/dist/tools/materials.js +190 -118
  164. package/dist/tools/niagara.d.ts +149 -39
  165. package/dist/tools/niagara.js +232 -182
  166. package/dist/tools/performance.d.ts +27 -12
  167. package/dist/tools/performance.js +204 -122
  168. package/dist/tools/physics.d.ts +32 -77
  169. package/dist/tools/physics.js +171 -582
  170. package/dist/tools/property-dictionary.d.ts +13 -0
  171. package/dist/tools/property-dictionary.js +82 -0
  172. package/dist/tools/sequence.d.ts +73 -48
  173. package/dist/tools/sequence.js +196 -748
  174. package/dist/tools/tool-definition-utils.d.ts +59 -0
  175. package/dist/tools/tool-definition-utils.js +35 -0
  176. package/dist/tools/ui.d.ts +66 -34
  177. package/dist/tools/ui.js +134 -214
  178. package/dist/types/env.d.ts +0 -3
  179. package/dist/types/env.js +0 -7
  180. package/dist/types/tool-interfaces.d.ts +898 -0
  181. package/dist/types/tool-interfaces.js +2 -0
  182. package/dist/types/tool-types.d.ts +183 -19
  183. package/dist/types/tool-types.js +0 -4
  184. package/dist/unreal-bridge.d.ts +24 -131
  185. package/dist/unreal-bridge.js +364 -1506
  186. package/dist/utils/command-validator.d.ts +9 -0
  187. package/dist/utils/command-validator.js +67 -0
  188. package/dist/utils/elicitation.d.ts +1 -1
  189. package/dist/utils/elicitation.js +12 -15
  190. package/dist/utils/error-handler.d.ts +2 -51
  191. package/dist/utils/error-handler.js +11 -87
  192. package/dist/utils/ini-reader.d.ts +3 -0
  193. package/dist/utils/ini-reader.js +69 -0
  194. package/dist/utils/logger.js +9 -6
  195. package/dist/utils/normalize.d.ts +3 -0
  196. package/dist/utils/normalize.js +56 -0
  197. package/dist/utils/response-factory.d.ts +7 -0
  198. package/dist/utils/response-factory.js +33 -0
  199. package/dist/utils/response-validator.d.ts +3 -24
  200. package/dist/utils/response-validator.js +130 -81
  201. package/dist/utils/result-helpers.d.ts +4 -5
  202. package/dist/utils/result-helpers.js +15 -16
  203. package/dist/utils/safe-json.js +5 -11
  204. package/dist/utils/unreal-command-queue.d.ts +24 -0
  205. package/dist/utils/unreal-command-queue.js +120 -0
  206. package/dist/utils/validation.d.ts +0 -40
  207. package/dist/utils/validation.js +1 -78
  208. package/dist/wasm/index.d.ts +70 -0
  209. package/dist/wasm/index.js +535 -0
  210. package/docs/GraphQL-API.md +888 -0
  211. package/docs/Migration-Guide-v0.5.0.md +692 -0
  212. package/docs/Roadmap.md +53 -0
  213. package/docs/WebAssembly-Integration.md +628 -0
  214. package/docs/editor-plugin-extension.md +370 -0
  215. package/docs/handler-mapping.md +242 -0
  216. package/docs/native-automation-progress.md +128 -0
  217. package/docs/testing-guide.md +423 -0
  218. package/mcp-config-example.json +6 -6
  219. package/package.json +60 -27
  220. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
  221. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
  222. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
  223. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
  224. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
  225. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
  226. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
  227. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
  228. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
  229. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
  230. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
  231. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
  232. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
  233. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
  234. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
  235. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
  236. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
  237. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
  238. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
  239. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
  240. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
  241. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
  242. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
  243. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
  244. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
  245. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
  246. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
  247. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
  248. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
  249. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
  250. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
  251. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
  252. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
  253. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
  254. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
  255. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
  256. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
  257. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
  258. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
  259. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
  260. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
  261. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
  262. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
  263. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
  264. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
  265. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
  266. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
  267. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
  268. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
  269. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
  270. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
  272. package/scripts/check-unreal-connection.mjs +19 -0
  273. package/scripts/clean-tmp.js +23 -0
  274. package/scripts/patch-wasm.js +26 -0
  275. package/scripts/run-all-tests.mjs +131 -0
  276. package/scripts/smoke-test.ts +94 -0
  277. package/scripts/sync-mcp-plugin.js +143 -0
  278. package/scripts/test-no-plugin-alternates.mjs +113 -0
  279. package/scripts/validate-server.js +46 -0
  280. package/scripts/verify-automation-bridge.js +200 -0
  281. package/server.json +57 -21
  282. package/src/automation/bridge.ts +558 -0
  283. package/src/automation/connection-manager.ts +130 -0
  284. package/src/automation/handshake.ts +99 -0
  285. package/src/automation/index.ts +2 -0
  286. package/src/automation/message-handler.ts +167 -0
  287. package/src/automation/request-tracker.ts +123 -0
  288. package/src/automation/types.ts +107 -0
  289. package/src/cli.ts +33 -6
  290. package/src/config.ts +73 -0
  291. package/src/constants.ts +12 -0
  292. package/src/graphql/resolvers.ts +1010 -0
  293. package/src/graphql/schema.ts +452 -0
  294. package/src/graphql/server.ts +154 -0
  295. package/src/graphql/types.ts +7 -0
  296. package/src/handlers/resource-handlers.ts +186 -0
  297. package/src/index.ts +152 -663
  298. package/src/prompts/index.ts +4 -4
  299. package/src/resources/actors.ts +58 -76
  300. package/src/resources/assets.ts +147 -134
  301. package/src/resources/levels.ts +28 -33
  302. package/src/server/resource-registry.ts +47 -0
  303. package/src/server/tool-registry.ts +354 -0
  304. package/src/server-setup.ts +148 -0
  305. package/src/services/health-monitor.ts +132 -0
  306. package/src/services/metrics-server.ts +142 -0
  307. package/src/tools/actors.ts +417 -322
  308. package/src/tools/animation.ts +671 -461
  309. package/src/tools/assets.ts +353 -289
  310. package/src/tools/audio.ts +323 -766
  311. package/src/tools/base-tool.ts +52 -0
  312. package/src/tools/behavior-tree.ts +45 -0
  313. package/src/tools/blueprint/helpers.ts +189 -0
  314. package/src/tools/blueprint.ts +787 -965
  315. package/src/tools/consolidated-tool-definitions.ts +993 -515
  316. package/src/tools/consolidated-tool-handlers.ts +272 -1139
  317. package/src/tools/debug.ts +292 -187
  318. package/src/tools/dynamic-handler-registry.ts +151 -0
  319. package/src/tools/editor.ts +309 -246
  320. package/src/tools/engine.ts +14 -3
  321. package/src/tools/environment.ts +287 -0
  322. package/src/tools/foliage.ts +314 -379
  323. package/src/tools/handlers/actor-handlers.ts +271 -0
  324. package/src/tools/handlers/animation-handlers.ts +237 -0
  325. package/src/tools/handlers/argument-helper.ts +142 -0
  326. package/src/tools/handlers/asset-handlers.ts +532 -0
  327. package/src/tools/handlers/audio-handlers.ts +194 -0
  328. package/src/tools/handlers/blueprint-handlers.ts +380 -0
  329. package/src/tools/handlers/common-handlers.ts +87 -0
  330. package/src/tools/handlers/editor-handlers.ts +123 -0
  331. package/src/tools/handlers/effect-handlers.ts +220 -0
  332. package/src/tools/handlers/environment-handlers.ts +183 -0
  333. package/src/tools/handlers/graph-handlers.ts +116 -0
  334. package/src/tools/handlers/input-handlers.ts +28 -0
  335. package/src/tools/handlers/inspect-handlers.ts +450 -0
  336. package/src/tools/handlers/level-handlers.ts +252 -0
  337. package/src/tools/handlers/lighting-handlers.ts +147 -0
  338. package/src/tools/handlers/performance-handlers.ts +132 -0
  339. package/src/tools/handlers/pipeline-handlers.ts +127 -0
  340. package/src/tools/handlers/sequence-handlers.ts +415 -0
  341. package/src/tools/handlers/system-handlers.ts +564 -0
  342. package/src/tools/input.ts +101 -0
  343. package/src/tools/introspection.ts +493 -584
  344. package/src/tools/landscape.ts +394 -489
  345. package/src/tools/level.ts +752 -694
  346. package/src/tools/lighting.ts +583 -984
  347. package/src/tools/logs.ts +9 -57
  348. package/src/tools/materials.ts +231 -121
  349. package/src/tools/niagara.ts +293 -168
  350. package/src/tools/performance.ts +320 -168
  351. package/src/tools/physics.ts +268 -613
  352. package/src/tools/property-dictionary.ts +98 -0
  353. package/src/tools/sequence.ts +255 -815
  354. package/src/tools/tool-definition-utils.ts +35 -0
  355. package/src/tools/ui.ts +207 -283
  356. package/src/types/env.ts +0 -10
  357. package/src/types/tool-interfaces.ts +250 -0
  358. package/src/types/tool-types.ts +243 -21
  359. package/src/unreal-bridge.ts +460 -1550
  360. package/src/utils/command-validator.ts +75 -0
  361. package/src/utils/elicitation.ts +10 -7
  362. package/src/utils/error-handler.ts +14 -90
  363. package/src/utils/ini-reader.ts +86 -0
  364. package/src/utils/logger.ts +8 -3
  365. package/src/utils/normalize.ts +60 -0
  366. package/src/utils/response-factory.ts +39 -0
  367. package/src/utils/response-validator.ts +176 -56
  368. package/src/utils/result-helpers.ts +21 -19
  369. package/src/utils/safe-json.ts +14 -11
  370. package/src/utils/unreal-command-queue.ts +152 -0
  371. package/src/utils/validation.ts +4 -1
  372. package/src/wasm/index.ts +838 -0
  373. package/test-server.mjs +100 -0
  374. package/tests/run-unreal-tool-tests.mjs +242 -14
  375. package/tests/test-animation.mjs +44 -0
  376. package/tests/test-asset-advanced.mjs +82 -0
  377. package/tests/test-asset-errors.mjs +35 -0
  378. package/tests/test-audio.mjs +219 -0
  379. package/tests/test-automation-timeouts.mjs +98 -0
  380. package/tests/test-behavior-tree.mjs +261 -0
  381. package/tests/test-blueprint-events.mjs +35 -0
  382. package/tests/test-blueprint-graph.mjs +79 -0
  383. package/tests/test-blueprint.mjs +577 -0
  384. package/tests/test-client-mode.mjs +86 -0
  385. package/tests/test-console-command.mjs +56 -0
  386. package/tests/test-control-actor.mjs +425 -0
  387. package/tests/test-control-editor.mjs +80 -0
  388. package/tests/test-extra-tools.mjs +38 -0
  389. package/tests/test-graphql.mjs +322 -0
  390. package/tests/test-inspect.mjs +72 -0
  391. package/tests/test-landscape.mjs +60 -0
  392. package/tests/test-manage-asset.mjs +438 -0
  393. package/tests/test-manage-level.mjs +70 -0
  394. package/tests/test-materials.mjs +356 -0
  395. package/tests/test-niagara.mjs +185 -0
  396. package/tests/test-no-inline-python.mjs +122 -0
  397. package/tests/test-plugin-handshake.mjs +82 -0
  398. package/tests/test-render.mjs +33 -0
  399. package/tests/test-runner.mjs +933 -0
  400. package/tests/test-search-assets.mjs +66 -0
  401. package/tests/test-sequence.mjs +68 -0
  402. package/tests/test-system.mjs +57 -0
  403. package/tests/test-wasm.mjs +193 -0
  404. package/tests/test-world-partition.mjs +215 -0
  405. package/tsconfig.json +3 -3
  406. package/wasm/Cargo.lock +363 -0
  407. package/wasm/Cargo.toml +42 -0
  408. package/wasm/LICENSE +21 -0
  409. package/wasm/README.md +253 -0
  410. package/wasm/src/dependency_resolver.rs +377 -0
  411. package/wasm/src/lib.rs +153 -0
  412. package/wasm/src/property_parser.rs +271 -0
  413. package/wasm/src/transform_math.rs +396 -0
  414. package/wasm/tests/integration.rs +109 -0
  415. package/.github/workflows/smithery-build.yml +0 -29
  416. package/dist/tools/build_environment_advanced.d.ts +0 -65
  417. package/dist/tools/build_environment_advanced.js +0 -633
  418. package/dist/tools/rc.d.ts +0 -110
  419. package/dist/tools/rc.js +0 -437
  420. package/dist/tools/visual.d.ts +0 -40
  421. package/dist/tools/visual.js +0 -282
  422. package/dist/utils/http.d.ts +0 -6
  423. package/dist/utils/http.js +0 -151
  424. package/dist/utils/python-output.d.ts +0 -18
  425. package/dist/utils/python-output.js +0 -290
  426. package/dist/utils/python.d.ts +0 -2
  427. package/dist/utils/python.js +0 -4
  428. package/dist/utils/stdio-redirect.d.ts +0 -2
  429. package/dist/utils/stdio-redirect.js +0 -20
  430. package/docs/unreal-tool-test-cases.md +0 -574
  431. package/smithery.yaml +0 -29
  432. package/src/tools/build_environment_advanced.ts +0 -732
  433. package/src/tools/rc.ts +0 -515
  434. package/src/tools/visual.ts +0 -281
  435. package/src/utils/http.ts +0 -187
  436. package/src/utils/python-output.ts +0 -351
  437. package/src/utils/python.ts +0 -3
  438. package/src/utils/stdio-redirect.ts +0 -18
package/src/tools/rc.ts DELETED
@@ -1,515 +0,0 @@
1
- import { UnrealBridge } from '../unreal-bridge.js';
2
- import { Logger } from '../utils/logger.js';
3
- import { interpretStandardResult } from '../utils/result-helpers.js';
4
-
5
- export interface RCPreset {
6
- id: string;
7
- name: string;
8
- path: string;
9
- description?: string;
10
- exposedEntities?: RCExposedEntity[];
11
- }
12
-
13
- export interface RCExposedEntity {
14
- id: string;
15
- label: string;
16
- type: 'property' | 'function' | 'actor';
17
- objectPath?: string;
18
- propertyName?: string;
19
- functionName?: string;
20
- metadata?: Record<string, any>;
21
- }
22
-
23
- export class RcTools {
24
- private log = new Logger('RcTools');
25
- private presetCache = new Map<string, RCPreset>();
26
- private retryAttempts = 3;
27
- private retryDelay = 1000;
28
-
29
- constructor(private bridge: UnrealBridge) {}
30
-
31
- /**
32
- * Execute with retry logic for transient failures
33
- */
34
- private async executeWithRetry<T>(
35
- operation: () => Promise<T>,
36
- operationName: string
37
- ): Promise<T> {
38
- let lastError: any;
39
-
40
- for (let attempt = 1; attempt <= this.retryAttempts; attempt++) {
41
- try {
42
- return await operation();
43
- } catch (error: any) {
44
- lastError = error;
45
- this.log.warn(`${operationName} attempt ${attempt} failed: ${error.message || error}`);
46
-
47
- if (attempt < this.retryAttempts) {
48
- await new Promise(resolve =>
49
- setTimeout(resolve, this.retryDelay * attempt)
50
- );
51
- }
52
- }
53
- }
54
-
55
- throw lastError;
56
- }
57
-
58
- /**
59
- * Parse Python execution result with better error handling
60
- */
61
- private parsePythonResult(resp: unknown, operationName: string): any {
62
- const interpreted = interpretStandardResult(resp, {
63
- successMessage: `${operationName} succeeded`,
64
- failureMessage: `${operationName} failed`
65
- });
66
-
67
- if (interpreted.success) {
68
- return {
69
- ...interpreted.payload,
70
- success: true
71
- };
72
- }
73
-
74
- const baseError = interpreted.error ?? `${operationName} did not return a valid result`;
75
- const rawOutput = interpreted.rawText ?? '';
76
- const cleanedOutput = interpreted.cleanText && interpreted.cleanText.trim().length > 0
77
- ? interpreted.cleanText.trim()
78
- : baseError;
79
-
80
- if (rawOutput.includes('ModuleNotFoundError')) {
81
- return { success: false, error: 'Remote Control module not available. Ensure Remote Control plugin is enabled.' };
82
- }
83
- if (rawOutput.includes('AttributeError')) {
84
- return { success: false, error: 'Remote Control API method not found. Check Unreal Engine version compatibility.' };
85
- }
86
-
87
- const error = baseError;
88
- this.log.error(`${operationName} returned no parsable result: ${cleanedOutput}`);
89
- return {
90
- success: false,
91
- error: (() => {
92
- const detail = cleanedOutput === baseError
93
- ? ''
94
- : (cleanedOutput ?? '').substring(0, 200).trim();
95
- return detail ? `${error}: ${detail}` : error;
96
- })()
97
- };
98
- }
99
-
100
- // Create a Remote Control Preset asset
101
- async createPreset(params: { name: string; path?: string }) {
102
- const name = params.name?.trim();
103
- const path = (params.path || '/Game/RCPresets').replace(/\/$/, '');
104
- if (!name) return { success: false, error: 'Preset name is required' };
105
- if (!path.startsWith('/Game/')) {
106
- return { success: false, error: `Preset path must be under /Game. Received: ${path}` };
107
- }
108
- const python = `
109
- import unreal, json
110
- import time
111
- name = r"${name}"
112
- base_path = r"${path}"
113
- full_path = f"{base_path}/{name}"
114
- try:
115
- # Check if asset already exists
116
- if unreal.EditorAssetLibrary.does_asset_exist(full_path):
117
- # If it exists, add a timestamp suffix to create a unique name
118
- timestamp = str(int(time.time() * 1000))
119
- unique_name = f"{name}_{timestamp}"
120
- full_path = f"{base_path}/{unique_name}"
121
- # Check again to ensure uniqueness
122
- if unreal.EditorAssetLibrary.does_asset_exist(full_path):
123
- print('RESULT:' + json.dumps({'success': True, 'presetPath': full_path, 'existing': True}))
124
- else:
125
- # Continue with creation using unique name
126
- name = unique_name
127
- # Now create the preset if it doesn't exist
128
- if not unreal.EditorAssetLibrary.does_asset_exist(full_path):
129
- # Ensure directory exists
130
- if not unreal.EditorAssetLibrary.does_directory_exist(base_path):
131
- unreal.EditorAssetLibrary.make_directory(base_path)
132
-
133
- asset_tools = unreal.AssetToolsHelpers.get_asset_tools()
134
- factory = None
135
- try:
136
- factory = unreal.RemoteControlPresetFactory()
137
- except Exception:
138
- # Factory might not be available in older versions
139
- factory = None
140
-
141
- asset = None
142
- try:
143
- if factory is not None:
144
- asset = asset_tools.create_asset(asset_name=name, package_path=base_path, asset_class=unreal.RemoteControlPreset, factory=factory)
145
- else:
146
- # Try alternative creation method
147
- asset = asset_tools.create_asset(asset_name=name, package_path=base_path, asset_class=unreal.RemoteControlPreset, factory=None)
148
- except Exception as e:
149
- # If creation fails, try to provide helpful error
150
- if "RemoteControlPreset" in str(e):
151
- print('RESULT:' + json.dumps({'success': False, 'error': 'RemoteControlPreset class not available. Ensure Remote Control plugin is enabled.'}))
152
- else:
153
- print('RESULT:' + json.dumps({'success': False, 'error': f'Create asset failed: {str(e)}'}))
154
- raise SystemExit(0)
155
-
156
- if asset:
157
- # Save with suppressed validation warnings
158
- try:
159
- unreal.EditorAssetLibrary.save_asset(full_path, only_if_is_dirty=False)
160
- print('RESULT:' + json.dumps({'success': True, 'presetPath': full_path}))
161
- except Exception as save_err:
162
- # Asset was created but save had warnings - still consider success
163
- print('RESULT:' + json.dumps({'success': True, 'presetPath': full_path, 'warning': 'Asset created with validation warnings'}))
164
- else:
165
- print('RESULT:' + json.dumps({'success': False, 'error': 'Preset creation returned None'}))
166
- except Exception as e:
167
- print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))
168
- `.trim();
169
- const resp = await this.executeWithRetry(
170
- () => this.bridge.executePython(python),
171
- 'createPreset'
172
- );
173
-
174
- const result = this.parsePythonResult(resp, 'createPreset');
175
-
176
- // Cache the preset if successful
177
- if (result.success && result.presetPath) {
178
- const preset: RCPreset = {
179
- id: result.presetPath,
180
- name: name,
181
- path: result.presetPath,
182
- description: `Created at ${new Date().toISOString()}`
183
- };
184
- this.presetCache.set(preset.id, preset);
185
- }
186
-
187
- return result;
188
- }
189
-
190
- // Expose an actor by label/name into a preset
191
- async exposeActor(params: { presetPath: string; actorName: string }) {
192
- const python = `
193
- import unreal
194
- import json
195
-
196
- preset_path = r"${params.presetPath}"
197
- actor_name = r"${params.actorName}"
198
-
199
- def find_actor_by_label(actor_subsystem, desired_name):
200
- if not actor_subsystem:
201
- return None
202
- desired_lower = desired_name.lower()
203
- try:
204
- actors = actor_subsystem.get_all_level_actors()
205
- except Exception:
206
- actors = []
207
- for actor in actors or []:
208
- if not actor:
209
- continue
210
- try:
211
- label = (actor.get_actor_label() or '').lower()
212
- name = (actor.get_name() or '').lower()
213
- if desired_lower in (label, name):
214
- return actor
215
- except Exception:
216
- continue
217
- return None
218
-
219
- try:
220
- preset = unreal.EditorAssetLibrary.load_asset(preset_path)
221
- if not preset:
222
- print('RESULT:' + json.dumps({'success': False, 'error': 'Preset not found'}))
223
- else:
224
- actor_sub = unreal.get_editor_subsystem(unreal.EditorActorSubsystem)
225
- if actor_sub and actor_name.lower() == 'missingactor':
226
- try:
227
- actors = actor_sub.get_all_level_actors()
228
- for actor in actors or []:
229
- if actor and (actor.get_actor_label() or '').lower() == 'missingactor':
230
- try:
231
- actor_sub.destroy_actor(actor)
232
- except Exception:
233
- pass
234
- except Exception:
235
- pass
236
- target = find_actor_by_label(actor_sub, actor_name)
237
- if not target:
238
- sample = []
239
- try:
240
- actors = actor_sub.get_all_level_actors() if actor_sub else []
241
- for actor in actors[:5]:
242
- if actor:
243
- sample.append({'label': actor.get_actor_label(), 'name': actor.get_name()})
244
- except Exception:
245
- pass
246
- print('RESULT:' + json.dumps({'success': False, 'error': f"Actor '{actor_name}' not found", 'availableActors': sample}))
247
- else:
248
- try:
249
- args = unreal.RemoteControlOptionalExposeArgs()
250
- unreal.RemoteControlFunctionLibrary.expose_actor(preset, target, args)
251
- unreal.EditorAssetLibrary.save_asset(preset_path)
252
- print('RESULT:' + json.dumps({'success': True}))
253
- except Exception as expose_error:
254
- print('RESULT:' + json.dumps({'success': False, 'error': str(expose_error)}))
255
- except Exception as e:
256
- print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))
257
- `.trim();
258
- const resp = await this.executeWithRetry(
259
- () => this.bridge.executePython(python),
260
- 'exposeActor'
261
- );
262
-
263
- const result = this.parsePythonResult(resp, 'exposeActor');
264
-
265
- // Clear cache for this preset to force refresh
266
- if (result.success) {
267
- this.presetCache.delete(params.presetPath);
268
- }
269
-
270
- return result;
271
- }
272
-
273
- // Expose a property on an object into a preset
274
- async exposeProperty(params: { presetPath: string; objectPath: string; propertyName: string }) {
275
- const python = `\nimport unreal, json\npreset_path = r"${params.presetPath}"\nobj_path = r"${params.objectPath}"\nprop_name = r"${params.propertyName}"\ntry:\n preset = unreal.EditorAssetLibrary.load_asset(preset_path)\n obj = unreal.load_object(None, obj_path)\n if not preset or not obj:\n print('RESULT:' + json.dumps({'success': False, 'error': 'Preset or object not found'}))\n else:\n try:\n # Expose with default optional args struct (cannot pass None)\n args = unreal.RemoteControlOptionalExposeArgs()\n unreal.RemoteControlFunctionLibrary.expose_property(preset, obj, prop_name, args)\n unreal.EditorAssetLibrary.save_asset(preset_path)\n print('RESULT:' + json.dumps({'success': True}))\n except Exception as e:\n print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))\nexcept Exception as e:\n print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))\n`.trim();
276
- const resp = await this.executeWithRetry(
277
- () => this.bridge.executePython(python),
278
- 'exposeProperty'
279
- );
280
-
281
- const result = this.parsePythonResult(resp, 'exposeProperty');
282
-
283
- // Clear cache for this preset to force refresh
284
- if (result.success) {
285
- this.presetCache.delete(params.presetPath);
286
- }
287
-
288
- return result;
289
- }
290
-
291
- // List exposed fields (best-effort)
292
- async listFields(params: { presetPath: string }) {
293
- const python = `
294
- import unreal, json
295
- preset_path = r"${params.presetPath}"
296
- try:
297
- # First check if the asset exists
298
- if not preset_path or not preset_path.startswith('/Game/'):
299
- print('RESULT:' + json.dumps({'success': False, 'error': 'Invalid preset path. Must start with /Game/'}))
300
- elif not unreal.EditorAssetLibrary.does_asset_exist(preset_path):
301
- print('RESULT:' + json.dumps({'success': False, 'error': 'Preset not found at path: ' + preset_path}))
302
- else:
303
- preset = unreal.EditorAssetLibrary.load_asset(preset_path)
304
- if not preset:
305
- print('RESULT:' + json.dumps({'success': False, 'error': 'Failed to load preset'}))
306
- else:
307
- fields = []
308
- try:
309
- # Try to get exposed entities
310
- if hasattr(preset, 'get_exposed_entities'):
311
- for entity in preset.get_exposed_entities():
312
- try:
313
- fields.append({
314
- 'id': str(entity.id) if hasattr(entity, 'id') else '',
315
- 'label': str(entity.label) if hasattr(entity, 'label') else '',
316
- 'path': str(getattr(entity, 'path', ''))
317
- })
318
- except Exception:
319
- pass
320
- except Exception as e:
321
- # Method might not exist or be accessible
322
- pass
323
- print('RESULT:' + json.dumps({'success': True, 'fields': fields}))
324
- except Exception as e:
325
- print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))
326
- `.trim();
327
- const resp = await this.executeWithRetry(
328
- () => this.bridge.executePython(python),
329
- 'listFields'
330
- );
331
-
332
- return this.parsePythonResult(resp, 'listFields');
333
- }
334
-
335
- // Set a property value via Remote Control property endpoint
336
- async setProperty(params: { objectPath: string; propertyName: string; value: any }) {
337
- return this.executeWithRetry(async () => {
338
- try {
339
- // Validate value type and convert if needed
340
- let processedValue = params.value;
341
-
342
- // Handle special types
343
- if (typeof params.value === 'object' && params.value !== null) {
344
- // Check if it's a vector/rotator/transform
345
- if ('x' in params.value || 'X' in params.value) {
346
- processedValue = {
347
- X: params.value.x || params.value.X || 0,
348
- Y: params.value.y || params.value.Y || 0,
349
- Z: params.value.z || params.value.Z || 0
350
- };
351
- }
352
- }
353
-
354
- const res = await this.bridge.httpCall('/remote/object/property', 'PUT', {
355
- objectPath: params.objectPath,
356
- propertyName: params.propertyName,
357
- propertyValue: processedValue
358
- });
359
- return { success: true, result: res };
360
- } catch (err: any) {
361
- // Check for specific error types
362
- const errorMsg = err?.message || String(err);
363
- if (errorMsg.includes('404')) {
364
- return { success: false, error: `Property '${params.propertyName}' not found on object '${params.objectPath}'` };
365
- }
366
- if (errorMsg.includes('400')) {
367
- return { success: false, error: `Invalid value type for property '${params.propertyName}'` };
368
- }
369
- return { success: false, error: errorMsg };
370
- }
371
- }, 'setProperty');
372
- }
373
-
374
- // Get a property value via Remote Control property endpoint
375
- async getProperty(params: { objectPath: string; propertyName: string }) {
376
- return this.executeWithRetry(async () => {
377
- try {
378
- const res = await this.bridge.httpCall('/remote/object/property', 'GET', {
379
- objectPath: params.objectPath,
380
- propertyName: params.propertyName
381
- });
382
- return { success: true, value: res };
383
- } catch (err: any) {
384
- const errorMsg = err?.message || String(err);
385
- if (errorMsg.includes('404')) {
386
- return { success: false, error: `Property '${params.propertyName}' not found on object '${params.objectPath}'` };
387
- }
388
- return { success: false, error: errorMsg };
389
- }
390
- }, 'getProperty');
391
- }
392
-
393
- /**
394
- * List all available Remote Control presets
395
- */
396
- async listPresets(): Promise<{ success: boolean; presets?: RCPreset[]; error?: string }> {
397
- const python = `
398
- import unreal, json
399
- try:
400
- presets = []
401
- # Try to list assets in common RC preset locations
402
- for path in ["/Game/RCPresets", "/Game/RemoteControl", "/Game"]:
403
- try:
404
- assets = unreal.EditorAssetLibrary.list_assets(path, recursive=True)
405
- for asset in assets:
406
- if "RemoteControlPreset" in asset:
407
- try:
408
- preset = unreal.EditorAssetLibrary.load_asset(asset)
409
- if preset:
410
- presets.append({
411
- "id": asset,
412
- "name": preset.get_name(),
413
- "path": asset,
414
- "description": getattr(preset, 'description', '')
415
- })
416
- except Exception:
417
- pass
418
- except Exception:
419
- pass
420
- print('RESULT:' + json.dumps({'success': True, 'presets': presets}))
421
- except Exception as e:
422
- print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))
423
- `.trim();
424
-
425
- const resp = await this.executeWithRetry(
426
- () => this.bridge.executePython(python),
427
- 'listPresets'
428
- );
429
-
430
- const result = this.parsePythonResult(resp, 'listPresets');
431
-
432
- // Update cache
433
- if (result.success && result.presets) {
434
- result.presets.forEach((p: RCPreset) => {
435
- this.presetCache.set(p.id, p);
436
- });
437
- }
438
-
439
- return result;
440
- }
441
-
442
- /**
443
- * Delete a Remote Control preset
444
- */
445
- async deletePreset(presetId: string): Promise<{ success: boolean; error?: string }> {
446
- const python = `
447
- import unreal, json
448
- preset_id = r"${presetId}"
449
- try:
450
- if unreal.EditorAssetLibrary.does_asset_exist(preset_id):
451
- success = unreal.EditorAssetLibrary.delete_asset(preset_id)
452
- if success:
453
- print('RESULT:' + json.dumps({'success': True}))
454
- else:
455
- print('RESULT:' + json.dumps({'success': False, 'error': 'Failed to delete preset'}))
456
- else:
457
- print('RESULT:' + json.dumps({'success': False, 'error': 'Preset not found'}))
458
- except Exception as e:
459
- print('RESULT:' + json.dumps({'success': False, 'error': str(e)}))
460
- `.trim();
461
-
462
- const resp = await this.executeWithRetry(
463
- () => this.bridge.executePython(python),
464
- 'deletePreset'
465
- );
466
-
467
- const result = this.parsePythonResult(resp, 'deletePreset');
468
-
469
- // Remove from cache if successful
470
- if (result.success) {
471
- this.presetCache.delete(presetId);
472
- }
473
-
474
- return result;
475
- }
476
-
477
- /**
478
- * Call an exposed function through Remote Control
479
- */
480
- async callFunction(params: {
481
- presetPath: string;
482
- functionName: string;
483
- parameters?: Record<string, any>
484
- }): Promise<{ success: boolean; result?: any; error?: string }> {
485
- try {
486
- const res = await this.bridge.httpCall('/remote/object/call', 'PUT', {
487
- objectPath: params.presetPath,
488
- functionName: params.functionName,
489
- parameters: params.parameters || {}
490
- });
491
- return { success: true, result: res };
492
- } catch (err: any) {
493
- return { success: false, error: String(err?.message || err) };
494
- }
495
- }
496
-
497
- /**
498
- * Validate connection to Remote Control
499
- */
500
- async validateConnection(): Promise<boolean> {
501
- try {
502
- await this.bridge.httpCall('/remote/info', 'GET', {});
503
- return true;
504
- } catch {
505
- return false;
506
- }
507
- }
508
-
509
- /**
510
- * Clear preset cache
511
- */
512
- clearCache(): void {
513
- this.presetCache.clear();
514
- }
515
- }