unreal-engine-mcp-server 0.5.4 → 0.5.6

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 (561) hide show
  1. package/CHANGELOG.md +350 -0
  2. package/dist/automation/bridge.d.ts.map +1 -0
  3. package/dist/automation/bridge.js +5 -4
  4. package/dist/automation/bridge.js.map +1 -0
  5. package/dist/automation/connection-manager.d.ts.map +1 -0
  6. package/dist/automation/connection-manager.js.map +1 -0
  7. package/dist/automation/handshake.d.ts.map +1 -0
  8. package/dist/automation/handshake.js.map +1 -0
  9. package/dist/automation/index.d.ts.map +1 -0
  10. package/dist/automation/index.js.map +1 -0
  11. package/dist/automation/message-handler.d.ts.map +1 -0
  12. package/dist/automation/message-handler.js.map +1 -0
  13. package/dist/automation/request-tracker.d.ts.map +1 -0
  14. package/dist/automation/request-tracker.js.map +1 -0
  15. package/dist/automation/types.d.ts +7 -0
  16. package/dist/automation/types.d.ts.map +1 -0
  17. package/dist/automation/types.js.map +1 -0
  18. package/dist/cli.d.ts.map +1 -0
  19. package/dist/cli.js +6 -4
  20. package/dist/cli.js.map +1 -0
  21. package/dist/config/class-aliases.d.ts.map +1 -0
  22. package/dist/config/class-aliases.js.map +1 -0
  23. package/dist/config.d.ts.map +1 -0
  24. package/dist/config.js.map +1 -0
  25. package/dist/constants.d.ts.map +1 -0
  26. package/dist/constants.js.map +1 -0
  27. package/dist/graphql/loaders.d.ts.map +1 -0
  28. package/dist/graphql/loaders.js.map +1 -0
  29. package/dist/graphql/resolvers.d.ts +174 -69
  30. package/dist/graphql/resolvers.d.ts.map +1 -0
  31. package/dist/graphql/resolvers.js +82 -67
  32. package/dist/graphql/resolvers.js.map +1 -0
  33. package/dist/graphql/schema.d.ts.map +1 -0
  34. package/dist/graphql/schema.js.map +1 -0
  35. package/dist/graphql/server.d.ts.map +1 -0
  36. package/dist/graphql/server.js.map +1 -0
  37. package/dist/graphql/types.d.ts.map +1 -0
  38. package/dist/graphql/types.js.map +1 -0
  39. package/dist/handlers/resource-handlers.d.ts.map +1 -0
  40. package/dist/handlers/resource-handlers.js.map +1 -0
  41. package/dist/index.d.ts +2 -1
  42. package/dist/index.d.ts.map +1 -0
  43. package/dist/index.js +70 -9
  44. package/dist/index.js.map +1 -0
  45. package/dist/resources/actors.d.ts +7 -4
  46. package/dist/resources/actors.d.ts.map +1 -0
  47. package/dist/resources/actors.js +15 -12
  48. package/dist/resources/actors.js.map +1 -0
  49. package/dist/resources/assets.d.ts +43 -2
  50. package/dist/resources/assets.d.ts.map +1 -0
  51. package/dist/resources/assets.js +21 -12
  52. package/dist/resources/assets.js.map +1 -0
  53. package/dist/resources/levels.d.ts.map +1 -0
  54. package/dist/resources/levels.js +7 -5
  55. package/dist/resources/levels.js.map +1 -0
  56. package/dist/schemas/index.d.ts +4 -0
  57. package/dist/schemas/index.d.ts.map +1 -0
  58. package/dist/schemas/index.js +4 -0
  59. package/dist/schemas/index.js.map +1 -0
  60. package/dist/schemas/parser.d.ts +20 -0
  61. package/dist/schemas/parser.d.ts.map +1 -0
  62. package/dist/schemas/parser.js +61 -0
  63. package/dist/schemas/parser.js.map +1 -0
  64. package/dist/schemas/primitives.d.ts +221 -0
  65. package/dist/schemas/primitives.d.ts.map +1 -0
  66. package/dist/schemas/primitives.js +115 -0
  67. package/dist/schemas/primitives.js.map +1 -0
  68. package/dist/schemas/responses.d.ts +362 -0
  69. package/dist/schemas/responses.d.ts.map +1 -0
  70. package/dist/schemas/responses.js +252 -0
  71. package/dist/schemas/responses.js.map +1 -0
  72. package/dist/server/resource-registry.d.ts.map +1 -0
  73. package/dist/server/resource-registry.js.map +1 -0
  74. package/dist/server/tool-registry.d.ts.map +1 -0
  75. package/dist/server/tool-registry.js +22 -17
  76. package/dist/server/tool-registry.js.map +1 -0
  77. package/dist/server-setup.d.ts.map +1 -0
  78. package/dist/server-setup.js.map +1 -0
  79. package/dist/services/health-monitor.d.ts +1 -1
  80. package/dist/services/health-monitor.d.ts.map +1 -0
  81. package/dist/services/health-monitor.js +4 -3
  82. package/dist/services/health-monitor.js.map +1 -0
  83. package/dist/services/metrics-server.d.ts.map +1 -0
  84. package/dist/services/metrics-server.js.map +1 -0
  85. package/dist/tools/actors.d.ts +27 -27
  86. package/dist/tools/actors.d.ts.map +1 -0
  87. package/dist/tools/actors.js +14 -10
  88. package/dist/tools/actors.js.map +1 -0
  89. package/dist/tools/animation.d.ts +15 -23
  90. package/dist/tools/animation.d.ts.map +1 -0
  91. package/dist/tools/animation.js +17 -13
  92. package/dist/tools/animation.js.map +1 -0
  93. package/dist/tools/assets.d.ts.map +1 -0
  94. package/dist/tools/assets.js +18 -12
  95. package/dist/tools/assets.js.map +1 -0
  96. package/dist/tools/audio.d.ts +10 -10
  97. package/dist/tools/audio.d.ts.map +1 -0
  98. package/dist/tools/audio.js.map +1 -0
  99. package/dist/tools/base-tool.d.ts.map +1 -0
  100. package/dist/tools/base-tool.js.map +1 -0
  101. package/dist/tools/behavior-tree.d.ts +24 -24
  102. package/dist/tools/behavior-tree.d.ts.map +1 -0
  103. package/dist/tools/behavior-tree.js.map +1 -0
  104. package/dist/tools/blueprint.d.ts +14 -3
  105. package/dist/tools/blueprint.d.ts.map +1 -0
  106. package/dist/tools/blueprint.js +5 -3
  107. package/dist/tools/blueprint.js.map +1 -0
  108. package/dist/tools/consolidated-tool-definitions.d.ts +32 -32
  109. package/dist/tools/consolidated-tool-definitions.d.ts.map +1 -0
  110. package/dist/tools/consolidated-tool-definitions.js.map +1 -0
  111. package/dist/tools/consolidated-tool-handlers.d.ts +1 -1
  112. package/dist/tools/consolidated-tool-handlers.d.ts.map +1 -0
  113. package/dist/tools/consolidated-tool-handlers.js +26 -21
  114. package/dist/tools/consolidated-tool-handlers.js.map +1 -0
  115. package/dist/tools/debug.d.ts +25 -7
  116. package/dist/tools/debug.d.ts.map +1 -0
  117. package/dist/tools/debug.js +3 -1
  118. package/dist/tools/debug.js.map +1 -0
  119. package/dist/tools/dynamic-handler-registry.d.ts +1 -1
  120. package/dist/tools/dynamic-handler-registry.d.ts.map +1 -0
  121. package/dist/tools/dynamic-handler-registry.js +3 -1
  122. package/dist/tools/dynamic-handler-registry.js.map +1 -0
  123. package/dist/tools/editor.d.ts.map +1 -0
  124. package/dist/tools/editor.js +8 -6
  125. package/dist/tools/editor.js.map +1 -0
  126. package/dist/tools/engine.d.ts +1 -1
  127. package/dist/tools/engine.d.ts.map +1 -0
  128. package/dist/tools/engine.js +4 -2
  129. package/dist/tools/engine.js.map +1 -0
  130. package/dist/tools/environment.d.ts.map +1 -0
  131. package/dist/tools/environment.js +4 -3
  132. package/dist/tools/environment.js.map +1 -0
  133. package/dist/tools/foliage.d.ts.map +1 -0
  134. package/dist/tools/foliage.js +8 -8
  135. package/dist/tools/foliage.js.map +1 -0
  136. package/dist/tools/handlers/actor-handlers.d.ts +2 -1
  137. package/dist/tools/handlers/actor-handlers.d.ts.map +1 -0
  138. package/dist/tools/handlers/actor-handlers.js +56 -33
  139. package/dist/tools/handlers/actor-handlers.js.map +1 -0
  140. package/dist/tools/handlers/animation-handlers.d.ts +2 -1
  141. package/dist/tools/handlers/animation-handlers.d.ts.map +1 -0
  142. package/dist/tools/handlers/animation-handlers.js +74 -67
  143. package/dist/tools/handlers/animation-handlers.js.map +1 -0
  144. package/dist/tools/handlers/argument-helper.d.ts +24 -4
  145. package/dist/tools/handlers/argument-helper.d.ts.map +1 -0
  146. package/dist/tools/handlers/argument-helper.js +139 -4
  147. package/dist/tools/handlers/argument-helper.js.map +1 -0
  148. package/dist/tools/handlers/asset-handlers.d.ts +2 -1
  149. package/dist/tools/handlers/asset-handlers.d.ts.map +1 -0
  150. package/dist/tools/handlers/asset-handlers.js +155 -94
  151. package/dist/tools/handlers/asset-handlers.js.map +1 -0
  152. package/dist/tools/handlers/audio-handlers.d.ts +2 -1
  153. package/dist/tools/handlers/audio-handlers.d.ts.map +1 -0
  154. package/dist/tools/handlers/audio-handlers.js +82 -80
  155. package/dist/tools/handlers/audio-handlers.js.map +1 -0
  156. package/dist/tools/handlers/blueprint-handlers.d.ts +3 -5
  157. package/dist/tools/handlers/blueprint-handlers.d.ts.map +1 -0
  158. package/dist/tools/handlers/blueprint-handlers.js +150 -142
  159. package/dist/tools/handlers/blueprint-handlers.js.map +1 -0
  160. package/dist/tools/handlers/common-handlers.d.ts +2 -3
  161. package/dist/tools/handlers/common-handlers.d.ts.map +1 -0
  162. package/dist/tools/handlers/common-handlers.js.map +1 -0
  163. package/dist/tools/handlers/editor-handlers.d.ts.map +1 -0
  164. package/dist/tools/handlers/editor-handlers.js +12 -2
  165. package/dist/tools/handlers/editor-handlers.js.map +1 -0
  166. package/dist/tools/handlers/effect-handlers.d.ts +2 -1
  167. package/dist/tools/handlers/effect-handlers.d.ts.map +1 -0
  168. package/dist/tools/handlers/effect-handlers.js +70 -68
  169. package/dist/tools/handlers/effect-handlers.js.map +1 -0
  170. package/dist/tools/handlers/environment-handlers.d.ts +2 -1
  171. package/dist/tools/handlers/environment-handlers.d.ts.map +1 -0
  172. package/dist/tools/handlers/environment-handlers.js +86 -74
  173. package/dist/tools/handlers/environment-handlers.js.map +1 -0
  174. package/dist/tools/handlers/graph-handlers.d.ts +1 -1
  175. package/dist/tools/handlers/graph-handlers.d.ts.map +1 -0
  176. package/dist/tools/handlers/graph-handlers.js +63 -2
  177. package/dist/tools/handlers/graph-handlers.js.map +1 -0
  178. package/dist/tools/handlers/input-handlers.d.ts +2 -5
  179. package/dist/tools/handlers/input-handlers.d.ts.map +1 -0
  180. package/dist/tools/handlers/input-handlers.js +5 -4
  181. package/dist/tools/handlers/input-handlers.js.map +1 -0
  182. package/dist/tools/handlers/inspect-handlers.d.ts +2 -1
  183. package/dist/tools/handlers/inspect-handlers.d.ts.map +1 -0
  184. package/dist/tools/handlers/inspect-handlers.js +61 -37
  185. package/dist/tools/handlers/inspect-handlers.js.map +1 -0
  186. package/dist/tools/handlers/level-handlers.d.ts +2 -2
  187. package/dist/tools/handlers/level-handlers.d.ts.map +1 -0
  188. package/dist/tools/handlers/level-handlers.js +43 -39
  189. package/dist/tools/handlers/level-handlers.js.map +1 -0
  190. package/dist/tools/handlers/lighting-handlers.d.ts +12 -1
  191. package/dist/tools/handlers/lighting-handlers.d.ts.map +1 -0
  192. package/dist/tools/handlers/lighting-handlers.js +90 -47
  193. package/dist/tools/handlers/lighting-handlers.js.map +1 -0
  194. package/dist/tools/handlers/performance-handlers.d.ts +2 -1
  195. package/dist/tools/handlers/performance-handlers.d.ts.map +1 -0
  196. package/dist/tools/handlers/performance-handlers.js +55 -40
  197. package/dist/tools/handlers/performance-handlers.js.map +1 -0
  198. package/dist/tools/handlers/pipeline-handlers.d.ts.map +1 -0
  199. package/dist/tools/handlers/pipeline-handlers.js.map +1 -0
  200. package/dist/tools/handlers/sequence-handlers.d.ts.map +1 -0
  201. package/dist/tools/handlers/sequence-handlers.js.map +1 -0
  202. package/dist/tools/handlers/system-handlers.d.ts +3 -2
  203. package/dist/tools/handlers/system-handlers.d.ts.map +1 -0
  204. package/dist/tools/handlers/system-handlers.js +105 -52
  205. package/dist/tools/handlers/system-handlers.js.map +1 -0
  206. package/dist/tools/input.d.ts.map +1 -0
  207. package/dist/tools/input.js +3 -1
  208. package/dist/tools/input.js.map +1 -0
  209. package/dist/tools/introspection.d.ts +14 -14
  210. package/dist/tools/introspection.d.ts.map +1 -0
  211. package/dist/tools/introspection.js +54 -45
  212. package/dist/tools/introspection.js.map +1 -0
  213. package/dist/tools/landscape.d.ts.map +1 -0
  214. package/dist/tools/landscape.js +15 -13
  215. package/dist/tools/landscape.js.map +1 -0
  216. package/dist/tools/level.d.ts.map +1 -0
  217. package/dist/tools/level.js +3 -2
  218. package/dist/tools/level.js.map +1 -0
  219. package/dist/tools/lighting.d.ts +32 -59
  220. package/dist/tools/lighting.d.ts.map +1 -0
  221. package/dist/tools/lighting.js +56 -19
  222. package/dist/tools/lighting.js.map +1 -0
  223. package/dist/tools/logs.d.ts.map +1 -0
  224. package/dist/tools/logs.js +2 -1
  225. package/dist/tools/logs.js.map +1 -0
  226. package/dist/tools/materials.d.ts +42 -14
  227. package/dist/tools/materials.d.ts.map +1 -0
  228. package/dist/tools/materials.js +15 -9
  229. package/dist/tools/materials.js.map +1 -0
  230. package/dist/tools/niagara.d.ts +63 -39
  231. package/dist/tools/niagara.d.ts.map +1 -0
  232. package/dist/tools/niagara.js +43 -33
  233. package/dist/tools/niagara.js.map +1 -0
  234. package/dist/tools/performance.d.ts +12 -11
  235. package/dist/tools/performance.d.ts.map +1 -0
  236. package/dist/tools/performance.js +3 -2
  237. package/dist/tools/performance.js.map +1 -0
  238. package/dist/tools/physics.d.ts +37 -20
  239. package/dist/tools/physics.d.ts.map +1 -0
  240. package/dist/tools/physics.js +37 -30
  241. package/dist/tools/physics.js.map +1 -0
  242. package/dist/tools/property-dictionary.d.ts.map +1 -0
  243. package/dist/tools/property-dictionary.js.map +1 -0
  244. package/dist/tools/sequence.d.ts +1 -1
  245. package/dist/tools/sequence.d.ts.map +1 -0
  246. package/dist/tools/sequence.js +8 -4
  247. package/dist/tools/sequence.js.map +1 -0
  248. package/dist/tools/tool-definition-utils.d.ts.map +1 -0
  249. package/dist/tools/tool-definition-utils.js.map +1 -0
  250. package/dist/tools/ui.d.ts +11 -11
  251. package/dist/tools/ui.d.ts.map +1 -0
  252. package/dist/tools/ui.js +7 -3
  253. package/dist/tools/ui.js.map +1 -0
  254. package/dist/types/automation-responses.d.ts.map +1 -0
  255. package/dist/types/automation-responses.js.map +1 -0
  256. package/dist/types/env.d.ts.map +1 -0
  257. package/dist/types/env.js.map +1 -0
  258. package/dist/types/handler-types.d.ts +112 -3
  259. package/dist/types/handler-types.d.ts.map +1 -0
  260. package/dist/types/handler-types.js.map +1 -0
  261. package/dist/types/tool-interfaces.d.ts +39 -21
  262. package/dist/types/tool-interfaces.d.ts.map +1 -0
  263. package/dist/types/tool-interfaces.js.map +1 -0
  264. package/dist/types/tool-types.d.ts +8 -8
  265. package/dist/types/tool-types.d.ts.map +1 -0
  266. package/dist/types/tool-types.js.map +1 -0
  267. package/dist/unreal-bridge.d.ts +8 -6
  268. package/dist/unreal-bridge.d.ts.map +1 -0
  269. package/dist/unreal-bridge.js +16 -3
  270. package/dist/unreal-bridge.js.map +1 -0
  271. package/dist/utils/command-validator.d.ts.map +1 -0
  272. package/dist/utils/command-validator.js.map +1 -0
  273. package/dist/utils/elicitation.d.ts +2 -5
  274. package/dist/utils/elicitation.d.ts.map +1 -0
  275. package/dist/utils/elicitation.js +3 -2
  276. package/dist/utils/elicitation.js.map +1 -0
  277. package/dist/utils/error-handler.d.ts.map +1 -0
  278. package/dist/utils/error-handler.js.map +1 -0
  279. package/dist/utils/ini-reader.d.ts +1 -1
  280. package/dist/utils/ini-reader.d.ts.map +1 -0
  281. package/dist/utils/ini-reader.js.map +1 -0
  282. package/dist/utils/logger.d.ts +4 -4
  283. package/dist/utils/logger.d.ts.map +1 -0
  284. package/dist/utils/logger.js.map +1 -0
  285. package/dist/utils/normalize.d.ts +2 -2
  286. package/dist/utils/normalize.d.ts.map +1 -0
  287. package/dist/utils/normalize.js +4 -3
  288. package/dist/utils/normalize.js.map +1 -0
  289. package/dist/utils/path-security.d.ts.map +1 -0
  290. package/dist/utils/path-security.js.map +1 -0
  291. package/dist/utils/response-factory.d.ts +2 -2
  292. package/dist/utils/response-factory.d.ts.map +1 -0
  293. package/dist/utils/response-factory.js +3 -1
  294. package/dist/utils/response-factory.js.map +1 -0
  295. package/dist/utils/response-validator.d.ts +4 -4
  296. package/dist/utils/response-validator.d.ts.map +1 -0
  297. package/dist/utils/response-validator.js +31 -23
  298. package/dist/utils/response-validator.js.map +1 -0
  299. package/dist/utils/result-helpers.d.ts.map +1 -0
  300. package/dist/utils/result-helpers.js.map +1 -0
  301. package/dist/utils/safe-json.d.ts.map +1 -0
  302. package/dist/utils/safe-json.js.map +1 -0
  303. package/dist/utils/unreal-command-queue.d.ts +2 -2
  304. package/dist/utils/unreal-command-queue.d.ts.map +1 -0
  305. package/dist/utils/unreal-command-queue.js +4 -3
  306. package/dist/utils/unreal-command-queue.js.map +1 -0
  307. package/dist/utils/validation.d.ts +1 -1
  308. package/dist/utils/validation.d.ts.map +1 -0
  309. package/dist/utils/validation.js.map +1 -0
  310. package/dist/wasm/index.d.ts +2 -2
  311. package/dist/wasm/index.d.ts.map +1 -0
  312. package/dist/wasm/index.js +11 -7
  313. package/dist/wasm/index.js.map +1 -0
  314. package/package.json +12 -34
  315. package/server.json +2 -2
  316. package/.dockerignore +0 -57
  317. package/.env.example +0 -26
  318. package/.env.production +0 -61
  319. package/.eslintrc.json +0 -0
  320. package/.eslintrc.override.json +0 -8
  321. package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -94
  322. package/.github/ISSUE_TEMPLATE/config.yml +0 -8
  323. package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -56
  324. package/.github/copilot-instructions.md +0 -478
  325. package/.github/dependabot.yml +0 -19
  326. package/.github/labeler.yml +0 -24
  327. package/.github/labels.yml +0 -70
  328. package/.github/pull_request_template.md +0 -42
  329. package/.github/release-drafter-config.yml +0 -51
  330. package/.github/workflows/auto-merge.yml +0 -38
  331. package/.github/workflows/ci.yml +0 -38
  332. package/.github/workflows/dependency-review.yml +0 -17
  333. package/.github/workflows/gemini-issue-triage.yml +0 -172
  334. package/.github/workflows/greetings.yml +0 -27
  335. package/.github/workflows/labeler.yml +0 -17
  336. package/.github/workflows/links.yml +0 -80
  337. package/.github/workflows/pr-size-labeler.yml +0 -137
  338. package/.github/workflows/publish-mcp.yml +0 -79
  339. package/.github/workflows/release-drafter.yml +0 -24
  340. package/.github/workflows/release.yml +0 -112
  341. package/.github/workflows/semantic-pull-request.yml +0 -35
  342. package/.github/workflows/smoke-test.yml +0 -36
  343. package/.github/workflows/stale.yml +0 -28
  344. package/CONTRIBUTING.md +0 -140
  345. package/Dockerfile +0 -37
  346. package/GEMINI.md +0 -115
  347. package/Public/Plugin_setup_guide.mp4 +0 -0
  348. package/Public/icon.png +0 -0
  349. package/claude_desktop_config_example.json +0 -15
  350. package/dist/types/responses.d.ts +0 -249
  351. package/dist/types/responses.js +0 -2
  352. package/docs/GraphQL-API.md +0 -888
  353. package/docs/Migration-Guide-v0.5.0.md +0 -684
  354. package/docs/Roadmap.md +0 -53
  355. package/docs/WebAssembly-Integration.md +0 -628
  356. package/docs/editor-plugin-extension.md +0 -370
  357. package/docs/handler-mapping.md +0 -249
  358. package/docs/native-automation-progress.md +0 -128
  359. package/docs/testing-guide.md +0 -423
  360. package/eslint.config.mjs +0 -68
  361. package/mcp-config-example.json +0 -14
  362. package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +0 -8
  363. package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +0 -64
  364. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +0 -189
  365. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +0 -22
  366. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +0 -30
  367. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +0 -1983
  368. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +0 -72
  369. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +0 -46
  370. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +0 -846
  371. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +0 -2393
  372. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +0 -300
  373. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +0 -2807
  374. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +0 -1087
  375. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +0 -488
  376. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +0 -643
  377. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +0 -31
  378. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +0 -1094
  379. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +0 -5750
  380. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +0 -152
  381. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +0 -2614
  382. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +0 -42
  383. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +0 -1237
  384. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +0 -1725
  385. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +0 -2265
  386. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +0 -954
  387. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +0 -209
  388. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +0 -41
  389. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +0 -1164
  390. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +0 -762
  391. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +0 -663
  392. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +0 -136
  393. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +0 -494
  394. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +0 -278
  395. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +0 -625
  396. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +0 -401
  397. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +0 -67
  398. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +0 -472
  399. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +0 -2634
  400. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +0 -189
  401. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +0 -917
  402. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +0 -39
  403. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +0 -2706
  404. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +0 -519
  405. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +0 -38
  406. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +0 -668
  407. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +0 -346
  408. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +0 -1345
  409. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +0 -149
  410. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -782
  411. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +0 -115
  412. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +0 -796
  413. package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +0 -117
  414. package/scripts/check-unreal-connection.mjs +0 -19
  415. package/scripts/clean-tmp.js +0 -23
  416. package/scripts/patch-wasm.js +0 -26
  417. package/scripts/run-all-tests.mjs +0 -136
  418. package/scripts/smoke-test.ts +0 -94
  419. package/scripts/sync-mcp-plugin.js +0 -143
  420. package/scripts/test-no-plugin-alternates.mjs +0 -113
  421. package/scripts/validate-server.js +0 -46
  422. package/scripts/verify-automation-bridge.js +0 -200
  423. package/src/automation/bridge.ts +0 -630
  424. package/src/automation/connection-manager.ts +0 -148
  425. package/src/automation/handshake.ts +0 -99
  426. package/src/automation/index.ts +0 -2
  427. package/src/automation/message-handler.ts +0 -192
  428. package/src/automation/request-tracker.ts +0 -155
  429. package/src/automation/types.ts +0 -108
  430. package/src/cli.ts +0 -34
  431. package/src/config/class-aliases.ts +0 -65
  432. package/src/config.ts +0 -73
  433. package/src/constants.ts +0 -29
  434. package/src/graphql/loaders.ts +0 -244
  435. package/src/graphql/resolvers.ts +0 -1008
  436. package/src/graphql/schema.ts +0 -452
  437. package/src/graphql/server.ts +0 -156
  438. package/src/graphql/types.ts +0 -10
  439. package/src/handlers/resource-handlers.ts +0 -186
  440. package/src/index.ts +0 -243
  441. package/src/resources/actors.ts +0 -127
  442. package/src/resources/assets.ts +0 -286
  443. package/src/resources/levels.ts +0 -68
  444. package/src/server/resource-registry.ts +0 -47
  445. package/src/server/tool-registry.ts +0 -354
  446. package/src/server-setup.ts +0 -114
  447. package/src/services/health-monitor.ts +0 -132
  448. package/src/services/metrics-server.ts +0 -176
  449. package/src/tools/actors.ts +0 -564
  450. package/src/tools/animation.ts +0 -941
  451. package/src/tools/assets.ts +0 -394
  452. package/src/tools/audio.ts +0 -499
  453. package/src/tools/base-tool.ts +0 -52
  454. package/src/tools/behavior-tree.ts +0 -45
  455. package/src/tools/blueprint.ts +0 -940
  456. package/src/tools/consolidated-tool-definitions.ts +0 -1256
  457. package/src/tools/consolidated-tool-handlers.ts +0 -302
  458. package/src/tools/debug.ts +0 -622
  459. package/src/tools/dynamic-handler-registry.ts +0 -33
  460. package/src/tools/editor.ts +0 -435
  461. package/src/tools/engine.ts +0 -43
  462. package/src/tools/environment.ts +0 -281
  463. package/src/tools/foliage.ts +0 -596
  464. package/src/tools/handlers/actor-handlers.ts +0 -244
  465. package/src/tools/handlers/animation-handlers.ts +0 -237
  466. package/src/tools/handlers/argument-helper.ts +0 -142
  467. package/src/tools/handlers/asset-handlers.ts +0 -550
  468. package/src/tools/handlers/audio-handlers.ts +0 -194
  469. package/src/tools/handlers/blueprint-handlers.ts +0 -380
  470. package/src/tools/handlers/common-handlers.ts +0 -108
  471. package/src/tools/handlers/editor-handlers.ts +0 -124
  472. package/src/tools/handlers/effect-handlers.ts +0 -224
  473. package/src/tools/handlers/environment-handlers.ts +0 -183
  474. package/src/tools/handlers/graph-handlers.ts +0 -117
  475. package/src/tools/handlers/input-handlers.ts +0 -28
  476. package/src/tools/handlers/inspect-handlers.ts +0 -450
  477. package/src/tools/handlers/level-handlers.ts +0 -253
  478. package/src/tools/handlers/lighting-handlers.ts +0 -151
  479. package/src/tools/handlers/performance-handlers.ts +0 -132
  480. package/src/tools/handlers/pipeline-handlers.ts +0 -194
  481. package/src/tools/handlers/sequence-handlers.ts +0 -438
  482. package/src/tools/handlers/system-handlers.ts +0 -564
  483. package/src/tools/input.ts +0 -160
  484. package/src/tools/introspection.ts +0 -689
  485. package/src/tools/landscape.ts +0 -649
  486. package/src/tools/level.ts +0 -989
  487. package/src/tools/lighting.ts +0 -1052
  488. package/src/tools/logs.ts +0 -219
  489. package/src/tools/materials.ts +0 -295
  490. package/src/tools/niagara.ts +0 -485
  491. package/src/tools/performance.ts +0 -661
  492. package/src/tools/physics.ts +0 -679
  493. package/src/tools/property-dictionary.ts +0 -98
  494. package/src/tools/sequence.ts +0 -385
  495. package/src/tools/tool-definition-utils.ts +0 -35
  496. package/src/tools/ui.ts +0 -452
  497. package/src/types/automation-responses.ts +0 -119
  498. package/src/types/env.ts +0 -17
  499. package/src/types/handler-types.ts +0 -442
  500. package/src/types/responses.ts +0 -355
  501. package/src/types/tool-interfaces.ts +0 -250
  502. package/src/types/tool-types.ts +0 -575
  503. package/src/unreal-bridge.ts +0 -693
  504. package/src/utils/command-validator.ts +0 -139
  505. package/src/utils/elicitation.ts +0 -132
  506. package/src/utils/error-handler.ts +0 -287
  507. package/src/utils/ini-reader.ts +0 -86
  508. package/src/utils/logger.ts +0 -35
  509. package/src/utils/normalize.test.ts +0 -162
  510. package/src/utils/normalize.ts +0 -146
  511. package/src/utils/path-security.ts +0 -43
  512. package/src/utils/response-factory.ts +0 -44
  513. package/src/utils/response-validator.ts +0 -395
  514. package/src/utils/result-helpers.ts +0 -195
  515. package/src/utils/safe-json.test.ts +0 -90
  516. package/src/utils/safe-json.ts +0 -70
  517. package/src/utils/unreal-command-queue.ts +0 -166
  518. package/src/utils/validation.test.ts +0 -184
  519. package/src/utils/validation.ts +0 -312
  520. package/src/wasm/index.ts +0 -838
  521. package/test-server.mjs +0 -100
  522. package/tests/test-animation.mjs +0 -369
  523. package/tests/test-asset-advanced.mjs +0 -82
  524. package/tests/test-asset-graph.mjs +0 -311
  525. package/tests/test-audio.mjs +0 -417
  526. package/tests/test-automation-timeouts.mjs +0 -98
  527. package/tests/test-behavior-tree.mjs +0 -444
  528. package/tests/test-blueprint-graph.mjs +0 -410
  529. package/tests/test-blueprint.mjs +0 -577
  530. package/tests/test-client-mode.mjs +0 -86
  531. package/tests/test-console-command.mjs +0 -56
  532. package/tests/test-control-actor.mjs +0 -425
  533. package/tests/test-control-editor.mjs +0 -112
  534. package/tests/test-graphql.mjs +0 -372
  535. package/tests/test-input.mjs +0 -349
  536. package/tests/test-inspect.mjs +0 -302
  537. package/tests/test-landscape.mjs +0 -316
  538. package/tests/test-lighting.mjs +0 -428
  539. package/tests/test-manage-asset.mjs +0 -438
  540. package/tests/test-manage-level.mjs +0 -89
  541. package/tests/test-materials.mjs +0 -356
  542. package/tests/test-niagara.mjs +0 -185
  543. package/tests/test-no-inline-python.mjs +0 -122
  544. package/tests/test-performance.mjs +0 -539
  545. package/tests/test-plugin-handshake.mjs +0 -82
  546. package/tests/test-runner.mjs +0 -993
  547. package/tests/test-sequence.mjs +0 -104
  548. package/tests/test-system.mjs +0 -96
  549. package/tests/test-wasm.mjs +0 -283
  550. package/tests/test-world-partition.mjs +0 -215
  551. package/tsconfig.json +0 -56
  552. package/vitest.config.ts +0 -35
  553. package/wasm/Cargo.lock +0 -363
  554. package/wasm/Cargo.toml +0 -42
  555. package/wasm/LICENSE +0 -21
  556. package/wasm/README.md +0 -253
  557. package/wasm/src/dependency_resolver.rs +0 -377
  558. package/wasm/src/lib.rs +0 -153
  559. package/wasm/src/property_parser.rs +0 -271
  560. package/wasm/src/transform_math.rs +0 -396
  561. package/wasm/tests/integration.rs +0 -109
