unreal-engine-mcp-server 0.4.7 → 0.5.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (454) hide show
  1. package/.env.example +26 -0
  2. package/.env.production +38 -7
  3. package/.eslintrc.json +0 -54
  4. package/.eslintrc.override.json +8 -0
  5. package/.github/ISSUE_TEMPLATE/bug_report.yml +94 -0
  6. package/.github/ISSUE_TEMPLATE/config.yml +8 -0
  7. package/.github/ISSUE_TEMPLATE/feature_request.yml +56 -0
  8. package/.github/copilot-instructions.md +478 -45
  9. package/.github/dependabot.yml +19 -0
  10. package/.github/labeler.yml +24 -0
  11. package/.github/labels.yml +70 -0
  12. package/.github/pull_request_template.md +42 -0
  13. package/.github/release-drafter-config.yml +51 -0
  14. package/.github/workflows/auto-merge.yml +38 -0
  15. package/.github/workflows/ci.yml +38 -0
  16. package/.github/workflows/dependency-review.yml +17 -0
  17. package/.github/workflows/gemini-issue-triage.yml +172 -0
  18. package/.github/workflows/greetings.yml +27 -0
  19. package/.github/workflows/labeler.yml +17 -0
  20. package/.github/workflows/links.yml +80 -0
  21. package/.github/workflows/pr-size-labeler.yml +137 -0
  22. package/.github/workflows/publish-mcp.yml +13 -7
  23. package/.github/workflows/release-drafter.yml +23 -0
  24. package/.github/workflows/release.yml +112 -0
  25. package/.github/workflows/semantic-pull-request.yml +35 -0
  26. package/.github/workflows/smoke-test.yml +36 -0
  27. package/.github/workflows/stale.yml +28 -0
  28. package/CHANGELOG.md +338 -31
  29. package/CONTRIBUTING.md +140 -0
  30. package/GEMINI.md +115 -0
  31. package/Public/Plugin_setup_guide.mp4 +0 -0
  32. package/README.md +189 -128
  33. package/claude_desktop_config_example.json +7 -6
  34. package/dist/automation/bridge.d.ts +50 -0
  35. package/dist/automation/bridge.js +452 -0
  36. package/dist/automation/connection-manager.d.ts +23 -0
  37. package/dist/automation/connection-manager.js +107 -0
  38. package/dist/automation/handshake.d.ts +11 -0
  39. package/dist/automation/handshake.js +89 -0
  40. package/dist/automation/index.d.ts +3 -0
  41. package/dist/automation/index.js +3 -0
  42. package/dist/automation/message-handler.d.ts +12 -0
  43. package/dist/automation/message-handler.js +149 -0
  44. package/dist/automation/request-tracker.d.ts +25 -0
  45. package/dist/automation/request-tracker.js +98 -0
  46. package/dist/automation/types.d.ts +130 -0
  47. package/dist/automation/types.js +2 -0
  48. package/dist/cli.js +32 -5
  49. package/dist/config.d.ts +26 -0
  50. package/dist/config.js +59 -0
  51. package/dist/constants.d.ts +16 -0
  52. package/dist/constants.js +16 -0
  53. package/dist/graphql/loaders.d.ts +64 -0
  54. package/dist/graphql/loaders.js +117 -0
  55. package/dist/graphql/resolvers.d.ts +268 -0
  56. package/dist/graphql/resolvers.js +746 -0
  57. package/dist/graphql/schema.d.ts +5 -0
  58. package/dist/graphql/schema.js +437 -0
  59. package/dist/graphql/server.d.ts +26 -0
  60. package/dist/graphql/server.js +117 -0
  61. package/dist/graphql/types.d.ts +9 -0
  62. package/dist/graphql/types.js +2 -0
  63. package/dist/handlers/resource-handlers.d.ts +20 -0
  64. package/dist/handlers/resource-handlers.js +180 -0
  65. package/dist/index.d.ts +33 -18
  66. package/dist/index.js +130 -619
  67. package/dist/resources/actors.d.ts +17 -12
  68. package/dist/resources/actors.js +56 -76
  69. package/dist/resources/assets.d.ts +6 -14
  70. package/dist/resources/assets.js +115 -147
  71. package/dist/resources/levels.d.ts +13 -13
  72. package/dist/resources/levels.js +25 -34
  73. package/dist/server/resource-registry.d.ts +20 -0
  74. package/dist/server/resource-registry.js +37 -0
  75. package/dist/server/tool-registry.d.ts +23 -0
  76. package/dist/server/tool-registry.js +322 -0
  77. package/dist/server-setup.d.ts +20 -0
  78. package/dist/server-setup.js +71 -0
  79. package/dist/services/health-monitor.d.ts +34 -0
  80. package/dist/services/health-monitor.js +105 -0
  81. package/dist/services/metrics-server.d.ts +11 -0
  82. package/dist/services/metrics-server.js +105 -0
  83. package/dist/tools/actors.d.ts +163 -9
  84. package/dist/tools/actors.js +356 -311
  85. package/dist/tools/animation.d.ts +135 -4
  86. package/dist/tools/animation.js +510 -411
  87. package/dist/tools/assets.d.ts +75 -29
  88. package/dist/tools/assets.js +265 -284
  89. package/dist/tools/audio.d.ts +102 -42
  90. package/dist/tools/audio.js +272 -685
  91. package/dist/tools/base-tool.d.ts +17 -0
  92. package/dist/tools/base-tool.js +46 -0
  93. package/dist/tools/behavior-tree.d.ts +94 -0
  94. package/dist/tools/behavior-tree.js +39 -0
  95. package/dist/tools/blueprint.d.ts +208 -126
  96. package/dist/tools/blueprint.js +685 -832
  97. package/dist/tools/consolidated-tool-definitions.d.ts +5462 -1781
  98. package/dist/tools/consolidated-tool-definitions.js +829 -496
  99. package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
  100. package/dist/tools/consolidated-tool-handlers.js +198 -1027
  101. package/dist/tools/debug.d.ts +143 -85
  102. package/dist/tools/debug.js +234 -180
  103. package/dist/tools/dynamic-handler-registry.d.ts +13 -0
  104. package/dist/tools/dynamic-handler-registry.js +23 -0
  105. package/dist/tools/editor.d.ts +30 -83
  106. package/dist/tools/editor.js +247 -244
  107. package/dist/tools/engine.d.ts +10 -4
  108. package/dist/tools/engine.js +13 -5
  109. package/dist/tools/environment.d.ts +30 -0
  110. package/dist/tools/environment.js +267 -0
  111. package/dist/tools/foliage.d.ts +65 -99
  112. package/dist/tools/foliage.js +221 -331
  113. package/dist/tools/handlers/actor-handlers.d.ts +3 -0
  114. package/dist/tools/handlers/actor-handlers.js +227 -0
  115. package/dist/tools/handlers/animation-handlers.d.ts +3 -0
  116. package/dist/tools/handlers/animation-handlers.js +185 -0
  117. package/dist/tools/handlers/argument-helper.d.ts +16 -0
  118. package/dist/tools/handlers/argument-helper.js +80 -0
  119. package/dist/tools/handlers/asset-handlers.d.ts +3 -0
  120. package/dist/tools/handlers/asset-handlers.js +496 -0
  121. package/dist/tools/handlers/audio-handlers.d.ts +3 -0
  122. package/dist/tools/handlers/audio-handlers.js +166 -0
  123. package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
  124. package/dist/tools/handlers/blueprint-handlers.js +358 -0
  125. package/dist/tools/handlers/common-handlers.d.ts +14 -0
  126. package/dist/tools/handlers/common-handlers.js +56 -0
  127. package/dist/tools/handlers/editor-handlers.d.ts +3 -0
  128. package/dist/tools/handlers/editor-handlers.js +119 -0
  129. package/dist/tools/handlers/effect-handlers.d.ts +3 -0
  130. package/dist/tools/handlers/effect-handlers.js +171 -0
  131. package/dist/tools/handlers/environment-handlers.d.ts +3 -0
  132. package/dist/tools/handlers/environment-handlers.js +170 -0
  133. package/dist/tools/handlers/graph-handlers.d.ts +3 -0
  134. package/dist/tools/handlers/graph-handlers.js +90 -0
  135. package/dist/tools/handlers/input-handlers.d.ts +3 -0
  136. package/dist/tools/handlers/input-handlers.js +21 -0
  137. package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
  138. package/dist/tools/handlers/inspect-handlers.js +383 -0
  139. package/dist/tools/handlers/level-handlers.d.ts +3 -0
  140. package/dist/tools/handlers/level-handlers.js +237 -0
  141. package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
  142. package/dist/tools/handlers/lighting-handlers.js +144 -0
  143. package/dist/tools/handlers/performance-handlers.d.ts +3 -0
  144. package/dist/tools/handlers/performance-handlers.js +130 -0
  145. package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
  146. package/dist/tools/handlers/pipeline-handlers.js +110 -0
  147. package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
  148. package/dist/tools/handlers/sequence-handlers.js +376 -0
  149. package/dist/tools/handlers/system-handlers.d.ts +4 -0
  150. package/dist/tools/handlers/system-handlers.js +506 -0
  151. package/dist/tools/input.d.ts +19 -0
  152. package/dist/tools/input.js +89 -0
  153. package/dist/tools/introspection.d.ts +103 -40
  154. package/dist/tools/introspection.js +425 -568
  155. package/dist/tools/landscape.d.ts +54 -93
  156. package/dist/tools/landscape.js +284 -409
  157. package/dist/tools/level.d.ts +66 -27
  158. package/dist/tools/level.js +647 -675
  159. package/dist/tools/lighting.d.ts +77 -38
  160. package/dist/tools/lighting.js +445 -943
  161. package/dist/tools/logs.d.ts +3 -3
  162. package/dist/tools/logs.js +5 -57
  163. package/dist/tools/materials.d.ts +91 -24
  164. package/dist/tools/materials.js +194 -118
  165. package/dist/tools/niagara.d.ts +149 -39
  166. package/dist/tools/niagara.js +267 -182
  167. package/dist/tools/performance.d.ts +27 -13
  168. package/dist/tools/performance.js +203 -122
  169. package/dist/tools/physics.d.ts +32 -77
  170. package/dist/tools/physics.js +175 -582
  171. package/dist/tools/property-dictionary.d.ts +13 -0
  172. package/dist/tools/property-dictionary.js +82 -0
  173. package/dist/tools/sequence.d.ts +85 -60
  174. package/dist/tools/sequence.js +208 -747
  175. package/dist/tools/tool-definition-utils.d.ts +59 -0
  176. package/dist/tools/tool-definition-utils.js +35 -0
  177. package/dist/tools/ui.d.ts +64 -34
  178. package/dist/tools/ui.js +134 -214
  179. package/dist/types/automation-responses.d.ts +115 -0
  180. package/dist/types/automation-responses.js +2 -0
  181. package/dist/types/env.d.ts +0 -3
  182. package/dist/types/env.js +0 -7
  183. package/dist/types/responses.d.ts +249 -0
  184. package/dist/types/responses.js +2 -0
  185. package/dist/types/tool-interfaces.d.ts +898 -0
  186. package/dist/types/tool-interfaces.js +2 -0
  187. package/dist/types/tool-types.d.ts +183 -19
  188. package/dist/types/tool-types.js +0 -4
  189. package/dist/unreal-bridge.d.ts +24 -131
  190. package/dist/unreal-bridge.js +364 -1506
  191. package/dist/utils/command-validator.d.ts +9 -0
  192. package/dist/utils/command-validator.js +68 -0
  193. package/dist/utils/elicitation.d.ts +1 -1
  194. package/dist/utils/elicitation.js +12 -15
  195. package/dist/utils/error-handler.d.ts +2 -51
  196. package/dist/utils/error-handler.js +11 -87
  197. package/dist/utils/ini-reader.d.ts +3 -0
  198. package/dist/utils/ini-reader.js +69 -0
  199. package/dist/utils/logger.js +9 -6
  200. package/dist/utils/normalize.d.ts +3 -0
  201. package/dist/utils/normalize.js +56 -0
  202. package/dist/utils/path-security.d.ts +2 -0
  203. package/dist/utils/path-security.js +24 -0
  204. package/dist/utils/response-factory.d.ts +7 -0
  205. package/dist/utils/response-factory.js +27 -0
  206. package/dist/utils/response-validator.d.ts +3 -24
  207. package/dist/utils/response-validator.js +130 -81
  208. package/dist/utils/result-helpers.d.ts +4 -5
  209. package/dist/utils/result-helpers.js +15 -16
  210. package/dist/utils/safe-json.js +5 -11
  211. package/dist/utils/unreal-command-queue.d.ts +24 -0
  212. package/dist/utils/unreal-command-queue.js +120 -0
  213. package/dist/utils/validation.d.ts +0 -40
  214. package/dist/utils/validation.js +1 -78
  215. package/dist/wasm/index.d.ts +70 -0
  216. package/dist/wasm/index.js +535 -0
  217. package/docs/GraphQL-API.md +888 -0
  218. package/docs/Migration-Guide-v0.5.0.md +684 -0
  219. package/docs/Roadmap.md +53 -0
  220. package/docs/WebAssembly-Integration.md +628 -0
  221. package/docs/editor-plugin-extension.md +370 -0
  222. package/docs/handler-mapping.md +242 -0
  223. package/docs/native-automation-progress.md +128 -0
  224. package/docs/testing-guide.md +423 -0
  225. package/mcp-config-example.json +6 -6
  226. package/package.json +67 -28
  227. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
  228. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
  229. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
  230. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
  231. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
  232. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
  233. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
  234. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
  235. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
  236. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
  237. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
  238. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
  239. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
  240. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
  241. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
  242. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
  243. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
  244. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
  245. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
  246. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
  247. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
  248. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
  249. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
  250. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
  251. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
  252. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
  253. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
  254. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
  255. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
  256. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
  257. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
  258. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
  259. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
  260. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
  261. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
  262. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
  263. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
  264. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
  265. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
  266. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
  267. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
  268. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
  269. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
  270. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
  271. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
  272. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
  273. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
  274. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
  275. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
  276. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
  277. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
  278. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
  279. package/scripts/check-unreal-connection.mjs +19 -0
  280. package/scripts/clean-tmp.js +23 -0
  281. package/scripts/patch-wasm.js +26 -0
  282. package/scripts/run-all-tests.mjs +136 -0
  283. package/scripts/smoke-test.ts +94 -0
  284. package/scripts/sync-mcp-plugin.js +143 -0
  285. package/scripts/test-no-plugin-alternates.mjs +113 -0
  286. package/scripts/validate-server.js +46 -0
  287. package/scripts/verify-automation-bridge.js +200 -0
  288. package/server.json +58 -21
  289. package/src/automation/bridge.ts +558 -0
  290. package/src/automation/connection-manager.ts +130 -0
  291. package/src/automation/handshake.ts +99 -0
  292. package/src/automation/index.ts +2 -0
  293. package/src/automation/message-handler.ts +167 -0
  294. package/src/automation/request-tracker.ts +123 -0
  295. package/src/automation/types.ts +107 -0
  296. package/src/cli.ts +33 -6
  297. package/src/config.ts +73 -0
  298. package/src/constants.ts +19 -0
  299. package/src/graphql/loaders.ts +244 -0
  300. package/src/graphql/resolvers.ts +1008 -0
  301. package/src/graphql/schema.ts +452 -0
  302. package/src/graphql/server.ts +156 -0
  303. package/src/graphql/types.ts +10 -0
  304. package/src/handlers/resource-handlers.ts +186 -0
  305. package/src/index.ts +166 -664
  306. package/src/resources/actors.ts +58 -76
  307. package/src/resources/assets.ts +148 -134
  308. package/src/resources/levels.ts +28 -33
  309. package/src/server/resource-registry.ts +47 -0
  310. package/src/server/tool-registry.ts +354 -0
  311. package/src/server-setup.ts +114 -0
  312. package/src/services/health-monitor.ts +132 -0
  313. package/src/services/metrics-server.ts +142 -0
  314. package/src/tools/actors.ts +426 -323
  315. package/src/tools/animation.ts +672 -461
  316. package/src/tools/assets.ts +364 -289
  317. package/src/tools/audio.ts +323 -766
  318. package/src/tools/base-tool.ts +52 -0
  319. package/src/tools/behavior-tree.ts +45 -0
  320. package/src/tools/blueprint.ts +792 -970
  321. package/src/tools/consolidated-tool-definitions.ts +993 -515
  322. package/src/tools/consolidated-tool-handlers.ts +258 -1146
  323. package/src/tools/debug.ts +292 -187
  324. package/src/tools/dynamic-handler-registry.ts +33 -0
  325. package/src/tools/editor.ts +329 -253
  326. package/src/tools/engine.ts +14 -3
  327. package/src/tools/environment.ts +281 -0
  328. package/src/tools/foliage.ts +330 -392
  329. package/src/tools/handlers/actor-handlers.ts +265 -0
  330. package/src/tools/handlers/animation-handlers.ts +237 -0
  331. package/src/tools/handlers/argument-helper.ts +142 -0
  332. package/src/tools/handlers/asset-handlers.ts +532 -0
  333. package/src/tools/handlers/audio-handlers.ts +194 -0
  334. package/src/tools/handlers/blueprint-handlers.ts +380 -0
  335. package/src/tools/handlers/common-handlers.ts +87 -0
  336. package/src/tools/handlers/editor-handlers.ts +123 -0
  337. package/src/tools/handlers/effect-handlers.ts +220 -0
  338. package/src/tools/handlers/environment-handlers.ts +183 -0
  339. package/src/tools/handlers/graph-handlers.ts +116 -0
  340. package/src/tools/handlers/input-handlers.ts +28 -0
  341. package/src/tools/handlers/inspect-handlers.ts +450 -0
  342. package/src/tools/handlers/level-handlers.ts +252 -0
  343. package/src/tools/handlers/lighting-handlers.ts +147 -0
  344. package/src/tools/handlers/performance-handlers.ts +132 -0
  345. package/src/tools/handlers/pipeline-handlers.ts +127 -0
  346. package/src/tools/handlers/sequence-handlers.ts +415 -0
  347. package/src/tools/handlers/system-handlers.ts +564 -0
  348. package/src/tools/input.ts +101 -0
  349. package/src/tools/introspection.ts +493 -584
  350. package/src/tools/landscape.ts +418 -507
  351. package/src/tools/level.ts +786 -708
  352. package/src/tools/lighting.ts +588 -984
  353. package/src/tools/logs.ts +9 -57
  354. package/src/tools/materials.ts +237 -121
  355. package/src/tools/niagara.ts +335 -168
  356. package/src/tools/performance.ts +320 -169
  357. package/src/tools/physics.ts +274 -613
  358. package/src/tools/property-dictionary.ts +98 -0
  359. package/src/tools/sequence.ts +276 -820
  360. package/src/tools/tool-definition-utils.ts +35 -0
  361. package/src/tools/ui.ts +205 -283
  362. package/src/types/automation-responses.ts +119 -0
  363. package/src/types/env.ts +0 -10
  364. package/src/types/responses.ts +355 -0
  365. package/src/types/tool-interfaces.ts +250 -0
  366. package/src/types/tool-types.ts +243 -21
  367. package/src/unreal-bridge.ts +460 -1550
  368. package/src/utils/command-validator.ts +76 -0
  369. package/src/utils/elicitation.ts +10 -7
  370. package/src/utils/error-handler.ts +14 -90
  371. package/src/utils/ini-reader.ts +86 -0
  372. package/src/utils/logger.ts +8 -3
  373. package/src/utils/normalize.test.ts +162 -0
  374. package/src/utils/normalize.ts +60 -0
  375. package/src/utils/path-security.ts +43 -0
  376. package/src/utils/response-factory.ts +44 -0
  377. package/src/utils/response-validator.ts +176 -56
  378. package/src/utils/result-helpers.ts +21 -19
  379. package/src/utils/safe-json.test.ts +90 -0
  380. package/src/utils/safe-json.ts +14 -11
  381. package/src/utils/unreal-command-queue.ts +152 -0
  382. package/src/utils/validation.test.ts +184 -0
  383. package/src/utils/validation.ts +4 -1
  384. package/src/wasm/index.ts +838 -0
  385. package/test-server.mjs +100 -0
  386. package/tests/run-unreal-tool-tests.mjs +242 -14
  387. package/tests/test-animation.mjs +369 -0
  388. package/tests/test-asset-advanced.mjs +82 -0
  389. package/tests/test-asset-errors.mjs +35 -0
  390. package/tests/test-asset-graph.mjs +311 -0
  391. package/tests/test-audio.mjs +417 -0
  392. package/tests/test-automation-timeouts.mjs +98 -0
  393. package/tests/test-behavior-tree.mjs +444 -0
  394. package/tests/test-blueprint-graph.mjs +410 -0
  395. package/tests/test-blueprint.mjs +577 -0
  396. package/tests/test-client-mode.mjs +86 -0
  397. package/tests/test-console-command.mjs +56 -0
  398. package/tests/test-control-actor.mjs +425 -0
  399. package/tests/test-control-editor.mjs +112 -0
  400. package/tests/test-graphql.mjs +372 -0
  401. package/tests/test-input.mjs +349 -0
  402. package/tests/test-inspect.mjs +302 -0
  403. package/tests/test-landscape.mjs +316 -0
  404. package/tests/test-lighting.mjs +428 -0
  405. package/tests/test-manage-asset.mjs +438 -0
  406. package/tests/test-manage-level.mjs +89 -0
  407. package/tests/test-materials.mjs +356 -0
  408. package/tests/test-niagara.mjs +185 -0
  409. package/tests/test-no-inline-python.mjs +122 -0
  410. package/tests/test-performance.mjs +539 -0
  411. package/tests/test-plugin-handshake.mjs +82 -0
  412. package/tests/test-runner.mjs +933 -0
  413. package/tests/test-sequence.mjs +104 -0
  414. package/tests/test-system.mjs +96 -0
  415. package/tests/test-wasm.mjs +283 -0
  416. package/tests/test-world-partition.mjs +215 -0
  417. package/tsconfig.json +3 -3
  418. package/vitest.config.ts +35 -0
  419. package/wasm/Cargo.lock +363 -0
  420. package/wasm/Cargo.toml +42 -0
  421. package/wasm/LICENSE +21 -0
  422. package/wasm/README.md +253 -0
  423. package/wasm/src/dependency_resolver.rs +377 -0
  424. package/wasm/src/lib.rs +153 -0
  425. package/wasm/src/property_parser.rs +271 -0
  426. package/wasm/src/transform_math.rs +396 -0
  427. package/wasm/tests/integration.rs +109 -0
  428. package/.github/workflows/smithery-build.yml +0 -29
  429. package/dist/prompts/index.d.ts +0 -21
  430. package/dist/prompts/index.js +0 -217
  431. package/dist/tools/build_environment_advanced.d.ts +0 -65
  432. package/dist/tools/build_environment_advanced.js +0 -633
  433. package/dist/tools/rc.d.ts +0 -110
  434. package/dist/tools/rc.js +0 -437
  435. package/dist/tools/visual.d.ts +0 -40
  436. package/dist/tools/visual.js +0 -282
  437. package/dist/utils/http.d.ts +0 -6
  438. package/dist/utils/http.js +0 -151
  439. package/dist/utils/python-output.d.ts +0 -18
  440. package/dist/utils/python-output.js +0 -290
  441. package/dist/utils/python.d.ts +0 -2
  442. package/dist/utils/python.js +0 -4
  443. package/dist/utils/stdio-redirect.d.ts +0 -2
  444. package/dist/utils/stdio-redirect.js +0 -20
  445. package/docs/unreal-tool-test-cases.md +0 -574
  446. package/smithery.yaml +0 -29
  447. package/src/prompts/index.ts +0 -249
  448. package/src/tools/build_environment_advanced.ts +0 -732
  449. package/src/tools/rc.ts +0 -515
  450. package/src/tools/visual.ts +0 -281
  451. package/src/utils/http.ts +0 -187
  452. package/src/utils/python-output.ts +0 -351
  453. package/src/utils/python.ts +0 -3
  454. package/src/utils/stdio-redirect.ts +0 -18
