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
@@ -0,0 +1,66 @@
1
+ import { Client } from '@modelcontextprotocol/sdk/client/index.js';
2
+ import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
3
+ import { spawn } from 'child_process';
4
+ import path from 'path';
5
+ import { fileURLToPath } from 'url';
6
+
7
+ const __dirname = path.dirname(fileURLToPath(import.meta.url));
8
+ const SERVER_PATH = path.resolve(__dirname, '../dist/index.js');
9
+
10
+ async function runTest() {
11
+ const serverProcess = spawn('node', [SERVER_PATH], {
12
+ stdio: ['pipe', 'pipe', 'inherit']
13
+ });
14
+
15
+ const transport = new StdioClientTransport({
16
+ command: 'node',
17
+ args: [SERVER_PATH]
18
+ });
19
+
20
+ const client = new Client({
21
+ name: 'test-search-assets',
22
+ version: '1.0.0'
23
+ }, {
24
+ capabilities: {}
25
+ });
26
+
27
+ try {
28
+ await client.connect(transport);
29
+ console.log('Connected to MCP server');
30
+
31
+ // Test 1: Search for StaticMeshes in /Engine/BasicShapes
32
+ console.log('\nTest 1: Searching for StaticMeshes in /Engine/BasicShapes...');
33
+ const result1 = await client.callTool({
34
+ name: 'manage_asset',
35
+ arguments: {
36
+ action: 'search_assets',
37
+ classNames: ['StaticMesh'],
38
+ packagePaths: ['/Engine/BasicShapes'],
39
+ recursivePaths: true,
40
+ limit: 5
41
+ }
42
+ });
43
+ console.log('Result 1:', JSON.stringify(result1, null, 2));
44
+
45
+ // Test 2: Search for Blueprints with limit
46
+ console.log('\nTest 2: Searching for Blueprints (limit 2)...');
47
+ const result2 = await client.callTool({
48
+ name: 'manage_asset',
49
+ arguments: {
50
+ action: 'search_assets',
51
+ classNames: ['Blueprint'],
52
+ packagePaths: ['/Game'],
53
+ limit: 2
54
+ }
55
+ });
56
+ console.log('Result 2:', JSON.stringify(result2, null, 2));
57
+
58
+ } catch (error) {
59
+ console.error('Test failed:', error);
60
+ } finally {
61
+ await client.close();
62
+ process.exit(0);
63
+ }
64
+ }
65
+
66
+ runTest();
@@ -0,0 +1,68 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Sequencer Test Suite (supported actions only)
4
+ * Tool: manage_sequence
5
+ */
6
+
7
+ import { runToolTests } from './test-runner.mjs';
8
+
9
+ const seqPath = '/Game/Cinematics/TC_Seq';
10
+ const copyDir = '/Game/Cinematics/Copies';
11
+
12
+ const testCases = [
13
+ { scenario: 'Create sequence', toolName: 'manage_sequence', arguments: { action: 'create', name: 'TC_Seq', path: '/Game/Cinematics' }, expected: 'success|Sequence already exists' },
14
+ { scenario: 'Open sequence', toolName: 'manage_sequence', arguments: { action: 'open', path: seqPath }, expected: 'success' },
15
+ { scenario: 'Add camera (spawn-only fallback ok)', toolName: 'manage_sequence', arguments: { action: 'add_camera', spawnable: true }, expected: 'success' },
16
+ { scenario: 'Get bindings', toolName: 'manage_sequence', arguments: { action: 'get_bindings', path: seqPath }, expected: 'success - bindings listed' },
17
+ { scenario: 'Set playback speed', toolName: 'manage_sequence', arguments: { action: 'set_playback_speed', path: seqPath, speed: 1.2 }, expected: 'success' },
18
+ { scenario: 'Get sequence properties', toolName: 'manage_sequence', arguments: { action: 'get_properties', path: seqPath }, expected: 'success|INVALID_SEQUENCE' },
19
+ { scenario: 'Duplicate sequence', toolName: 'manage_sequence', arguments: { action: 'duplicate', path: seqPath, destinationPath: copyDir, newName: 'TC_Seq_Copy', overwrite: true }, expected: 'success - duplicated' },
20
+ { scenario: 'Rename sequence copy', toolName: 'manage_sequence', arguments: { action: 'rename', path: `${copyDir}/TC_Seq_Copy`, newName: 'TC_Seq_Renamed' }, expected: 'success|Failed to rename' },
21
+ { scenario: 'Delete sequence copy', toolName: 'manage_sequence', arguments: { action: 'delete', path: `${copyDir}/TC_Seq_Renamed` }, expected: 'success|Failed to delete' },
22
+ // Real-World Scenario: Cinematic Shot
23
+ // Setup: Ensure TC_Cube exists for the cinematic
24
+ { scenario: 'Setup - Spawn Cube for Cinematic', toolName: 'control_actor', arguments: { action: 'spawn', classPath: '/Engine/BasicShapes/Cube', actorName: 'TC_Cube', location: { x: 0, y: 0, z: 0 } }, expected: 'success' },
25
+ { scenario: 'Cinematic - Create Sequence', toolName: 'manage_sequence', arguments: { action: 'create', name: 'TC_Cinematic', path: '/Game/Cinematics' }, expected: 'success|Sequence already exists' },
26
+ { scenario: 'Cinematic - Add Actor', toolName: 'manage_sequence', arguments: { action: 'add_actor', path: '/Game/Cinematics/TC_Cinematic', actorName: 'TC_Cube' }, expected: 'success' },
27
+ { scenario: 'Cinematic - Keyframe Transform', toolName: 'manage_sequence', arguments: { action: 'add_keyframe', path: '/Game/Cinematics/TC_Cinematic', actorName: 'TC_Cube', property: 'Transform', frame: 0, value: { location: { x: 0, y: 0, z: 0 } } }, expected: 'success' },
28
+ { scenario: 'Cinematic - Keyframe End', toolName: 'manage_sequence', arguments: { action: 'add_keyframe', path: '/Game/Cinematics/TC_Cinematic', actorName: 'TC_Cube', property: 'Transform', frame: 60, value: { location: { x: 200, y: 0, z: 0 } } }, expected: 'success' },
29
+
30
+ // Cleanup
31
+ { scenario: 'Cleanup - Delete Cinematic', toolName: 'manage_sequence', arguments: { action: 'delete', path: '/Game/Cinematics/TC_Cinematic' }, expected: 'success|Failed to delete' },
32
+ { scenario: 'Cleanup - Delete Cube', toolName: 'control_actor', arguments: { action: 'delete', actorName: 'TC_Cube' }, expected: 'success' },
33
+ { scenario: 'Delete original sequence', toolName: 'manage_sequence', arguments: { action: 'delete', path: seqPath }, expected: 'success|Failed to delete' },
34
+ { scenario: 'Verify sequence removed', toolName: 'manage_sequence', arguments: { action: 'get_bindings', path: seqPath }, expected: 'success|not found|error|ASSET_NOT_FOUND|LOAD_FAILED' },
35
+
36
+ {
37
+ scenario: "Error: Invalid actor name",
38
+ toolName: "manage_sequence",
39
+ arguments: { action: "add_actor", path: seqPath, actorName: "NonExistentActor" },
40
+ expected: "not_found|error|ASSET_NOT_FOUND|LOAD_FAILED"
41
+ },
42
+ {
43
+ scenario: "Edge: Playback speed 0",
44
+ toolName: "manage_sequence",
45
+ arguments: { action: "set_playback_speed", speed: 0 },
46
+ expected: "error"
47
+ },
48
+ {
49
+ scenario: "Border: Empty actors array",
50
+ toolName: "manage_sequence",
51
+ arguments: { action: "add_actors", path: seqPath, actorNames: [] },
52
+ expected: "actorNames required|INVALID_ARGUMENT"
53
+ },
54
+ {
55
+ scenario: "Error: Invalid class spawnable",
56
+ toolName: "manage_sequence",
57
+ arguments: { action: "add_spawnable_from_class", path: seqPath, className: "InvalidClass" },
58
+ expected: "error"
59
+ },
60
+ {
61
+ scenario: "Cleanup Sequence Tests",
62
+ toolName: "manage_asset",
63
+ arguments: { action: "delete", assetPaths: [seqPath] },
64
+ expected: "success|ASSET_NOT_FOUND|LOAD_FAILED"
65
+ }
66
+ ];
67
+
68
+ await runToolTests('Sequences', testCases);
@@ -0,0 +1,57 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * Condensed System Control Test Suite (15 safe cases)
4
+ * Tool: system_control
5
+ * This file avoids destructive operations (engine quit/start) and focuses on
6
+ * safe diagnostics, screenshots, widget operations, CVARs, and profiling toggles.
7
+ */
8
+
9
+ import { runToolTests } from './test-runner.mjs';
10
+
11
+ const testCases = [
12
+ { scenario: 'Enable FPS display', toolName: 'system_control', arguments: { action: 'show_fps', enabled: true }, expected: 'success - FPS shown' },
13
+ { scenario: 'Disable FPS display', toolName: 'system_control', arguments: { action: 'show_fps', enabled: false }, expected: 'success - FPS hidden' },
14
+ { scenario: 'Enable CPU profiling (brief)', toolName: 'system_control', arguments: { action: 'profile', profileType: 'CPU', enabled: true }, expected: 'success - profiling enabled' },
15
+ { scenario: 'Disable CPU profiling', toolName: 'system_control', arguments: { action: 'profile', profileType: 'CPU', enabled: false }, expected: 'success - profiling disabled' },
16
+ { scenario: 'Set shadow quality to medium', toolName: 'system_control', arguments: { action: 'set_quality', category: 'Shadow', level: 1 }, expected: 'success - quality set' },
17
+ { scenario: 'Set texture quality to high', toolName: 'system_control', arguments: { action: 'set_quality', category: 'Texture', level: 2 }, expected: 'success - quality set' },
18
+ { scenario: 'Execute console command (stat fps)', toolName: 'system_control', arguments: { action: 'execute_command', command: 'stat fps' }, expected: 'success - console command executed' },
19
+ { scenario: 'Take a screenshot', toolName: 'system_control', arguments: { action: 'screenshot', filename: 'tc_sys_screenshot' }, expected: 'success - screenshot taken' },
20
+ { scenario: 'Take screenshot with metadata', toolName: 'system_control', arguments: { action: 'screenshot', includeMetadata: true, metadata: { test: 'system_tc' } }, expected: 'success - metadata screenshot taken' },
21
+ { scenario: 'Create debug widget asset', toolName: 'system_control', arguments: { action: 'create_widget', name: 'TestWidget_Safe', savePath: '/Game/Tests' }, expected: 'success - widget created or handled' },
22
+ { scenario: 'Show short notification', toolName: 'system_control', arguments: { action: 'show_widget', widgetId: 'Notification', visible: true, message: 'TC: Notification', duration: 1.5 }, expected: 'success - notification shown' },
23
+ { scenario: 'Set VSync CVAR', toolName: 'system_control', arguments: { action: 'set_cvar', name: 'r.VSync', value: '0' }, expected: 'success - CVAR set' },
24
+ { scenario: 'Set max FPS CVAR', toolName: 'system_control', arguments: { action: 'set_cvar', name: 't.MaxFPS', value: '60' }, expected: 'success - CVAR set' },
25
+ { scenario: 'Play short UI sound (best-effort)', toolName: 'system_control', arguments: { action: 'play_sound', soundPath: '/Engine/EditorSounds/Notifications/CompileSuccess.CompileSuccess', volume: 0.5 }, expected: 'success - sound played or handled' },
26
+ { scenario: 'Create console widget asset', toolName: 'system_control', arguments: { action: 'create_widget', name: 'TestWidget_Console', savePath: '/Game/Tests' }, expected: 'success - widget created or handled' },
27
+ // Additional
28
+ // Real-World Scenario: Project Validation
29
+ { scenario: 'Validation - Check Settings', toolName: 'system_control', arguments: { action: 'get_project_settings', category: 'Project' }, expected: 'success' },
30
+ { scenario: 'Validation - Validate Assets', toolName: 'system_control', arguments: { action: 'validate_assets', paths: ['/Game'] }, expected: 'success' },
31
+ {
32
+ scenario: "Error: Invalid profile type",
33
+ toolName: "system_control",
34
+ arguments: { action: "profile", profileType: "InvalidProfile" },
35
+ expected: "error"
36
+ },
37
+ {
38
+ scenario: "Edge: Quality level 0 (low)",
39
+ toolName: "system_control",
40
+ arguments: { action: "set_quality", category: "ViewDistance", level: 0 },
41
+ expected: "success"
42
+ },
43
+ {
44
+ scenario: "Border: Volume 0 (silent)",
45
+ toolName: "system_control",
46
+ arguments: { action: "play_sound", soundPath: "/Engine/EditorSounds/Notifications/CompileSuccess.CompileSuccess", volume: 0 },
47
+ expected: "success"
48
+ },
49
+ {
50
+ scenario: "Error: Invalid resolution",
51
+ toolName: "system_control",
52
+ arguments: { action: "set_resolution", width: -1, height: -1 },
53
+ expected: "error|validation"
54
+ }
55
+ ];
56
+
57
+ await runToolTests('System Control', testCases);
@@ -0,0 +1,193 @@
1
+ #!/usr/bin/env node
2
+ /**
3
+ * WebAssembly Integration Test Suite
4
+ *
5
+ * Tests the WebAssembly integration and fallback mechanisms
6
+ */
7
+
8
+ import { wasmIntegration } from '../dist/wasm/index.js';
9
+ import { pathToFileURL } from 'node:url';
10
+
11
+ const log = {
12
+ info: (...args) => console.log('[INFO]', ...args),
13
+ warn: (...args) => console.warn('[WARN]', ...args),
14
+ error: (...args) => console.error('[ERROR]', ...args),
15
+ debug: (...args) => console.debug('[DEBUG]', ...args)
16
+ };
17
+
18
+ async function testWASMIntegration() {
19
+ log.info('Starting WebAssembly integration test...\n');
20
+
21
+ // Test 1: Environment Check
22
+ log.info('=== Test 1: Environment Check ===');
23
+ const isSupported = wasmIntegration.constructor.isSupported();
24
+ log.info(`WebAssembly supported: ${isSupported}`);
25
+
26
+ if (!isSupported) {
27
+ log.warn('WebAssembly not supported, testing TypeScript fallbacks only');
28
+ }
29
+
30
+ // Test 2: Initialization
31
+ log.info('\n=== Test 2: Initialization ===');
32
+ try {
33
+ await wasmIntegration.initialize();
34
+ log.info('✅ Initialization successful');
35
+
36
+ if (wasmIntegration.isReady()) {
37
+ log.info('✅ WASM module is ready');
38
+ } else {
39
+ log.warn('⚠️ WASM module not ready, using TypeScript fallbacks');
40
+ }
41
+ } catch (error) {
42
+ log.error('❌ Initialization failed:', error.message);
43
+ log.info('This is expected if WASM module is not built yet');
44
+ }
45
+
46
+ // Test 3: Property Parsing
47
+ log.info('\n=== Test 3: Property Parsing ===');
48
+ const testJson = JSON.stringify({
49
+ name: 'TestAsset',
50
+ value: 42,
51
+ location: { x: 100, y: 200, z: 300 },
52
+ tags: ['tag1', 'tag2'],
53
+ properties: {
54
+ material: { name: 'Mat1', intensity: 5000 }
55
+ }
56
+ });
57
+
58
+ try {
59
+ const start = performance.now();
60
+ const result = await wasmIntegration.parseProperties(testJson);
61
+ const duration = performance.now() - start;
62
+
63
+ log.info(`✅ Property parsing completed in ${duration.toFixed(2)}ms`);
64
+ log.info(`Result has ${Object.keys(result).length} properties`);
65
+
66
+ if (result && typeof result === 'object') {
67
+ log.info('Result structure is valid');
68
+ }
69
+ } catch (error) {
70
+ log.error('❌ Property parsing failed:', error.message);
71
+ }
72
+
73
+ // Test 4: Transform Calculations
74
+ log.info('\n=== Test 4: Transform Calculations ===');
75
+ try {
76
+ const location = [100, 200, 300];
77
+ const rotation = [0, 90, 0];
78
+ const scale = [1, 1, 1];
79
+
80
+ const matrix = wasmIntegration.composeTransform(location, rotation, scale);
81
+
82
+ log.info(`✅ Transform composition successful`);
83
+ log.info(`Matrix length: ${matrix.length} (expected: 9)`);
84
+
85
+ if (matrix.length === 9) {
86
+ log.info('✅ Matrix has correct length');
87
+ }
88
+
89
+ // Test matrix decomposition
90
+ const decomposed = wasmIntegration.decomposeMatrix(matrix);
91
+ log.info(`✅ Matrix decomposition successful`);
92
+ log.info(`Decomposed: [${decomposed.slice(0, 3).join(', ')}, ...]`);
93
+ } catch (error) {
94
+ log.error('❌ Transform calculation failed:', error.message);
95
+ }
96
+
97
+ // Test 5: Vector Operations
98
+ log.info('\n=== Test 5: Vector Operations ===');
99
+ try {
100
+ const v1 = [1, 2, 3];
101
+ const v2 = [4, 5, 6];
102
+ const result = wasmIntegration.vectorAdd(v1, v2);
103
+
104
+ log.info(`✅ Vector addition successful`);
105
+ log.info(`${v1.join(', ')} + ${v2.join(', ')} = [${result.join(', ')}]`);
106
+
107
+ // Verify result
108
+ const expected = [5, 7, 9];
109
+ const isCorrect = result.every((val, idx) => Math.abs(val - expected[idx]) < 0.001);
110
+
111
+ if (isCorrect) {
112
+ log.info('✅ Vector addition result is correct');
113
+ } else {
114
+ log.warn('⚠️ Vector addition result may be incorrect');
115
+ }
116
+ } catch (error) {
117
+ log.error('❌ Vector operation failed:', error.message);
118
+ }
119
+
120
+ // Test 6: Dependency Resolution
121
+ log.info('\n=== Test 6: Dependency Resolution ===');
122
+ const testDependencies = {
123
+ 'AssetA': ['AssetB', 'AssetC'],
124
+ 'AssetB': ['AssetC'],
125
+ 'AssetC': []
126
+ };
127
+
128
+ try {
129
+ const result = await wasmIntegration.resolveDependencies('AssetA', testDependencies);
130
+
131
+ log.info(`✅ Dependency resolution successful`);
132
+ log.info(`Found ${result.dependencies?.length || 0} dependencies`);
133
+ log.info(`Asset path: ${result.asset}`);
134
+
135
+ if (result.dependencies && result.dependencies.length > 0) {
136
+ log.info('First dependency:', result.dependencies[0].path);
137
+ }
138
+ } catch (error) {
139
+ log.error('❌ Dependency resolution failed:', error.message);
140
+ }
141
+
142
+ // Test 7: Performance Metrics
143
+ log.info('\n=== Test 7: Performance Metrics ===');
144
+ const metrics = wasmIntegration.getMetrics();
145
+
146
+ log.info(`Total operations: ${metrics.totalOperations}`);
147
+ log.info(`WASM operations: ${metrics.wasmOperations}`);
148
+ log.info(`TypeScript operations: ${metrics.tsOperations}`);
149
+ log.info(`Average time: ${metrics.averageTime.toFixed(2)}ms`);
150
+
151
+ if (metrics.totalOperations > 0) {
152
+ log.info('✅ Performance metrics collected');
153
+ }
154
+
155
+ // Print detailed performance report
156
+ log.info('\n=== Performance Report ===');
157
+ log.info(wasmIntegration.reportPerformance());
158
+
159
+ // Test 8: Fallback Mechanism
160
+ log.info('\n=== Test 8: Fallback Mechanism ===');
161
+ log.info('Testing TypeScript fallback by clearing metrics...');
162
+ wasmIntegration.clearMetrics();
163
+
164
+ // Force a few operations to test metrics
165
+ await wasmIntegration.parseProperties(testJson);
166
+ const newMetrics = wasmIntegration.getMetrics();
167
+
168
+ log.info(`✅ Metrics reset successful (${newMetrics.totalOperations} operations)`);
169
+
170
+ // Final Summary
171
+ log.info('\n=== Test Summary ===');
172
+ log.info('All tests completed. Check the output above for details.');
173
+ log.info('');
174
+ log.info('Note: Some tests may use TypeScript fallbacks if WASM is not available.');
175
+ log.info('This is expected behavior and the integration will still work correctly.');
176
+ log.info('');
177
+ log.info('To use WebAssembly:');
178
+ log.info('1. Build the WASM module: cd wasm && wasm-pack build --target web');
179
+ log.info('2. Copy the pkg/ directory to src/wasm/');
180
+ log.info('3. Set environment variable: WASM_ENABLED=true');
181
+ log.info('4. Run tests again');
182
+
183
+ process.exit(0);
184
+ }
185
+
186
+ const mainScriptUrl = pathToFileURL(process.argv[1]).href;
187
+
188
+ if (import.meta.url === mainScriptUrl) {
189
+ testWASMIntegration().catch(error => {
190
+ log.error('Test failed with error:', error);
191
+ process.exit(1);
192
+ });
193
+ }
@@ -0,0 +1,215 @@
1
+ import { TestRunner } from './test-runner.mjs';
2
+
3
+ const runner = new TestRunner('World Partition Tests');
4
+ const timestamp = Date.now();
5
+ const bpName = `BP_WP_Test_${timestamp}`;
6
+ const bpPath = `/Game/Tests/WP/${bpName}`;
7
+ let testActorPath = '';
8
+
9
+ runner.addStep('Create Test Blueprint', async (tools) => {
10
+ const result = await tools.executeTool('manage_blueprint', {
11
+ action: 'create',
12
+ name: bpName,
13
+ blueprintType: 'Actor',
14
+ savePath: '/Game/Tests/WP',
15
+ waitForCompletion: true
16
+ });
17
+ return result.success;
18
+ });
19
+
20
+ runner.addStep('Spawn Test Actor', async (tools) => {
21
+ // Wait for Asset Registry to catch up
22
+ await new Promise(r => setTimeout(r, 2000));
23
+
24
+ // Use spawn_blueprint which handles class resolution internally
25
+ // avoiding the need to manually construct _C paths and cleaner error handling
26
+ const result = await tools.executeTool('control_actor', {
27
+ action: 'spawn_blueprint',
28
+ blueprintPath: bpPath,
29
+ location: { x: 0, y: 0, z: 500 }
30
+ });
31
+ /* DEBUG LOGGING */
32
+ // Handle nested result structure from automation responses
33
+ const resultData = result.result || result;
34
+ const actorPathValue = resultData.actorPath || result.actorPath;
35
+ const actorNameValue = resultData.actorName || result.actorName;
36
+
37
+ const logMsg = `Spawn Result: Success=${result.success}, ActorPath=${actorPathValue}, ActorName=${actorNameValue}`;
38
+ await tools.executeTool('system_control', {
39
+ action: 'console_command',
40
+ command: `Log "${logMsg}"`
41
+ }).catch(() => { });
42
+
43
+ if (result.success && actorPathValue) {
44
+ testActorPath = actorPathValue;
45
+ // Wait for Actor to be fully registered in World Partition system
46
+ await new Promise(r => setTimeout(r, 1000));
47
+ return true;
48
+ }
49
+
50
+ // Also accept actorName as fallback for finding the actor
51
+ if (result.success && actorNameValue) {
52
+ testActorPath = actorNameValue;
53
+ await new Promise(r => setTimeout(r, 1000));
54
+ return true;
55
+ }
56
+
57
+ return false;
58
+ });
59
+
60
+
61
+ runner.addStep('Load World Partition Cells', async (tools) => {
62
+ const result = await tools.executeTool('manage_world_partition', {
63
+ action: 'load_cells',
64
+ origin: [0, 0, 0],
65
+ extent: [10000, 10000, 10000]
66
+ });
67
+ // Success or NOT_IMPLEMENTED (if not WP level) are both acceptable "pass" states for automation check
68
+ return true;
69
+ });
70
+
71
+ runner.addStep('Create Data Layer', async (tools) => {
72
+ // If we are in a WP level, we should be able to create data layers
73
+ try {
74
+ const result = await tools.executeTool('manage_world_partition', {
75
+ action: 'create_datalayer',
76
+ dataLayerName: 'TestLayer'
77
+ });
78
+
79
+ // It's robust to accept success or "already exists"
80
+ if (result.success) return true;
81
+ if (result.message && result.message.includes('already exists')) return true;
82
+
83
+ // If not supported (e.g. non-editor or no subsystem), we might skip or fail.
84
+ // Given the previous step passes on NOT_SUPPORTED, we might want to do the same here.
85
+ if (result.error === 'NOT_SUPPORTED' || result.error === 'SUBSYSTEM_NOT_FOUND') {
86
+ console.log('DEBUG: Create Data Layer not supported, skipping creation.');
87
+ return true;
88
+ }
89
+
90
+ // Fail if we expected it to work
91
+ return false;
92
+ } catch (e) {
93
+ if (e.message.includes('Unknown subAction')) {
94
+ // Plugin might not be recompiled yet, warn but don't fail hard if SetDataLayer expects failure?
95
+ // But typically we want this to work.
96
+ console.log('DEBUG: create_datalayer not implemented in plugin subAction.');
97
+ return false;
98
+ }
99
+ throw e;
100
+ }
101
+ });
102
+
103
+ runner.addStep('Set Data Layer', async (tools) => {
104
+ console.log('DEBUG: Starting Set Data Layer step');
105
+ try {
106
+ if (!testActorPath) {
107
+ throw new Error('No test actor spawned');
108
+ }
109
+
110
+ let attempt = 0;
111
+ let result;
112
+ while (attempt < 3) {
113
+ console.log(`DEBUG: Set Data Layer Attempt ${attempt + 1}`);
114
+ try {
115
+ result = await tools.executeTool('manage_world_partition', {
116
+ action: 'set_datalayer',
117
+ actorPath: testActorPath,
118
+ dataLayerName: 'TestLayer'
119
+ });
120
+ } catch (toolErr) {
121
+ console.error('DEBUG: executeTool threw:', toolErr);
122
+ throw toolErr;
123
+ }
124
+
125
+ // Debug log to Unreal console
126
+ await tools.executeTool('system_control', {
127
+ action: 'console_command',
128
+ command: `Log "SetDataLayer Attempt ${attempt + 1}: ${result.success ? 'Success' : result.error || result.message}"`
129
+ }).catch(() => { });
130
+
131
+ if (result.success) return true;
132
+ if (result.error === 'DATALAYER_NOT_FOUND') return true;
133
+ if (result.message && result.message.includes('not found')) return true;
134
+
135
+ // If actor not found, retry
136
+ if (result.error === 'ACTOR_NOT_FOUND') {
137
+ console.log('DEBUG: Actor not found, retrying...');
138
+ await new Promise(r => setTimeout(r, 1000));
139
+ attempt++;
140
+ continue;
141
+ }
142
+ break;
143
+ }
144
+
145
+ // If it failed with ACTOR_NOT_FOUND after retries, fail the test
146
+ if (result.error === 'ACTOR_NOT_FOUND') return false;
147
+
148
+ return true;
149
+ } catch (e) {
150
+ console.error('DEBUG: Set Data Layer Step FAILED with exception:', e);
151
+ await tools.executeTool('system_control', {
152
+ action: 'console_command',
153
+ command: `Log "SetDataLayer Step EXCEPTION: ${e.message}"`
154
+ }).catch(() => { });
155
+ throw e;
156
+ }
157
+ });
158
+
159
+ runner.addStep('Cleanup Actor', async (tools) => {
160
+ if (!testActorPath) return true;
161
+ try {
162
+ await tools.executeTool('control_actor', {
163
+ action: 'delete',
164
+ actorPath: testActorPath
165
+ });
166
+ } catch (e) {
167
+ console.warn(`[WARN] Failed to delete actor: ${e.message}`);
168
+ }
169
+ return true;
170
+ });
171
+
172
+ runner.addStep('Wait for Cleanup', async (tools) => {
173
+ // Multiple GC passes with delays to release all references
174
+ for (let i = 0; i < 5; i++) {
175
+ await tools.executeTool('system_control', { action: 'console_command', command: 'obj gc' });
176
+ await new Promise(r => setTimeout(r, 500));
177
+ }
178
+ // Additional wait for asset registry to update
179
+ await new Promise(r => setTimeout(r, 2000));
180
+ return true;
181
+ });
182
+
183
+ runner.addStep('Cleanup Blueprint', async (tools) => {
184
+ // Try to delete the blueprint with retries
185
+ let deleted = false;
186
+ for (let attempt = 0; attempt < 3 && !deleted; attempt++) {
187
+ try {
188
+ // Force GC before each attempt
189
+ await tools.executeTool('system_control', { action: 'console_command', command: 'obj gc' });
190
+ await new Promise(r => setTimeout(r, 500));
191
+
192
+ const result = await tools.executeTool('manage_asset', {
193
+ action: 'delete',
194
+ assetPath: bpPath,
195
+ force: true // Request force delete if supported
196
+ });
197
+
198
+ if (result.success) {
199
+ deleted = true;
200
+ }
201
+ } catch (e) {
202
+ // Quietly retry
203
+ await new Promise(r => setTimeout(r, 1000));
204
+ }
205
+ }
206
+
207
+ if (!deleted) {
208
+ console.log(`[INFO] Could not delete test blueprint ${bpPath}. This is expected if the class is still in memory.`);
209
+ }
210
+
211
+ // Always return true - cleanup failures shouldn't fail the test
212
+ return true;
213
+ });
214
+
215
+ runner.run().catch(console.error);
package/tsconfig.json CHANGED
@@ -17,8 +17,8 @@
17
17
  "alwaysStrict": true,
18
18
 
19
19
  // Additional Checks
20
- "noUnusedLocals": false,
21
- "noUnusedParameters": false,
20
+ "noUnusedLocals": true,
21
+ "noUnusedParameters": true,
22
22
  "noImplicitReturns": true,
23
23
  "noFallthroughCasesInSwitch": true,
24
24
  "allowUnreachableCode": false,
@@ -34,7 +34,7 @@
34
34
  "declaration": true,
35
35
  "declarationMap": true,
36
36
  "sourceMap": true,
37
- "removeComments": false,
37
+ "removeComments": true,
38
38
  "importHelpers": false,
39
39
  "emitDeclarationOnly": false,
40
40