@@ -1,630 +0,0 @@
1
- import { EventEmitter } from 'node:events';
2
- import { WebSocket } from 'ws';
3
- import { Logger } from '../utils/logger.js';
4
- import {
5
- DEFAULT_AUTOMATION_HOST,
6
- DEFAULT_AUTOMATION_PORT,
7
- DEFAULT_NEGOTIATED_PROTOCOLS,
8
- DEFAULT_HEARTBEAT_INTERVAL_MS,
9
- DEFAULT_MAX_PENDING_REQUESTS,
10
- DEFAULT_MAX_QUEUED_REQUESTS,
11
- MAX_WS_MESSAGE_SIZE_BYTES
12
- } from '../constants.js';
13
- import { createRequire } from 'node:module';
14
- import {
15
- AutomationBridgeOptions,
16
- AutomationBridgeStatus,
17
- AutomationBridgeMessage,
18
- AutomationBridgeResponseMessage,
19
- AutomationBridgeEvents
20
- } from './types.js';
21
- import { ConnectionManager } from './connection-manager.js';
22
- import { RequestTracker } from './request-tracker.js';
23
- import { HandshakeHandler } from './handshake.js';
24
- import { MessageHandler } from './message-handler.js';
25
-
26
- const require = createRequire(import.meta.url);
27
- const packageInfo: { name?: string; version?: string } = (() => {
28
- try {
29
- return require('../../package.json');
30
- } catch (error) {
31
- const log = new Logger('AutomationBridge');
32
- log.debug('Unable to read package.json for version info', error);
33
- return {};
34
- }
35
- })();
36
-
37
- export class AutomationBridge extends EventEmitter {
38
- private readonly host: string;
39
- private readonly port: number;
40
- private readonly ports: number[];
41
- private readonly negotiatedProtocols: string[];
42
- private readonly capabilityToken?: string;
43
- private readonly enabled: boolean;
44
- private readonly serverName: string;
45
- private readonly serverVersion: string;
46
- private readonly clientHost: string;
47
- private readonly clientPort: number;
48
- private readonly serverLegacyEnabled: boolean;
49
- private readonly maxConcurrentConnections: number;
50
- private readonly maxQueuedRequests: number;
51
-
52
- private connectionManager: ConnectionManager;
53
- private requestTracker: RequestTracker;
54
- private handshakeHandler: HandshakeHandler;
55
- private messageHandler: MessageHandler;
56
- private log = new Logger('AutomationBridge');
57
-
58
- private lastHandshakeAt?: Date;
59
- private lastHandshakeMetadata?: Record<string, unknown>;
60
- private lastHandshakeAck?: AutomationBridgeMessage;
61
- private lastHandshakeFailure?: { reason: string; at: Date };
62
- private lastDisconnect?: { code: number; reason: string; at: Date };
63
- private lastError?: { message: string; at: Date };
64
- private queuedRequestItems: Array<{ resolve: (v: any) => void; reject: (e: any) => void; action: string; payload: any; options: any }> = [];
65
- private connectionPromise?: Promise<void>;
66
- private connectionLock = false;
67
-
68
- constructor(options: AutomationBridgeOptions = {}) {
69
- super();
70
- this.host = options.host ?? process.env.MCP_AUTOMATION_WS_HOST ?? DEFAULT_AUTOMATION_HOST;
71
-
72
- const sanitizePort = (value: unknown): number | null => {
73
- if (typeof value === 'number' && Number.isInteger(value)) {
74
- return value > 0 && value <= 65535 ? value : null;
75
- }
76
- if (typeof value === 'string' && value.trim().length > 0) {
77
- const parsed = Number.parseInt(value.trim(), 10);
78
- return Number.isInteger(parsed) && parsed > 0 && parsed <= 65535 ? parsed : null;
79
- }
80
- return null;
81
- };
82
-
83
- const defaultPort = sanitizePort(options.port ?? process.env.MCP_AUTOMATION_WS_PORT) ?? DEFAULT_AUTOMATION_PORT;
84
- const configuredPortValues: Array<number | string> | undefined = options.ports
85
- ? options.ports
86
- : process.env.MCP_AUTOMATION_WS_PORTS
87
- ?.split(',')
88
- .map((token) => token.trim())
89
- .filter((token) => token.length > 0);
90
-
91
- const sanitizedPorts = Array.isArray(configuredPortValues)
92
- ? configuredPortValues
93
- .map((value) => sanitizePort(value))
94
- .filter((port): port is number => port !== null)
95
- : [];
96
-
97
- if (!sanitizedPorts.includes(defaultPort)) {
98
- sanitizedPorts.unshift(defaultPort);
99
- }
100
- if (sanitizedPorts.length === 0) {
101
- sanitizedPorts.push(DEFAULT_AUTOMATION_PORT);
102
- }
103
-
104
- this.ports = Array.from(new Set(sanitizedPorts));
105
- const defaultProtocols = DEFAULT_NEGOTIATED_PROTOCOLS;
106
- const userProtocols = Array.isArray(options.protocols)
107
- ? options.protocols.filter((proto) => typeof proto === 'string' && proto.trim().length > 0)
108
- : [];
109
- const envProtocols = process.env.MCP_AUTOMATION_WS_PROTOCOLS
110
- ? process.env.MCP_AUTOMATION_WS_PROTOCOLS.split(',')
111
- .map((token) => token.trim())
112
- .filter((token) => token.length > 0)
113
- : [];
114
- this.negotiatedProtocols = Array.from(new Set([...userProtocols, ...envProtocols, ...defaultProtocols]));
115
- this.port = this.ports[0];
116
- this.serverLegacyEnabled =
117
- options.serverLegacyEnabled ?? process.env.MCP_AUTOMATION_SERVER_LEGACY !== 'false';
118
- this.capabilityToken =
119
- options.capabilityToken ?? process.env.MCP_AUTOMATION_CAPABILITY_TOKEN ?? undefined;
120
- this.enabled = options.enabled ?? process.env.MCP_AUTOMATION_BRIDGE_ENABLED !== 'false';
121
- this.serverName = options.serverName
122
- ?? process.env.MCP_SERVER_NAME
123
- ?? packageInfo.name
124
- ?? 'unreal-engine-mcp';
125
- this.serverVersion = options.serverVersion
126
- ?? process.env.MCP_SERVER_VERSION
127
- ?? packageInfo.version
128
- ?? process.env.npm_package_version
129
- ?? '0.0.0';
130
-
131
- const heartbeatIntervalMs = (options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS) > 0
132
- ? (options.heartbeatIntervalMs ?? DEFAULT_HEARTBEAT_INTERVAL_MS)
133
- : 0;
134
-
135
- const maxPendingRequests = Math.max(1, options.maxPendingRequests ?? DEFAULT_MAX_PENDING_REQUESTS);
136
- const maxConcurrentConnections = Math.max(1, options.maxConcurrentConnections ?? 10);
137
- this.maxQueuedRequests = Math.max(0, options.maxQueuedRequests ?? DEFAULT_MAX_QUEUED_REQUESTS);
138
-
139
- this.clientHost = options.clientHost ?? process.env.MCP_AUTOMATION_CLIENT_HOST ?? DEFAULT_AUTOMATION_HOST;
140
- this.clientPort = options.clientPort ?? sanitizePort(process.env.MCP_AUTOMATION_CLIENT_PORT) ?? DEFAULT_AUTOMATION_PORT;
141
- this.maxConcurrentConnections = maxConcurrentConnections;
142
-
143
- // Initialize components
144
- this.connectionManager = new ConnectionManager(heartbeatIntervalMs);
145
- this.requestTracker = new RequestTracker(maxPendingRequests);
146
- this.handshakeHandler = new HandshakeHandler(this.capabilityToken);
147
- this.messageHandler = new MessageHandler(this.requestTracker);
148
-
149
- // Forward events from connection manager
150
- // Note: ConnectionManager doesn't emit 'connected'/'disconnected' directly in the same way,
151
- // we handle socket events here and use ConnectionManager to track state.
152
- }
153
-
154
- override on<K extends keyof AutomationBridgeEvents>(
155
- event: K,
156
- listener: AutomationBridgeEvents[K]
157
- ): this {
158
- return super.on(event, listener as (...args: unknown[]) => void);
159
- }
160
-
161
- override once<K extends keyof AutomationBridgeEvents>(
162
- event: K,
163
- listener: AutomationBridgeEvents[K]
164
- ): this {
165
- return super.once(event, listener as (...args: unknown[]) => void);
166
- }
167
-
168
- override off<K extends keyof AutomationBridgeEvents>(
169
- event: K,
170
- listener: AutomationBridgeEvents[K]
171
- ): this {
172
- return super.off(event, listener as (...args: unknown[]) => void);
173
- }
174
-
175
- start(): void {
176
- if (!this.enabled) {
177
- this.log.info('Automation bridge disabled by configuration.');
178
- return;
179
- }
180
-
181
- this.log.info(`Automation bridge connecting to Unreal server at ws://${this.clientHost}:${this.clientPort}`);
182
- this.startClient();
183
- }
184
-
185
- private startClient(): void {
186
- try {
187
- const url = `ws://${this.clientHost}:${this.clientPort}`;
188
- this.log.info(`Connecting to Unreal Engine automation server at ${url}`);
189
-
190
- this.log.debug(`Negotiated protocols: ${JSON.stringify(this.negotiatedProtocols)}`);
191
-
192
- const protocols = this.negotiatedProtocols.length === 1
193
- ? this.negotiatedProtocols[0]
194
- : this.negotiatedProtocols;
195
-
196
- this.log.debug(`Using WebSocket protocols arg: ${JSON.stringify(protocols)}`);
197
-
198
- const headers: Record<string, string> | undefined = this.capabilityToken
199
- ? {
200
- 'X-MCP-Capability': this.capabilityToken,
201
- 'X-MCP-Capability-Token': this.capabilityToken
202
- }
203
- : undefined;
204
-
205
- const socket = new WebSocket(url, protocols, {
206
- headers,
207
- perMessageDeflate: false
208
- });
209
-
210
- this.handleClientConnection(socket);
211
- } catch (error) {
212
- const errorObj = error instanceof Error ? error : new Error(String(error));
213
- this.lastError = { message: errorObj.message, at: new Date() };
214
- this.log.error('Failed to create WebSocket client connection', errorObj);
215
- const errorWithPort = Object.assign(errorObj, { port: this.clientPort });
216
- this.emitAutomation('error', errorWithPort);
217
- }
218
- }
219
-
220
- private async handleClientConnection(socket: WebSocket): Promise<void> {
221
- socket.on('open', async () => {
222
- this.log.info('Automation bridge client connected, starting handshake');
223
- try {
224
- const metadata = await this.handshakeHandler.initiateHandshake(socket);
225
-
226
- this.lastHandshakeAt = new Date();
227
- this.lastHandshakeMetadata = metadata;
228
- this.lastHandshakeFailure = undefined;
229
- this.connectionManager.updateLastMessageTime();
230
-
231
- // Extract remote address/port from underlying TCP socket
232
- // Note: WebSocket types don't expose _socket, but it exists at runtime
233
- const socketWithInternal = socket as unknown as { _socket?: { remoteAddress?: string; remotePort?: number }; socket?: { remoteAddress?: string; remotePort?: number } };
234
- const underlying = socketWithInternal._socket || socketWithInternal.socket;
235
- const remoteAddr = underlying?.remoteAddress ?? undefined;
236
- const remotePort = underlying?.remotePort ?? undefined;
237
-
238
- this.connectionManager.registerSocket(socket, this.clientPort, metadata, remoteAddr, remotePort);
239
- this.connectionManager.startHeartbeat();
240
-
241
- this.emitAutomation('connected', {
242
- socket,
243
- metadata,
244
- port: this.clientPort,
245
- protocol: socket.protocol || null
246
- });
247
-
248
- const getRawDataByteLength = (data: unknown): number => {
249
- if (typeof data === 'string') {
250
- return Buffer.byteLength(data, 'utf8');
251
- }
252
-
253
- if (Buffer.isBuffer(data)) {
254
- return data.length;
255
- }
256
-
257
- if (Array.isArray(data)) {
258
- return data.reduce((total, item) => total + (Buffer.isBuffer(item) ? item.length : 0), 0);
259
- }
260
-
261
- if (data instanceof ArrayBuffer) {
262
- return data.byteLength;
263
- }
264
-
265
- if (ArrayBuffer.isView(data)) {
266
- return data.byteLength;
267
- }
268
-
269
- return 0;
270
- };
271
-
272
- const rawDataToUtf8String = (data: unknown, byteLengthHint?: number): string => {
273
- if (typeof data === 'string') {
274
- return data;
275
- }
276
-
277
- if (Buffer.isBuffer(data)) {
278
- return data.toString('utf8');
279
- }
280
-
281
- if (Array.isArray(data)) {
282
- const buffers = data.filter((item): item is Buffer => Buffer.isBuffer(item));
283
- const totalLength = typeof byteLengthHint === 'number'
284
- ? byteLengthHint
285
- : buffers.reduce((total, item) => total + item.length, 0);
286
- return Buffer.concat(buffers, totalLength).toString('utf8');
287
- }
288
-
289
- if (data instanceof ArrayBuffer) {
290
- return Buffer.from(data).toString('utf8');
291
- }
292
-
293
- if (ArrayBuffer.isView(data)) {
294
- return Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('utf8');
295
- }
296
-
297
- return '';
298
- };
299
-
300
- socket.on('message', (data) => {
301
- try {
302
- const byteLength = getRawDataByteLength(data);
303
- if (byteLength > MAX_WS_MESSAGE_SIZE_BYTES) {
304
- this.log.error(
305
- `Received oversized message (${byteLength} bytes, max: ${MAX_WS_MESSAGE_SIZE_BYTES}). Dropping.`
306
- );
307
- return;
308
- }
309
-
310
- const text = rawDataToUtf8String(data, byteLength);
311
- this.log.debug(`[AutomationBridge Client] Received message: ${text.substring(0, 1000)}`);
312
- const parsed = JSON.parse(text) as AutomationBridgeMessage;
313
- this.connectionManager.updateLastMessageTime();
314
- this.messageHandler.handleMessage(parsed);
315
- this.emitAutomation('message', parsed);
316
- } catch (error) {
317
- this.log.error('Error handling message', error);
318
- }
319
- });
320
-
321
- } catch (error) {
322
- const err = error instanceof Error ? error : new Error(String(error));
323
- this.lastHandshakeFailure = { reason: err.message, at: new Date() };
324
- this.emitAutomation('handshakeFailed', { reason: err.message, port: this.clientPort });
325
- }
326
- });
327
-
328
- socket.on('error', (error) => {
329
- this.log.error('Automation bridge client socket error', error);
330
- const errObj = error instanceof Error ? error : new Error(String(error));
331
- this.lastError = { message: errObj.message, at: new Date() };
332
- const errWithPort = Object.assign(errObj, { port: this.clientPort });
333
- this.emitAutomation('error', errWithPort);
334
- });
335
-
336
- socket.on('close', (code, reasonBuffer) => {
337
- const reason = reasonBuffer.toString('utf8');
338
- const socketInfo = this.connectionManager.removeSocket(socket);
339
-
340
- if (socketInfo) {
341
- this.lastDisconnect = { code, reason, at: new Date() };
342
- this.emitAutomation('disconnected', {
343
- code,
344
- reason,
345
- port: socketInfo.port,
346
- protocol: socketInfo.protocol || null
347
- });
348
- this.log.info(`Automation bridge client socket closed (code=${code}, reason=${reason})`);
349
-
350
- if (!this.connectionManager.isConnected()) {
351
- this.requestTracker.rejectAll(new Error(reason || 'Connection lost'));
352
- }
353
- }
354
- });
355
- }
356
-
357
- stop(): void {
358
- if (this.isConnected()) {
359
- this.broadcast({
360
- type: 'bridge_shutdown',
361
- timestamp: new Date().toISOString(),
362
- reason: 'Server shutting down'
363
- });
364
- }
365
- this.connectionManager.closeAll(1001, 'Server shutdown');
366
- this.lastHandshakeAck = undefined;
367
- this.requestTracker.rejectAll(new Error('Automation bridge server stopped'));
368
- }
369
-
370
- isConnected(): boolean {
371
- return this.connectionManager.isConnected();
372
- }
373
-
374
- getStatus(): AutomationBridgeStatus {
375
-
376
- const connectionInfos = Array.from(this.connectionManager.getActiveSockets().entries()).map(([socket, info]) => ({
377
- connectionId: info.connectionId,
378
- sessionId: info.sessionId ?? null,
379
- remoteAddress: info.remoteAddress ?? null,
380
- remotePort: info.remotePort ?? null,
381
- port: info.port,
382
- connectedAt: info.connectedAt.toISOString(),
383
- protocol: info.protocol || null,
384
- readyState: socket.readyState,
385
- isPrimary: socket === this.connectionManager.getPrimarySocket()
386
- }));
387
-
388
- return {
389
- enabled: this.enabled,
390
- host: this.host,
391
- port: this.port,
392
- configuredPorts: [...this.ports],
393
- listeningPorts: [], // We are client-only now
394
- connected: this.isConnected(),
395
- connectedAt: connectionInfos.length > 0 ? connectionInfos[0].connectedAt : null,
396
- activePort: connectionInfos.length > 0 ? connectionInfos[0].port : null,
397
- negotiatedProtocol: connectionInfos.length > 0 ? connectionInfos[0].protocol : null,
398
- supportedProtocols: [...this.negotiatedProtocols],
399
- supportedOpcodes: ['automation_request'],
400
- expectedResponseOpcodes: ['automation_response'],
401
- capabilityTokenRequired: Boolean(this.capabilityToken),
402
- lastHandshakeAt: this.lastHandshakeAt?.toISOString() ?? null,
403
- lastHandshakeMetadata: this.lastHandshakeMetadata ?? null,
404
- lastHandshakeAck: this.lastHandshakeAck ?? null,
405
- lastHandshakeFailure: this.lastHandshakeFailure
406
- ? { reason: this.lastHandshakeFailure.reason, at: this.lastHandshakeFailure.at.toISOString() }
407
- : null,
408
- lastDisconnect: this.lastDisconnect
409
- ? { code: this.lastDisconnect.code, reason: this.lastDisconnect.reason, at: this.lastDisconnect.at.toISOString() }
410
- : null,
411
- lastError: this.lastError
412
- ? { message: this.lastError.message, at: this.lastError.at.toISOString() }
413
- : null,
414
- lastMessageAt: this.connectionManager.getLastMessageTime()?.toISOString() ?? null,
415
- lastRequestSentAt: this.requestTracker.getLastRequestSentAt()?.toISOString() ?? null,
416
- pendingRequests: this.requestTracker.getPendingCount(),
417
- pendingRequestDetails: this.requestTracker.getPendingDetails(),
418
- connections: connectionInfos,
419
- webSocketListening: false,
420
- serverLegacyEnabled: this.serverLegacyEnabled,
421
- serverName: this.serverName,
422
- serverVersion: this.serverVersion,
423
- maxConcurrentConnections: this.maxConcurrentConnections,
424
- maxPendingRequests: this.requestTracker.getMaxPendingRequests(),
425
- heartbeatIntervalMs: this.connectionManager.getHeartbeatIntervalMs()
426
- };
427
- }
428
-
429
- async sendAutomationRequest<T = AutomationBridgeResponseMessage>(
430
- action: string,
431
- payload: Record<string, unknown> = {},
432
- options: { timeoutMs?: number } = {}
433
- ): Promise<T> {
434
- if (!this.isConnected()) {
435
- if (this.enabled) {
436
- this.log.info('Automation bridge not connected, attempting lazy connection...');
437
-
438
- // Avoid multiple simultaneous connection attempts using lock
439
- if (!this.connectionPromise && !this.connectionLock) {
440
- this.connectionLock = true;
441
- this.connectionPromise = new Promise<void>((resolve, reject) => {
442
- const onConnect = () => {
443
- cleanup(); resolve();
444
- };
445
- // We map errors to rejects, but we should be careful about which errors.
446
- // A socket error might happen during connection.
447
- const onError = (err: any) => {
448
- cleanup(); reject(err);
449
- };
450
- // Also listen for handshake failure
451
- const onHandshakeFail = (err: any) => {
452
- cleanup(); reject(new Error(`Handshake failed: ${err.reason}`));
453
- };
454
-
455
- const cleanup = () => {
456
- this.off('connected', onConnect);
457
- this.off('error', onError);
458
- this.off('handshakeFailed', onHandshakeFail);
459
- // Clear lock and promise so next attempt can try again
460
- this.connectionLock = false;
461
- this.connectionPromise = undefined;
462
- };
463
-
464
- this.once('connected', onConnect);
465
- this.once('error', onError);
466
- this.once('handshakeFailed', onHandshakeFail);
467
-
468
- try {
469
- this.startClient();
470
- } catch (e) {
471
- onError(e);
472
- }
473
- });
474
- }
475
-
476
- try {
477
- // Wait for connection with a short timeout for the connection itself
478
- const connectTimeout = 5000;
479
- let timeoutId: ReturnType<typeof setTimeout> | undefined;
480
- const timeoutPromise = new Promise<never>((_, reject) => {
481
- timeoutId = setTimeout(() => reject(new Error('Lazy connection timeout')), connectTimeout);
482
- });
483
-
484
- try {
485
- await Promise.race([this.connectionPromise, timeoutPromise]);
486
- } finally {
487
- if (timeoutId) clearTimeout(timeoutId);
488
- }
489
- } catch (err: any) {
490
- this.log.error('Lazy connection failed', err);
491
- // We don't throw here immediately, we let the isConnected check fail below
492
- // or throw a specific error.
493
- // Actually, if connection failed, we should probably fail the request.
494
- throw new Error(`Failed to establish connection to Unreal Engine: ${err.message}`);
495
- }
496
- } else {
497
- throw new Error('Automation bridge disabled');
498
- }
499
- }
500
-
501
- if (!this.isConnected()) {
502
- throw new Error('Automation bridge not connected');
503
- }
504
-
505
- if (this.requestTracker.getPendingCount() >= this.requestTracker.getMaxPendingRequests()) {
506
- if (this.queuedRequestItems.length >= this.maxQueuedRequests) {
507
- throw new Error(`Automation bridge request queue is full (max: ${this.maxQueuedRequests}). Please retry later.`);
508
- }
509
- return new Promise<T>((resolve, reject) => {
510
- this.queuedRequestItems.push({
511
- resolve,
512
- reject,
513
- action,
514
- payload,
515
- options
516
- });
517
- });
518
- }
519
-
520
- return this.sendRequestInternal<T>(action, payload, options);
521
- }
522
-
523
- private async sendRequestInternal<T>(
524
- action: string,
525
- payload: Record<string, unknown>,
526
- options: { timeoutMs?: number }
527
- ): Promise<T> {
528
- const timeoutMs = options.timeoutMs ?? 60000; // Increased default timeout to 60s
529
-
530
- // Check for coalescing
531
- const coalesceKey = this.requestTracker.createCoalesceKey(action, payload);
532
- if (coalesceKey) {
533
- const existing = this.requestTracker.getCoalescedRequest(coalesceKey);
534
- if (existing) {
535
- return existing as unknown as T;
536
- }
537
- }
538
-
539
- const { requestId, promise } = this.requestTracker.createRequest(action, payload, timeoutMs);
540
-
541
- if (coalesceKey) {
542
- this.requestTracker.setCoalescedRequest(coalesceKey, promise);
543
- }
544
-
545
- const message: AutomationBridgeMessage = {
546
- type: 'automation_request',
547
- requestId,
548
- action,
549
- payload
550
- };
551
-
552
- const resultPromise = promise as unknown as Promise<T>;
553
-
554
- // Ensure we process the queue when this request finishes
555
- resultPromise.finally(() => {
556
- this.processRequestQueue();
557
- }).catch(() => { }); // catch to prevent unhandled rejection during finally chain? no, finally returns new promise
558
-
559
- if (this.send(message)) {
560
- this.requestTracker.updateLastRequestSentAt();
561
- return resultPromise;
562
- } else {
563
- this.requestTracker.rejectRequest(requestId, new Error('Failed to send request'));
564
- throw new Error('Failed to send request');
565
- }
566
- }
567
-
568
- private processRequestQueue() {
569
- if (this.queuedRequestItems.length === 0) return;
570
-
571
- // while we have capacity and items
572
- while (
573
- this.queuedRequestItems.length > 0 &&
574
- this.requestTracker.getPendingCount() < this.requestTracker.getMaxPendingRequests()
575
- ) {
576
- const item = this.queuedRequestItems.shift();
577
- if (item) {
578
- this.sendRequestInternal(item.action, item.payload, item.options)
579
- .then(item.resolve)
580
- .catch(item.reject);
581
- }
582
- }
583
- }
584
-
585
- send(payload: AutomationBridgeMessage): boolean {
586
- const primarySocket = this.connectionManager.getPrimarySocket();
587
- if (!primarySocket || primarySocket.readyState !== WebSocket.OPEN) {
588
- this.log.warn('Attempted to send automation message without an active primary connection');
589
- return false;
590
- }
591
- try {
592
- primarySocket.send(JSON.stringify(payload));
593
- return true;
594
- } catch (error) {
595
- this.log.error('Failed to send automation message', error);
596
- const errObj = error instanceof Error ? error : new Error(String(error));
597
- const primaryInfo = this.connectionManager.getActiveSockets().get(primarySocket);
598
- const errorWithPort = Object.assign(errObj, { port: primaryInfo?.port });
599
- this.emitAutomation('error', errorWithPort);
600
- return false;
601
- }
602
- }
603
-
604
- private broadcast(payload: AutomationBridgeMessage): boolean {
605
- const sockets = this.connectionManager.getActiveSockets();
606
- if (sockets.size === 0) {
607
- this.log.warn('Attempted to broadcast automation message without any active connections');
608
- return false;
609
- }
610
- let sentCount = 0;
611
- for (const [socket] of sockets) {
612
- if (socket.readyState === WebSocket.OPEN) {
613
- try {
614
- socket.send(JSON.stringify(payload));
615
- sentCount++;
616
- } catch (error) {
617
- this.log.error('Failed to broadcast automation message to socket', error);
618
- }
619
- }
620
- }
621
- return sentCount > 0;
622
- }
623
-
624
- private emitAutomation<K extends keyof AutomationBridgeEvents>(
625
- event: K,
626
- ...args: Parameters<AutomationBridgeEvents[K]>
627
- ): void {
628
- this.emit(event, ...args);
629
- }
630
- }