unreal-engine-mcp-server 0.4.6 → 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 +269 -22
  29. package/CONTRIBUTING.md +140 -0
  30. package/README.md +166 -72
  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 -604
  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 +5475 -1627
  97. package/dist/tools/consolidated-tool-definitions.js +829 -482
  98. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  99. package/dist/tools/consolidated-tool-handlers.js +211 -1009
  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 +45 -0
  161. package/dist/tools/logs.js +210 -0
  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 +195 -11
  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 -649
  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 -500
  316. package/src/tools/consolidated-tool-handlers.ts +272 -1122
  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 +219 -0
  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 +250 -13
  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 -572
  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,377 @@
1
+ //! Asset dependency resolution module
2
+ //!
3
+ //! This module provides efficient traversal and analysis of
4
+ //! asset dependency graphs.
5
+
6
+ use serde::{Deserialize, Serialize};
7
+ use std::collections::{HashSet, HashMap, VecDeque};
8
+ use wasm_bindgen::prelude::*;
9
+ use serde_wasm_bindgen as swb;
10
+
11
+ /// Asset dependency information
12
+ #[derive(Serialize, Deserialize, Clone)]
13
+ #[serde(rename_all = "camelCase")]
14
+ pub struct AssetDependency {
15
+ pub path: String,
16
+ pub dependencies: Vec<String>,
17
+ pub dependents: Vec<String>,
18
+ pub depth: u32,
19
+ }
20
+
21
+ /// Dependency graph analysis result
22
+ #[derive(Serialize, Deserialize)]
23
+ #[serde(rename_all = "camelCase")]
24
+ pub struct DependencyAnalysis {
25
+ pub asset: String,
26
+ pub dependencies: Vec<AssetDependency>,
27
+ pub total_dependency_count: usize,
28
+ pub max_depth: u32,
29
+ pub circular_dependencies: Vec<Vec<String>>,
30
+ pub analysis_time_ms: f64,
31
+ }
32
+
33
+ #[wasm_bindgen]
34
+ pub struct DependencyResolver {
35
+ /// Maximum depth to prevent infinite recursion
36
+ max_depth: usize,
37
+ }
38
+
39
+ #[wasm_bindgen]
40
+ impl DependencyResolver {
41
+ /// Create a DependencyResolver with default max depth (100)
42
+ #[wasm_bindgen(constructor)]
43
+ pub fn new() -> DependencyResolver {
44
+ console_error_panic_hook::set_once();
45
+ DependencyResolver { max_depth: 100 }
46
+ }
47
+
48
+ /// Create a DependencyResolver with custom max depth
49
+ #[wasm_bindgen(js_name = withMaxDepth)]
50
+ pub fn with_max_depth(max_depth: usize) -> DependencyResolver {
51
+ console_error_panic_hook::set_once();
52
+ DependencyResolver { max_depth }
53
+ }
54
+
55
+ /// Analyze dependencies for an asset
56
+ #[wasm_bindgen(js_name = analyzeDependencies)]
57
+ pub fn analyze_dependencies(
58
+ &self,
59
+ asset_path: &str,
60
+ dependencies_json: &str,
61
+ max_depth: Option<usize>,
62
+ ) -> Result<JsValue, JsValue> {
63
+ let start = js_sys::Date::now();
64
+
65
+ let dependencies_map: HashMap<String, Vec<String>> = serde_json::from_str(dependencies_json)
66
+ .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
67
+
68
+ let depth_limit = max_depth.unwrap_or(self.max_depth);
69
+
70
+ if !dependencies_map.contains_key(asset_path) {
71
+ return Err(JsValue::from_str(&format!("Asset not found: {}", asset_path)));
72
+ }
73
+
74
+ let mut visited = HashSet::new();
75
+ let mut result = Vec::new();
76
+ let mut stack = VecDeque::new();
77
+ let mut circular_deps = Vec::new();
78
+
79
+ stack.push_back((asset_path.to_string(), 0));
80
+
81
+ while let Some((current_path, current_depth)) = stack.pop_front() {
82
+ if current_depth > depth_limit {
83
+ continue;
84
+ }
85
+
86
+ if visited.contains(&current_path) {
87
+ // Found circular dependency
88
+ circular_deps.push(vec![current_path.clone()]);
89
+ continue;
90
+ }
91
+
92
+ visited.insert(current_path.clone());
93
+
94
+ if let Some(deps) = dependencies_map.get(&current_path) {
95
+ result.push(AssetDependency {
96
+ path: current_path.clone(),
97
+ dependencies: deps.clone(),
98
+ dependents: self.find_dependents_internal(&current_path, &dependencies_map),
99
+ depth: current_depth as u32,
100
+ });
101
+
102
+ for dep in deps {
103
+ if !visited.contains(dep) {
104
+ stack.push_back((dep.clone(), current_depth + 1));
105
+ }
106
+ }
107
+ }
108
+ }
109
+
110
+ let analysis_time = js_sys::Date::now() - start;
111
+
112
+ let total_dependency_count = result.len();
113
+
114
+ let analysis = DependencyAnalysis {
115
+ asset: asset_path.to_string(),
116
+ dependencies: result,
117
+ total_dependency_count,
118
+ max_depth: depth_limit as u32,
119
+ circular_dependencies: circular_deps,
120
+ analysis_time_ms: analysis_time,
121
+ };
122
+
123
+ let js_value = swb::to_value(&analysis)
124
+ .map_err(|e| JsValue::from_str(&format!("Serialize error: {}", e)))?;
125
+ Ok(js_value)
126
+ }
127
+
128
+ /// Find all dependents of an asset
129
+ #[wasm_bindgen(js_name = findDependents)]
130
+ pub fn find_dependents(
131
+ &self,
132
+ asset_path: &str,
133
+ dependencies_json: &str,
134
+ ) -> Result<JsValue, JsValue> {
135
+ let dependencies_map: HashMap<String, Vec<String>> = serde_json::from_str(dependencies_json)
136
+ .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
137
+
138
+ let dependents = self.find_dependents_internal(asset_path, &dependencies_map);
139
+
140
+ let js_value = swb::to_value(&dependents)
141
+ .map_err(|e| JsValue::from_str(&format!("Serialize error: {}", e)))?;
142
+ Ok(js_value)
143
+ }
144
+
145
+ /// Calculate dependency depth
146
+ #[wasm_bindgen(js_name = calculateDepth)]
147
+ pub fn calculate_depth(
148
+ &self,
149
+ asset_path: &str,
150
+ dependencies_json: &str,
151
+ max_depth: Option<usize>,
152
+ ) -> Result<u32, JsValue> {
153
+ let dependencies_map: HashMap<String, Vec<String>> = serde_json::from_str(dependencies_json)
154
+ .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
155
+
156
+ let depth_limit = max_depth.unwrap_or(self.max_depth);
157
+
158
+ let depth = self.calculate_depth_internal(asset_path, &dependencies_map, depth_limit, &mut HashSet::new());
159
+
160
+ Ok(depth)
161
+ }
162
+
163
+ /// Find circular dependencies in the graph
164
+ #[wasm_bindgen(js_name = findCircularDependencies)]
165
+ pub fn find_circular_dependencies(
166
+ &self,
167
+ dependencies_json: &str,
168
+ max_depth: Option<usize>,
169
+ ) -> Result<JsValue, JsValue> {
170
+ let dependencies_map: HashMap<String, Vec<String>> = serde_json::from_str(dependencies_json)
171
+ .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
172
+
173
+ let depth_limit = max_depth.unwrap_or(self.max_depth);
174
+
175
+ let circular_deps = self.find_circular_dependencies_internal(&dependencies_map, depth_limit);
176
+
177
+ let js_value = swb::to_value(&circular_deps)
178
+ .map_err(|e| JsValue::from_str(&format!("Serialize error: {}", e)))?;
179
+ Ok(js_value)
180
+ }
181
+
182
+ /// Topological sort of dependencies
183
+ #[wasm_bindgen(js_name = topologicalSort)]
184
+ pub fn topological_sort(
185
+ &self,
186
+ dependencies_json: &str,
187
+ ) -> Result<JsValue, JsValue> {
188
+ let dependencies_map: HashMap<String, Vec<String>> = serde_json::from_str(dependencies_json)
189
+ .map_err(|e| JsValue::from_str(&format!("JSON parse error: {}", e)))?;
190
+
191
+ let sorted = self.topological_sort_internal(&dependencies_map)?;
192
+
193
+ let js_value = swb::to_value(&sorted)
194
+ .map_err(|e| JsValue::from_str(&format!("Serialize error: {}", e)))?;
195
+ Ok(js_value)
196
+ }
197
+ }
198
+
199
+ impl DependencyResolver {
200
+ fn find_dependents_internal(
201
+ &self,
202
+ asset_path: &str,
203
+ dependencies_map: &HashMap<String, Vec<String>>,
204
+ ) -> Vec<String> {
205
+ let mut dependents = Vec::new();
206
+
207
+ for (path, deps) in dependencies_map {
208
+ if deps.contains(&asset_path.to_string()) {
209
+ dependents.push(path.clone());
210
+ }
211
+ }
212
+
213
+ dependents
214
+ }
215
+
216
+ fn calculate_depth_internal(
217
+ &self,
218
+ asset_path: &str,
219
+ dependencies_map: &HashMap<String, Vec<String>>,
220
+ max_depth: usize,
221
+ visited: &mut HashSet<String>,
222
+ ) -> u32 {
223
+ if visited.contains(asset_path) {
224
+ return 0;
225
+ }
226
+
227
+ if max_depth == 0 {
228
+ return 0;
229
+ }
230
+
231
+ visited.insert(asset_path.to_string());
232
+
233
+ if let Some(deps) = dependencies_map.get(asset_path) {
234
+ if deps.is_empty() {
235
+ visited.remove(asset_path);
236
+ return 0;
237
+ }
238
+
239
+ let mut max_child_depth = 0;
240
+ for dep in deps {
241
+ let child_depth = self.calculate_depth_internal(
242
+ dep,
243
+ dependencies_map,
244
+ max_depth - 1,
245
+ visited,
246
+ );
247
+ max_child_depth = max_child_depth.max(child_depth);
248
+ }
249
+
250
+ visited.remove(asset_path);
251
+ max_child_depth + 1
252
+ } else {
253
+ visited.remove(asset_path);
254
+ 0
255
+ }
256
+ }
257
+
258
+ fn find_circular_dependencies_internal(
259
+ &self,
260
+ dependencies_map: &HashMap<String, Vec<String>>,
261
+ max_depth: usize,
262
+ ) -> Vec<Vec<String>> {
263
+ let mut cycles = Vec::new();
264
+ let mut visited = HashSet::new();
265
+ let mut stack = HashSet::new();
266
+
267
+ fn dfs(
268
+ current: &str,
269
+ dependencies_map: &HashMap<String, Vec<String>>,
270
+ visited: &mut HashSet<String>,
271
+ stack: &mut HashSet<String>,
272
+ cycles: &mut Vec<Vec<String>>,
273
+ path: &mut Vec<String>,
274
+ depth: usize,
275
+ max_depth: usize,
276
+ ) {
277
+ if depth > max_depth {
278
+ return;
279
+ }
280
+
281
+ visited.insert(current.to_string());
282
+ stack.insert(current.to_string());
283
+ path.push(current.to_string());
284
+
285
+ if let Some(deps) = dependencies_map.get(current) {
286
+ for dep in deps {
287
+ if !visited.contains(dep) {
288
+ dfs(
289
+ dep,
290
+ dependencies_map,
291
+ visited,
292
+ stack,
293
+ cycles,
294
+ path,
295
+ depth + 1,
296
+ max_depth,
297
+ );
298
+ } else if stack.contains(dep) {
299
+ // Found a cycle
300
+ let cycle_start = path.iter().position(|p| p == dep);
301
+ if let Some(start) = cycle_start {
302
+ cycles.push(path[start..].to_vec());
303
+ }
304
+ }
305
+ }
306
+ }
307
+
308
+ stack.remove(current);
309
+ path.pop();
310
+ }
311
+
312
+ for asset in dependencies_map.keys() {
313
+ if !visited.contains(asset) {
314
+ let mut path = Vec::new();
315
+ dfs(
316
+ asset,
317
+ dependencies_map,
318
+ &mut visited,
319
+ &mut stack,
320
+ &mut cycles,
321
+ &mut path,
322
+ 0,
323
+ max_depth,
324
+ );
325
+ }
326
+ }
327
+
328
+ cycles
329
+ }
330
+
331
+ fn topological_sort_internal(
332
+ &self,
333
+ dependencies_map: &HashMap<String, Vec<String>>,
334
+ ) -> Result<Vec<String>, JsValue> {
335
+ let mut in_degree: HashMap<String, usize> = HashMap::new();
336
+ let mut graph: HashMap<String, Vec<String>> = HashMap::new();
337
+
338
+ // Initialize
339
+ for (asset, deps) in dependencies_map {
340
+ in_degree.entry(asset.clone()).or_insert(0);
341
+ for dep in deps {
342
+ in_degree.entry(dep.clone()).or_insert(0);
343
+ graph.entry(dep.clone()).or_insert_with(Vec::new).push(asset.clone());
344
+ }
345
+ }
346
+
347
+ // Kahn's algorithm
348
+ let mut queue: VecDeque<String> = in_degree
349
+ .iter()
350
+ .filter(|(_, &degree)| degree == 0)
351
+ .map(|(asset, _)| asset.clone())
352
+ .collect();
353
+
354
+ let mut sorted = Vec::new();
355
+
356
+ while let Some(asset) = queue.pop_front() {
357
+ sorted.push(asset.clone());
358
+
359
+ if let Some(dependents) = graph.get(&asset) {
360
+ for dependent in dependents {
361
+ if let Some(&mut ref mut degree) = in_degree.get_mut(dependent) {
362
+ *degree -= 1;
363
+ if *degree == 0 {
364
+ queue.push_back(dependent.clone());
365
+ }
366
+ }
367
+ }
368
+ }
369
+ }
370
+
371
+ if sorted.len() != in_degree.len() {
372
+ return Err(JsValue::from_str("Graph contains cycles - topological sort not possible"));
373
+ }
374
+
375
+ Ok(sorted)
376
+ }
377
+ }
@@ -0,0 +1,153 @@
1
+ //! WebAssembly module for performance-critical operations
2
+ //! in the Unreal Engine MCP Server.
3
+ //!
4
+ //! This module provides optimized implementations for:
5
+ //! - Property parsing and serialization
6
+ //! - Transform calculations
7
+ //! - Vector math
8
+ //! - Asset dependency resolution
9
+
10
+ mod property_parser;
11
+ mod transform_math;
12
+ mod dependency_resolver;
13
+
14
+ pub use property_parser::PropertyParser;
15
+ pub use transform_math::{TransformCalculator, Vector, Rotator, Transform};
16
+ pub use dependency_resolver::DependencyResolver;
17
+
18
+ // Re-export wasm-bindgen for convenience
19
+ pub use wasm_bindgen::prelude::*;
20
+
21
+ /// Initialize the WASM module
22
+ #[wasm_bindgen(start)]
23
+ pub fn main() {
24
+ // This function is called when the module is loaded
25
+ console_error_panic_hook::set_once();
26
+ web_sys::console::log_1(&"WASM module initialized".into());
27
+ }
28
+
29
+ // Provide console logging in WASM
30
+ #[wasm_bindgen]
31
+ extern "C" {
32
+ #[wasm_bindgen(js_namespace = console)]
33
+ fn log(s: &str);
34
+
35
+ #[wasm_bindgen(js_namespace = console)]
36
+ fn error(s: &str);
37
+
38
+ #[wasm_bindgen(js_namespace = console)]
39
+ fn warn(s: &str);
40
+ }
41
+
42
+ /// Utility functions
43
+ #[wasm_bindgen]
44
+ pub struct Utils;
45
+
46
+ #[wasm_bindgen]
47
+ impl Utils {
48
+ /// Get the current high-resolution time in milliseconds
49
+ #[wasm_bindgen(js_name = now)]
50
+ pub fn now() -> f64 {
51
+ web_sys::window()
52
+ .and_then(|w| w.performance())
53
+ .map(|p| p.now())
54
+ .unwrap_or(0.0)
55
+ }
56
+
57
+ /// Generate a random floating-point number between 0 and 1
58
+ #[wasm_bindgen(js_name = random)]
59
+ pub fn random() -> f64 {
60
+ js_sys::Math::random()
61
+ }
62
+
63
+ /// Clamp a number between min and max
64
+ #[wasm_bindgen(js_name = clamp)]
65
+ pub fn clamp(value: f32, min: f32, max: f32) -> f32 {
66
+ value.max(min).min(max)
67
+ }
68
+
69
+ /// Linear interpolation between two values
70
+ #[wasm_bindgen(js_name = lerp)]
71
+ pub fn lerp(a: f32, b: f32, t: f32) -> f32 {
72
+ a + (b - a) * t
73
+ }
74
+
75
+ /// Convert degrees to radians
76
+ #[wasm_bindgen(js_name = degToRad)]
77
+ pub fn deg_to_rad(degrees: f32) -> f32 {
78
+ degrees * std::f32::consts::PI / 180.0
79
+ }
80
+
81
+ /// Convert radians to degrees
82
+ #[wasm_bindgen(js_name = radToDeg)]
83
+ pub fn rad_to_deg(radians: f32) -> f32 {
84
+ radians * 180.0 / std::f32::consts::PI
85
+ }
86
+ }
87
+
88
+ /// Performance metrics for WASM operations
89
+ #[wasm_bindgen]
90
+ pub struct Metrics {
91
+ operations: Vec<OperationMetric>,
92
+ }
93
+
94
+ #[derive(Clone)]
95
+ struct OperationMetric {
96
+ name: String,
97
+ duration_ms: f64,
98
+ #[allow(dead_code)]
99
+ timestamp: f64,
100
+ }
101
+
102
+ #[wasm_bindgen]
103
+ impl Metrics {
104
+ #[wasm_bindgen(constructor)]
105
+ pub fn new() -> Metrics {
106
+ Metrics {
107
+ operations: Vec::new(),
108
+ }
109
+ }
110
+
111
+ /// Record an operation
112
+ #[wasm_bindgen(js_name = record)]
113
+ pub fn record(&mut self, name: String, duration_ms: f64) {
114
+ let timestamp = js_sys::Date::now();
115
+ self.operations.push(OperationMetric {
116
+ name,
117
+ duration_ms,
118
+ timestamp,
119
+ });
120
+ }
121
+
122
+ /// Get average duration for an operation
123
+ #[wasm_bindgen(js_name = averageFor)]
124
+ pub fn average_for(&self, name: String) -> f64 {
125
+ let mut total = 0.0;
126
+ let mut count = 0.0;
127
+
128
+ for op in &self.operations {
129
+ if op.name == name {
130
+ total += op.duration_ms;
131
+ count += 1.0;
132
+ }
133
+ }
134
+
135
+ if count > 0.0 {
136
+ total / count
137
+ } else {
138
+ 0.0
139
+ }
140
+ }
141
+
142
+ /// Get total number of operations recorded
143
+ #[wasm_bindgen]
144
+ pub fn count(&self) -> u32 {
145
+ self.operations.len() as u32
146
+ }
147
+
148
+ /// Clear all metrics
149
+ #[wasm_bindgen]
150
+ pub fn clear(&mut self) {
151
+ self.operations.clear();
152
+ }
153
+ }