package/wasm/README.md ADDED
@@ -0,0 +1,253 @@
1
+ # Unreal MCP WASM Module
2
+
3
+ WebAssembly module providing high-performance operations for the Unreal Engine MCP Server.
4
+
5
+ ## Features
6
+
7
+ - **Property Parser**: Efficient JSON property parsing and serialization
8
+ - **Transform Math**: Optimized 3D vector and matrix operations
9
+ - **Dependency Resolver**: Asset dependency graph traversal and analysis
10
+ - **Utils**: Common mathematical utilities
11
+
12
+ ## Prerequisites
13
+
14
+ - Rust (latest stable)
15
+ - wasm-pack
16
+ - Node.js (for integration testing)
17
+
18
+ ## Build Instructions
19
+
20
+ ### Install wasm-pack
21
+
22
+ ```bash
23
+ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
24
+ ```
25
+
26
+ ### Build for Release
27
+
28
+ ```bash
29
+ wasm-pack build --release --target web
30
+ ```
31
+
32
+ This creates a `pkg/` directory with:
33
+ - `unreal_mcp_wasm.js` - JavaScript bindings
34
+ - `unreal_mcp_wasm_bg.wasm` - Compiled WebAssembly binary
35
+ - `unreal_mcp_wasm.d.ts` - TypeScript definitions
36
+
37
+ ### Build for Development
38
+
39
+ ```bash
40
+ wasm-pack build --dev --target web --watch
41
+ ```
42
+
43
+ The `--watch` flag enables hot reloading during development.
44
+
45
+ ### Testing
46
+
47
+ ```bash
48
+ # Run Rust tests
49
+ cargo test
50
+
51
+ # Run integration tests
52
+ wasm-pack test --headless --firefox
53
+ ```
54
+
55
+ ## Usage
56
+
57
+ ### In TypeScript
58
+
59
+ ```typescript
60
+ import init, {
61
+ PropertyParser,
62
+ TransformCalculator,
63
+ Vector
64
+ } from './pkg/unreal_mcp_wasm.js';
65
+
66
+ async function main() {
67
+ await init();
68
+
69
+ // Property parsing
70
+ const parser = new PropertyParser();
71
+ const json = '{"name": "Test", "value": 42}';
72
+ const result = parser.parse_properties(json);
73
+ console.log(result);
74
+
75
+ // Vector math
76
+ const v1 = new Vector(1, 2, 3);
77
+ const v2 = new Vector(4, 5, 6);
78
+ const sum = v1.add(v2);
79
+ console.log(sum); // { x: 5, y: 7, z: 9 }
80
+
81
+ // Transform calculations
82
+ const calculator = new TransformCalculator();
83
+ const location = [100, 200, 300];
84
+ const rotation = [0, 90, 0];
85
+ const scale = [1, 1, 1];
86
+ const matrix = calculator.compose_transform(location, rotation, scale);
87
+ console.log(matrix);
88
+ }
89
+
90
+ main();
91
+ ```
92
+
93
+ ## API Reference
94
+
95
+ ### PropertyParser
96
+
97
+ ```typescript
98
+ new PropertyParser(maxDepth?: number)
99
+ parse_properties(jsonStr: string, maxDepth?: number): Promise<ParseResult>
100
+ serialize_properties(properties: JsValue): Promise<string>
101
+ extract_property_names(jsonStr: string): Promise<string[]>
102
+ get_property_type(jsonStr: string): string
103
+ ```
104
+
105
+ ### TransformCalculator
106
+
107
+ ```typescript
108
+ new TransformCalculator()
109
+ compose_transform(location: [number, number, number], rotation: [number, number, number], scale: [number, number, number]): number[]
110
+ decompose_matrix(matrix: number[]): number[]
111
+ apply_transform(point: number[], transform: number[]): number[]
112
+ ```
113
+
114
+ ### Vector
115
+
116
+ ```typescript
117
+ new Vector(x: number, y: number, z: number)
118
+ add(other: Vector): Vector
119
+ subtract(other: Vector): Vector
120
+ multiply(other: Vector): Vector
121
+ scale(scalar: number): Vector
122
+ dot(other: Vector): number
123
+ cross(other: Vector): Vector
124
+ length(): number
125
+ normalize(): Vector
126
+ distance_to(other: Vector): number
127
+ lerp(other: Vector, t: number): Vector
128
+ to_array(): number[]
129
+ ```
130
+
131
+ ### DependencyResolver
132
+
133
+ ```typescript
134
+ new DependencyResolver(maxDepth?: number)
135
+ analyze_dependencies(assetPath: string, dependenciesJson: string, maxDepth?: number): Promise<DependencyAnalysis>
136
+ find_dependents(assetPath: string, dependenciesJson: string): string[]
137
+ calculate_depth(assetPath: string, dependenciesJson: string, maxDepth?: number): number
138
+ find_circular_dependencies(dependenciesJson: string, maxDepth?: number): string[][]
139
+ topological_sort(dependenciesJson: string): string[]
140
+ ```
141
+
142
+ ### Utils
143
+
144
+ ```typescript
145
+ now(): number
146
+ random(): number
147
+ clamp(value: number, min: number, max: number): number
148
+ lerp(a: number, b: number, t: number): number
149
+ deg_to_rad(degrees: number): number
150
+ rad_to_deg(radians: number): number
151
+ ```
152
+
153
+ ### Metrics
154
+
155
+ ```typescript
156
+ new Metrics()
157
+ record(name: string, durationMs: number): void
158
+ average_for(name: string): number
159
+ count(): number
160
+ clear(): void
161
+ ```
162
+
163
+ ## Performance
164
+
165
+ ### Benchmarks (Approximate)
166
+
167
+ | Operation | WASM | TypeScript | Speedup |
168
+ |-----------|------|------------|---------|
169
+ | Parse 1000 properties | 20-40ms | 150-300ms | **5-8x** |
170
+ | Vector operations (1000) | 1-2ms | 5-10ms | **5x** |
171
+ | Transform composition | 0.5ms | 5ms | **10x** |
172
+ | Dependency analysis | 10-20ms | 50-100ms | **5x** |
173
+
174
+ ## Limitations
175
+
176
+ 1. Requires WebAssembly support (all modern browsers)
177
+ 2. Limited to f32 for floating-point operations (performance optimization)
178
+ 3. Maximum recursion depth defaults to 100 (configurable)
179
+
180
+ ## Troubleshooting
181
+
182
+ ### Build Errors
183
+
184
+ **Error: `wasm-pack` not found**
185
+ ```bash
186
+ curl https://rustwasm.github.io/wasm-pack/installer/init.sh -sSf | sh
187
+ ```
188
+
189
+ **Error: `cargo` not found**
190
+ Install Rust from https://rustup.rs/
191
+
192
+ ### Runtime Errors
193
+
194
+ **Error: "WebAssembly module not initialized"**
195
+ ```typescript
196
+ await init(); // Must be called before using WASM functions
197
+ ```
198
+
199
+ **Error: "Maximum nesting depth exceeded"**
200
+ ```typescript
201
+ const parser = new PropertyParser(200); // Increase max depth
202
+ ```
203
+
204
+ ## Development
205
+
206
+ ### Project Structure
207
+
208
+ ```
209
+ wasm/
210
+ ├── src/
211
+ │ ├── lib.rs # Entry point
212
+ │ ├── property_parser.rs # Property parsing
213
+ │ ├── transform_math.rs # Vector/matrix math
214
+ │ └── dependency_resolver.rs # Dependency graphs
215
+ ├── tests/
216
+ │ └── integration.rs # Integration tests
217
+ ├── Cargo.toml # Rust configuration
218
+ └── README.md # This file
219
+ ```
220
+
221
+ ### Adding New Functions
222
+
223
+ 1. Add function to appropriate module
224
+ 2. Mark with `#[wasm_bindgen]`
225
+ 3. Build with `wasm-pack build --dev`
226
+ 4. Run tests with `cargo test`
227
+
228
+ ### Code Style
229
+
230
+ - Use `f32` for floating-point numbers
231
+ - Prefer simple types over complex generics
232
+ - Add documentation comments
233
+ - Include tests for new functionality
234
+
235
+ ## License
236
+
237
+ MIT
238
+
239
+ ## Contributing
240
+
241
+ 1. Fork the repository
242
+ 2. Create a feature branch
243
+ 3. Make your changes
244
+ 4. Add tests
245
+ 5. Run `cargo test`
246
+ 6. Submit a pull request
247
+
248
+ ## See Also
249
+
250
+ - [WebAssembly.org](https://webassembly.org/)
251
+ - [wasm-bindgen](https://rustwasm.github.io/wasm-bindgen/)
252
+ - [wasm-pack](https://rustwasm.github.io/wasm-pack/)
253
+ - [serde](https://serde.rs/)
@@ -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
+ }