unreal-engine-mcp-server 0.5.4 → 0.5.5
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.
- package/dist/automation/bridge.d.ts.map +1 -0
- package/dist/automation/bridge.js.map +1 -0
- package/dist/automation/connection-manager.d.ts.map +1 -0
- package/dist/automation/connection-manager.js.map +1 -0
- package/dist/automation/handshake.d.ts.map +1 -0
- package/dist/automation/handshake.js.map +1 -0
- package/dist/automation/index.d.ts.map +1 -0
- package/dist/automation/index.js.map +1 -0
- package/dist/automation/message-handler.d.ts.map +1 -0
- package/dist/automation/message-handler.js.map +1 -0
- package/dist/automation/request-tracker.d.ts.map +1 -0
- package/dist/automation/request-tracker.js.map +1 -0
- package/dist/automation/types.d.ts.map +1 -0
- package/dist/automation/types.js.map +1 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +4 -3
- package/dist/cli.js.map +1 -0
- package/dist/config/class-aliases.d.ts.map +1 -0
- package/dist/config/class-aliases.js.map +1 -0
- package/dist/config.d.ts.map +1 -0
- package/dist/config.js.map +1 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js.map +1 -0
- package/dist/graphql/loaders.d.ts.map +1 -0
- package/dist/graphql/loaders.js.map +1 -0
- package/dist/graphql/resolvers.d.ts.map +1 -0
- package/dist/graphql/resolvers.js +29 -29
- package/dist/graphql/resolvers.js.map +1 -0
- package/dist/graphql/schema.d.ts.map +1 -0
- package/dist/graphql/schema.js.map +1 -0
- package/dist/graphql/server.d.ts.map +1 -0
- package/dist/graphql/server.js.map +1 -0
- package/dist/graphql/types.d.ts.map +1 -0
- package/dist/graphql/types.js.map +1 -0
- package/dist/handlers/resource-handlers.d.ts.map +1 -0
- package/dist/handlers/resource-handlers.js.map +1 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +64 -7
- package/dist/index.js.map +1 -0
- package/dist/resources/actors.d.ts.map +1 -0
- package/dist/resources/actors.js.map +1 -0
- package/dist/resources/assets.d.ts.map +1 -0
- package/dist/resources/assets.js +6 -4
- package/dist/resources/assets.js.map +1 -0
- package/dist/resources/levels.d.ts.map +1 -0
- package/dist/resources/levels.js.map +1 -0
- package/dist/server/resource-registry.d.ts.map +1 -0
- package/dist/server/resource-registry.js.map +1 -0
- package/dist/server/tool-registry.d.ts.map +1 -0
- package/dist/server/tool-registry.js.map +1 -0
- package/dist/server-setup.d.ts.map +1 -0
- package/dist/server-setup.js.map +1 -0
- package/dist/services/health-monitor.d.ts.map +1 -0
- package/dist/services/health-monitor.js.map +1 -0
- package/dist/services/metrics-server.d.ts.map +1 -0
- package/dist/services/metrics-server.js.map +1 -0
- package/dist/tools/actors.d.ts.map +1 -0
- package/dist/tools/actors.js +3 -1
- package/dist/tools/actors.js.map +1 -0
- package/dist/tools/animation.d.ts.map +1 -0
- package/dist/tools/animation.js +2 -2
- package/dist/tools/animation.js.map +1 -0
- package/dist/tools/assets.d.ts.map +1 -0
- package/dist/tools/assets.js.map +1 -0
- package/dist/tools/audio.d.ts.map +1 -0
- package/dist/tools/audio.js.map +1 -0
- package/dist/tools/base-tool.d.ts.map +1 -0
- package/dist/tools/base-tool.js.map +1 -0
- package/dist/tools/behavior-tree.d.ts.map +1 -0
- package/dist/tools/behavior-tree.js.map +1 -0
- package/dist/tools/blueprint.d.ts.map +1 -0
- package/dist/tools/blueprint.js +4 -2
- package/dist/tools/blueprint.js.map +1 -0
- package/dist/tools/consolidated-tool-definitions.d.ts.map +1 -0
- package/dist/tools/consolidated-tool-definitions.js.map +1 -0
- package/dist/tools/consolidated-tool-handlers.d.ts.map +1 -0
- package/dist/tools/consolidated-tool-handlers.js.map +1 -0
- package/dist/tools/debug.d.ts.map +1 -0
- package/dist/tools/debug.js +3 -1
- package/dist/tools/debug.js.map +1 -0
- package/dist/tools/dynamic-handler-registry.d.ts.map +1 -0
- package/dist/tools/dynamic-handler-registry.js +3 -1
- package/dist/tools/dynamic-handler-registry.js.map +1 -0
- package/dist/tools/editor.d.ts.map +1 -0
- package/dist/tools/editor.js +1 -1
- package/dist/tools/editor.js.map +1 -0
- package/dist/tools/engine.d.ts.map +1 -0
- package/dist/tools/engine.js.map +1 -0
- package/dist/tools/environment.d.ts.map +1 -0
- package/dist/tools/environment.js +2 -2
- package/dist/tools/environment.js.map +1 -0
- package/dist/tools/foliage.d.ts.map +1 -0
- package/dist/tools/foliage.js.map +1 -0
- package/dist/tools/handlers/actor-handlers.d.ts +1 -1
- package/dist/tools/handlers/actor-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/actor-handlers.js +6 -5
- package/dist/tools/handlers/actor-handlers.js.map +1 -0
- package/dist/tools/handlers/animation-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/animation-handlers.js.map +1 -0
- package/dist/tools/handlers/argument-helper.d.ts.map +1 -0
- package/dist/tools/handlers/argument-helper.js.map +1 -0
- package/dist/tools/handlers/asset-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/asset-handlers.js +5 -1
- package/dist/tools/handlers/asset-handlers.js.map +1 -0
- package/dist/tools/handlers/audio-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/audio-handlers.js.map +1 -0
- package/dist/tools/handlers/blueprint-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/blueprint-handlers.js +2 -1
- package/dist/tools/handlers/blueprint-handlers.js.map +1 -0
- package/dist/tools/handlers/common-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/common-handlers.js.map +1 -0
- package/dist/tools/handlers/editor-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/editor-handlers.js +12 -2
- package/dist/tools/handlers/editor-handlers.js.map +1 -0
- package/dist/tools/handlers/effect-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/effect-handlers.js.map +1 -0
- package/dist/tools/handlers/environment-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/environment-handlers.js.map +1 -0
- package/dist/tools/handlers/graph-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/graph-handlers.js +61 -1
- package/dist/tools/handlers/graph-handlers.js.map +1 -0
- package/dist/tools/handlers/input-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/input-handlers.js.map +1 -0
- package/dist/tools/handlers/inspect-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/inspect-handlers.js.map +1 -0
- package/dist/tools/handlers/level-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/level-handlers.js.map +1 -0
- package/dist/tools/handlers/lighting-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/lighting-handlers.js +23 -1
- package/dist/tools/handlers/lighting-handlers.js.map +1 -0
- package/dist/tools/handlers/performance-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/performance-handlers.js +15 -2
- package/dist/tools/handlers/performance-handlers.js.map +1 -0
- package/dist/tools/handlers/pipeline-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/pipeline-handlers.js.map +1 -0
- package/dist/tools/handlers/sequence-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/sequence-handlers.js.map +1 -0
- package/dist/tools/handlers/system-handlers.d.ts.map +1 -0
- package/dist/tools/handlers/system-handlers.js +16 -1
- package/dist/tools/handlers/system-handlers.js.map +1 -0
- package/dist/tools/input.d.ts.map +1 -0
- package/dist/tools/input.js +3 -1
- package/dist/tools/input.js.map +1 -0
- package/dist/tools/introspection.d.ts.map +1 -0
- package/dist/tools/introspection.js.map +1 -0
- package/dist/tools/landscape.d.ts.map +1 -0
- package/dist/tools/landscape.js +3 -1
- package/dist/tools/landscape.js.map +1 -0
- package/dist/tools/level.d.ts.map +1 -0
- package/dist/tools/level.js.map +1 -0
- package/dist/tools/lighting.d.ts.map +1 -0
- package/dist/tools/lighting.js +3 -1
- package/dist/tools/lighting.js.map +1 -0
- package/dist/tools/logs.d.ts.map +1 -0
- package/dist/tools/logs.js.map +1 -0
- package/dist/tools/materials.d.ts.map +1 -0
- package/dist/tools/materials.js +3 -1
- package/dist/tools/materials.js.map +1 -0
- package/dist/tools/niagara.d.ts.map +1 -0
- package/dist/tools/niagara.js +7 -5
- package/dist/tools/niagara.js.map +1 -0
- package/dist/tools/performance.d.ts.map +1 -0
- package/dist/tools/performance.js.map +1 -0
- package/dist/tools/physics.d.ts.map +1 -0
- package/dist/tools/physics.js +9 -7
- package/dist/tools/physics.js.map +1 -0
- package/dist/tools/property-dictionary.d.ts.map +1 -0
- package/dist/tools/property-dictionary.js.map +1 -0
- package/dist/tools/sequence.d.ts.map +1 -0
- package/dist/tools/sequence.js +3 -1
- package/dist/tools/sequence.js.map +1 -0
- package/dist/tools/tool-definition-utils.d.ts.map +1 -0
- package/dist/tools/tool-definition-utils.js.map +1 -0
- package/dist/tools/ui.d.ts.map +1 -0
- package/dist/tools/ui.js +3 -1
- package/dist/tools/ui.js.map +1 -0
- package/dist/types/automation-responses.d.ts.map +1 -0
- package/dist/types/automation-responses.js.map +1 -0
- package/dist/types/env.d.ts.map +1 -0
- package/dist/types/env.js.map +1 -0
- package/dist/types/handler-types.d.ts.map +1 -0
- package/dist/types/handler-types.js.map +1 -0
- package/dist/types/tool-interfaces.d.ts.map +1 -0
- package/dist/types/tool-interfaces.js.map +1 -0
- package/dist/types/tool-types.d.ts.map +1 -0
- package/dist/types/tool-types.js.map +1 -0
- package/dist/unreal-bridge.d.ts +1 -0
- package/dist/unreal-bridge.d.ts.map +1 -0
- package/dist/unreal-bridge.js +8 -0
- package/dist/unreal-bridge.js.map +1 -0
- package/dist/utils/command-validator.d.ts.map +1 -0
- package/dist/utils/command-validator.js.map +1 -0
- package/dist/utils/elicitation.d.ts.map +1 -0
- package/dist/utils/elicitation.js.map +1 -0
- package/dist/utils/error-handler.d.ts.map +1 -0
- package/dist/utils/error-handler.js.map +1 -0
- package/dist/utils/ini-reader.d.ts.map +1 -0
- package/dist/utils/ini-reader.js.map +1 -0
- package/dist/utils/logger.d.ts.map +1 -0
- package/dist/utils/logger.js.map +1 -0
- package/dist/utils/normalize.d.ts.map +1 -0
- package/dist/utils/normalize.js.map +1 -0
- package/dist/utils/path-security.d.ts.map +1 -0
- package/dist/utils/path-security.js.map +1 -0
- package/dist/utils/response-factory.d.ts.map +1 -0
- package/dist/utils/response-factory.js +3 -1
- package/dist/utils/response-factory.js.map +1 -0
- package/dist/utils/response-validator.d.ts.map +1 -0
- package/dist/utils/response-validator.js.map +1 -0
- package/dist/utils/result-helpers.d.ts.map +1 -0
- package/dist/utils/result-helpers.js.map +1 -0
- package/dist/utils/safe-json.d.ts.map +1 -0
- package/dist/utils/safe-json.js.map +1 -0
- package/dist/utils/unreal-command-queue.d.ts.map +1 -0
- package/dist/utils/unreal-command-queue.js.map +1 -0
- package/dist/utils/validation.d.ts.map +1 -0
- package/dist/utils/validation.js.map +1 -0
- package/dist/wasm/index.d.ts.map +1 -0
- package/dist/wasm/index.js.map +1 -0
- package/package.json +12 -34
- package/server.json +2 -2
- package/.dockerignore +0 -57
- package/.env.example +0 -26
- package/.env.production +0 -61
- package/.eslintrc.json +0 -0
- package/.eslintrc.override.json +0 -8
- package/.github/ISSUE_TEMPLATE/bug_report.yml +0 -94
- package/.github/ISSUE_TEMPLATE/config.yml +0 -8
- package/.github/ISSUE_TEMPLATE/feature_request.yml +0 -56
- package/.github/copilot-instructions.md +0 -478
- package/.github/dependabot.yml +0 -19
- package/.github/labeler.yml +0 -24
- package/.github/labels.yml +0 -70
- package/.github/pull_request_template.md +0 -42
- package/.github/release-drafter-config.yml +0 -51
- package/.github/workflows/auto-merge.yml +0 -38
- package/.github/workflows/ci.yml +0 -38
- package/.github/workflows/dependency-review.yml +0 -17
- package/.github/workflows/gemini-issue-triage.yml +0 -172
- package/.github/workflows/greetings.yml +0 -27
- package/.github/workflows/labeler.yml +0 -17
- package/.github/workflows/links.yml +0 -80
- package/.github/workflows/pr-size-labeler.yml +0 -137
- package/.github/workflows/publish-mcp.yml +0 -79
- package/.github/workflows/release-drafter.yml +0 -24
- package/.github/workflows/release.yml +0 -112
- package/.github/workflows/semantic-pull-request.yml +0 -35
- package/.github/workflows/smoke-test.yml +0 -36
- package/.github/workflows/stale.yml +0 -28
- package/CONTRIBUTING.md +0 -140
- package/Dockerfile +0 -37
- package/GEMINI.md +0 -115
- package/Public/Plugin_setup_guide.mp4 +0 -0
- package/Public/icon.png +0 -0
- package/claude_desktop_config_example.json +0 -15
- package/dist/types/responses.d.ts +0 -249
- package/dist/types/responses.js +0 -2
- package/docs/GraphQL-API.md +0 -888
- package/docs/Migration-Guide-v0.5.0.md +0 -684
- package/docs/Roadmap.md +0 -53
- package/docs/WebAssembly-Integration.md +0 -628
- package/docs/editor-plugin-extension.md +0 -370
- package/docs/handler-mapping.md +0 -249
- package/docs/native-automation-progress.md +0 -128
- package/docs/testing-guide.md +0 -423
- package/eslint.config.mjs +0 -68
- package/mcp-config-example.json +0 -14
- package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +0 -8
- package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +0 -64
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +0 -189
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +0 -22
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +0 -30
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +0 -1983
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +0 -72
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +0 -46
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +0 -846
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +0 -2393
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +0 -300
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +0 -2807
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +0 -1087
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +0 -488
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +0 -643
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +0 -31
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +0 -1094
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +0 -5750
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +0 -152
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +0 -2614
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +0 -42
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +0 -1237
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +0 -1725
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +0 -2265
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +0 -954
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +0 -209
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +0 -41
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +0 -1164
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +0 -762
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +0 -663
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +0 -136
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +0 -494
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +0 -278
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +0 -625
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +0 -401
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +0 -67
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +0 -472
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +0 -2634
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +0 -189
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +0 -917
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +0 -39
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +0 -2706
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +0 -519
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +0 -38
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +0 -668
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +0 -346
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +0 -1345
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +0 -149
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -782
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +0 -115
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +0 -796
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +0 -117
- package/scripts/check-unreal-connection.mjs +0 -19
- package/scripts/clean-tmp.js +0 -23
- package/scripts/patch-wasm.js +0 -26
- package/scripts/run-all-tests.mjs +0 -136
- package/scripts/smoke-test.ts +0 -94
- package/scripts/sync-mcp-plugin.js +0 -143
- package/scripts/test-no-plugin-alternates.mjs +0 -113
- package/scripts/validate-server.js +0 -46
- package/scripts/verify-automation-bridge.js +0 -200
- package/src/automation/bridge.ts +0 -630
- package/src/automation/connection-manager.ts +0 -148
- package/src/automation/handshake.ts +0 -99
- package/src/automation/index.ts +0 -2
- package/src/automation/message-handler.ts +0 -192
- package/src/automation/request-tracker.ts +0 -155
- package/src/automation/types.ts +0 -108
- package/src/cli.ts +0 -34
- package/src/config/class-aliases.ts +0 -65
- package/src/config.ts +0 -73
- package/src/constants.ts +0 -29
- package/src/graphql/loaders.ts +0 -244
- package/src/graphql/resolvers.ts +0 -1008
- package/src/graphql/schema.ts +0 -452
- package/src/graphql/server.ts +0 -156
- package/src/graphql/types.ts +0 -10
- package/src/handlers/resource-handlers.ts +0 -186
- package/src/index.ts +0 -243
- package/src/resources/actors.ts +0 -127
- package/src/resources/assets.ts +0 -286
- package/src/resources/levels.ts +0 -68
- package/src/server/resource-registry.ts +0 -47
- package/src/server/tool-registry.ts +0 -354
- package/src/server-setup.ts +0 -114
- package/src/services/health-monitor.ts +0 -132
- package/src/services/metrics-server.ts +0 -176
- package/src/tools/actors.ts +0 -564
- package/src/tools/animation.ts +0 -941
- package/src/tools/assets.ts +0 -394
- package/src/tools/audio.ts +0 -499
- package/src/tools/base-tool.ts +0 -52
- package/src/tools/behavior-tree.ts +0 -45
- package/src/tools/blueprint.ts +0 -940
- package/src/tools/consolidated-tool-definitions.ts +0 -1256
- package/src/tools/consolidated-tool-handlers.ts +0 -302
- package/src/tools/debug.ts +0 -622
- package/src/tools/dynamic-handler-registry.ts +0 -33
- package/src/tools/editor.ts +0 -435
- package/src/tools/engine.ts +0 -43
- package/src/tools/environment.ts +0 -281
- package/src/tools/foliage.ts +0 -596
- package/src/tools/handlers/actor-handlers.ts +0 -244
- package/src/tools/handlers/animation-handlers.ts +0 -237
- package/src/tools/handlers/argument-helper.ts +0 -142
- package/src/tools/handlers/asset-handlers.ts +0 -550
- package/src/tools/handlers/audio-handlers.ts +0 -194
- package/src/tools/handlers/blueprint-handlers.ts +0 -380
- package/src/tools/handlers/common-handlers.ts +0 -108
- package/src/tools/handlers/editor-handlers.ts +0 -124
- package/src/tools/handlers/effect-handlers.ts +0 -224
- package/src/tools/handlers/environment-handlers.ts +0 -183
- package/src/tools/handlers/graph-handlers.ts +0 -117
- package/src/tools/handlers/input-handlers.ts +0 -28
- package/src/tools/handlers/inspect-handlers.ts +0 -450
- package/src/tools/handlers/level-handlers.ts +0 -253
- package/src/tools/handlers/lighting-handlers.ts +0 -151
- package/src/tools/handlers/performance-handlers.ts +0 -132
- package/src/tools/handlers/pipeline-handlers.ts +0 -194
- package/src/tools/handlers/sequence-handlers.ts +0 -438
- package/src/tools/handlers/system-handlers.ts +0 -564
- package/src/tools/input.ts +0 -160
- package/src/tools/introspection.ts +0 -689
- package/src/tools/landscape.ts +0 -649
- package/src/tools/level.ts +0 -989
- package/src/tools/lighting.ts +0 -1052
- package/src/tools/logs.ts +0 -219
- package/src/tools/materials.ts +0 -295
- package/src/tools/niagara.ts +0 -485
- package/src/tools/performance.ts +0 -661
- package/src/tools/physics.ts +0 -679
- package/src/tools/property-dictionary.ts +0 -98
- package/src/tools/sequence.ts +0 -385
- package/src/tools/tool-definition-utils.ts +0 -35
- package/src/tools/ui.ts +0 -452
- package/src/types/automation-responses.ts +0 -119
- package/src/types/env.ts +0 -17
- package/src/types/handler-types.ts +0 -442
- package/src/types/responses.ts +0 -355
- package/src/types/tool-interfaces.ts +0 -250
- package/src/types/tool-types.ts +0 -575
- package/src/unreal-bridge.ts +0 -693
- package/src/utils/command-validator.ts +0 -139
- package/src/utils/elicitation.ts +0 -132
- package/src/utils/error-handler.ts +0 -287
- package/src/utils/ini-reader.ts +0 -86
- package/src/utils/logger.ts +0 -35
- package/src/utils/normalize.test.ts +0 -162
- package/src/utils/normalize.ts +0 -146
- package/src/utils/path-security.ts +0 -43
- package/src/utils/response-factory.ts +0 -44
- package/src/utils/response-validator.ts +0 -395
- package/src/utils/result-helpers.ts +0 -195
- package/src/utils/safe-json.test.ts +0 -90
- package/src/utils/safe-json.ts +0 -70
- package/src/utils/unreal-command-queue.ts +0 -166
- package/src/utils/validation.test.ts +0 -184
- package/src/utils/validation.ts +0 -312
- package/src/wasm/index.ts +0 -838
- package/test-server.mjs +0 -100
- package/tests/test-animation.mjs +0 -369
- package/tests/test-asset-advanced.mjs +0 -82
- package/tests/test-asset-graph.mjs +0 -311
- package/tests/test-audio.mjs +0 -417
- package/tests/test-automation-timeouts.mjs +0 -98
- package/tests/test-behavior-tree.mjs +0 -444
- package/tests/test-blueprint-graph.mjs +0 -410
- package/tests/test-blueprint.mjs +0 -577
- package/tests/test-client-mode.mjs +0 -86
- package/tests/test-console-command.mjs +0 -56
- package/tests/test-control-actor.mjs +0 -425
- package/tests/test-control-editor.mjs +0 -112
- package/tests/test-graphql.mjs +0 -372
- package/tests/test-input.mjs +0 -349
- package/tests/test-inspect.mjs +0 -302
- package/tests/test-landscape.mjs +0 -316
- package/tests/test-lighting.mjs +0 -428
- package/tests/test-manage-asset.mjs +0 -438
- package/tests/test-manage-level.mjs +0 -89
- package/tests/test-materials.mjs +0 -356
- package/tests/test-niagara.mjs +0 -185
- package/tests/test-no-inline-python.mjs +0 -122
- package/tests/test-performance.mjs +0 -539
- package/tests/test-plugin-handshake.mjs +0 -82
- package/tests/test-runner.mjs +0 -993
- package/tests/test-sequence.mjs +0 -104
- package/tests/test-system.mjs +0 -96
- package/tests/test-wasm.mjs +0 -283
- package/tests/test-world-partition.mjs +0 -215
- package/tsconfig.json +0 -56
- package/vitest.config.ts +0 -35
- package/wasm/Cargo.lock +0 -363
- package/wasm/Cargo.toml +0 -42
- package/wasm/LICENSE +0 -21
- package/wasm/README.md +0 -253
- package/wasm/src/dependency_resolver.rs +0 -377
- package/wasm/src/lib.rs +0 -153
- package/wasm/src/property_parser.rs +0 -271
- package/wasm/src/transform_math.rs +0 -396
- package/wasm/tests/integration.rs +0 -109
package/src/unreal-bridge.ts
DELETED
|
@@ -1,693 +0,0 @@
|
|
|
1
|
-
import { Logger } from './utils/logger.js';
|
|
2
|
-
import { ErrorHandler } from './utils/error-handler.js';
|
|
3
|
-
import type { AutomationBridge } from './automation/index.js';
|
|
4
|
-
import { DEFAULT_AUTOMATION_HOST, DEFAULT_AUTOMATION_PORT, CONSOLE_COMMAND_TIMEOUT_MS, ENGINE_QUERY_TIMEOUT_MS } from './constants.js';
|
|
5
|
-
import { UnrealCommandQueue } from './utils/unreal-command-queue.js';
|
|
6
|
-
import { CommandValidator } from './utils/command-validator.js';
|
|
7
|
-
|
|
8
|
-
/** Connection event payload for automation bridge events */
|
|
9
|
-
interface ConnectionEventInfo {
|
|
10
|
-
host?: string;
|
|
11
|
-
port?: number;
|
|
12
|
-
reason?: string;
|
|
13
|
-
error?: string;
|
|
14
|
-
[key: string]: unknown;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
/** Result object from automation requests */
|
|
18
|
-
interface AutomationResult {
|
|
19
|
-
value?: unknown;
|
|
20
|
-
propertyValue?: unknown;
|
|
21
|
-
message?: string;
|
|
22
|
-
warnings?: string[];
|
|
23
|
-
[key: string]: unknown;
|
|
24
|
-
}
|
|
25
|
-
|
|
26
|
-
/** Subsystems feature flags */
|
|
27
|
-
interface SubsystemFlags {
|
|
28
|
-
unrealEditor?: boolean;
|
|
29
|
-
levelEditor?: boolean;
|
|
30
|
-
editorActor?: boolean;
|
|
31
|
-
[key: string]: unknown;
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
/** Engine version result */
|
|
35
|
-
interface EngineVersionResult {
|
|
36
|
-
version?: string;
|
|
37
|
-
major?: number;
|
|
38
|
-
minor?: number;
|
|
39
|
-
patch?: number;
|
|
40
|
-
isUE56OrAbove?: boolean;
|
|
41
|
-
[key: string]: unknown;
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
/** Console command response */
|
|
45
|
-
interface ConsoleCommandResponse {
|
|
46
|
-
success?: boolean;
|
|
47
|
-
message?: string;
|
|
48
|
-
error?: string;
|
|
49
|
-
transport?: string;
|
|
50
|
-
[key: string]: unknown;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
export class UnrealBridge {
|
|
54
|
-
private log = new Logger('UnrealBridge');
|
|
55
|
-
private connected = false;
|
|
56
|
-
private automationBridge?: AutomationBridge;
|
|
57
|
-
private automationBridgeListeners?: {
|
|
58
|
-
connected: (info: ConnectionEventInfo) => void;
|
|
59
|
-
disconnected: (info: ConnectionEventInfo) => void;
|
|
60
|
-
handshakeFailed: (info: ConnectionEventInfo) => void;
|
|
61
|
-
};
|
|
62
|
-
|
|
63
|
-
// Command queue for throttling
|
|
64
|
-
private commandQueue = new UnrealCommandQueue();
|
|
65
|
-
|
|
66
|
-
get isConnected() { return this.connected; }
|
|
67
|
-
|
|
68
|
-
setAutomationBridge(automationBridge?: AutomationBridge): void {
|
|
69
|
-
if (this.automationBridge && this.automationBridgeListeners) {
|
|
70
|
-
this.automationBridge.off('connected', this.automationBridgeListeners.connected);
|
|
71
|
-
this.automationBridge.off('disconnected', this.automationBridgeListeners.disconnected);
|
|
72
|
-
this.automationBridge.off('handshakeFailed', this.automationBridgeListeners.handshakeFailed);
|
|
73
|
-
}
|
|
74
|
-
|
|
75
|
-
this.automationBridge = automationBridge;
|
|
76
|
-
this.automationBridgeListeners = undefined;
|
|
77
|
-
|
|
78
|
-
if (!automationBridge) {
|
|
79
|
-
this.connected = false;
|
|
80
|
-
return;
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
const onConnected = (info: ConnectionEventInfo) => {
|
|
84
|
-
this.connected = true;
|
|
85
|
-
this.log.debug('Automation bridge connected', info);
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
const onDisconnected = (info: ConnectionEventInfo) => {
|
|
89
|
-
this.connected = false;
|
|
90
|
-
this.log.debug('Automation bridge disconnected', info);
|
|
91
|
-
};
|
|
92
|
-
|
|
93
|
-
const onHandshakeFailed = (info: ConnectionEventInfo) => {
|
|
94
|
-
this.connected = false;
|
|
95
|
-
this.log.warn('Automation bridge handshake failed', info);
|
|
96
|
-
};
|
|
97
|
-
|
|
98
|
-
automationBridge.on('connected', onConnected);
|
|
99
|
-
automationBridge.on('disconnected', onDisconnected);
|
|
100
|
-
automationBridge.on('handshakeFailed', onHandshakeFailed);
|
|
101
|
-
|
|
102
|
-
this.automationBridgeListeners = {
|
|
103
|
-
connected: onConnected,
|
|
104
|
-
disconnected: onDisconnected,
|
|
105
|
-
handshakeFailed: onHandshakeFailed
|
|
106
|
-
};
|
|
107
|
-
|
|
108
|
-
this.connected = automationBridge.isConnected();
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
/**
|
|
112
|
-
* Get the automation bridge instance safely.
|
|
113
|
-
* Throws if not configured, but does not check connection status (use isConnected for that).
|
|
114
|
-
*/
|
|
115
|
-
getAutomationBridge(): AutomationBridge {
|
|
116
|
-
if (!this.automationBridge) {
|
|
117
|
-
throw new Error('Automation bridge is not configured');
|
|
118
|
-
}
|
|
119
|
-
return this.automationBridge;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
/**
|
|
123
|
-
* Attempt to connect with exponential backoff retry strategy
|
|
124
|
-
* Uses optimized retry pattern from TypeScript best practices
|
|
125
|
-
* @param maxAttempts Maximum number of connection attempts
|
|
126
|
-
* @param timeoutMs Timeout for each connection attempt in milliseconds
|
|
127
|
-
* @param retryDelayMs Initial delay between retry attempts in milliseconds
|
|
128
|
-
* @returns Promise that resolves to true if connected, false otherwise
|
|
129
|
-
*/
|
|
130
|
-
private connectPromise?: Promise<void>;
|
|
131
|
-
|
|
132
|
-
async tryConnect(maxAttempts: number = 3, timeoutMs: number = 15000, retryDelayMs: number = 3000): Promise<boolean> {
|
|
133
|
-
if (process.env.MOCK_UNREAL_CONNECTION === 'true') {
|
|
134
|
-
this.log.info('🔌 MOCK MODE: Simulating active connection');
|
|
135
|
-
this.connected = true;
|
|
136
|
-
return true;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
if (this.connected && this.automationBridge?.isConnected()) {
|
|
140
|
-
return true;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
if (!this.automationBridge) {
|
|
144
|
-
this.log.warn('Automation bridge is not configured; cannot establish connection.');
|
|
145
|
-
return false;
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
if (this.automationBridge.isConnected()) {
|
|
149
|
-
this.connected = true;
|
|
150
|
-
return true;
|
|
151
|
-
}
|
|
152
|
-
|
|
153
|
-
if (this.connectPromise) {
|
|
154
|
-
try {
|
|
155
|
-
await this.connectPromise;
|
|
156
|
-
} catch (err) {
|
|
157
|
-
this.log.debug('Existing connect promise rejected', err instanceof Error ? err.message : String(err));
|
|
158
|
-
}
|
|
159
|
-
return this.connected;
|
|
160
|
-
}
|
|
161
|
-
|
|
162
|
-
this.connectPromise = ErrorHandler.retryWithBackoff(
|
|
163
|
-
() => {
|
|
164
|
-
const envTimeout = process.env.UNREAL_CONNECTION_TIMEOUT ? parseInt(process.env.UNREAL_CONNECTION_TIMEOUT, 10) : 30000;
|
|
165
|
-
const actualTimeout = envTimeout > 0 ? envTimeout : timeoutMs;
|
|
166
|
-
return this.connect(actualTimeout);
|
|
167
|
-
},
|
|
168
|
-
{
|
|
169
|
-
maxRetries: Math.max(0, maxAttempts - 1),
|
|
170
|
-
initialDelay: retryDelayMs,
|
|
171
|
-
maxDelay: 10000,
|
|
172
|
-
backoffMultiplier: 1.5,
|
|
173
|
-
shouldRetry: (error: any) => {
|
|
174
|
-
const msg = (error as Error)?.message?.toLowerCase() || '';
|
|
175
|
-
return msg.includes('timeout') || msg.includes('connect') || msg.includes('automation');
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
).catch((err: any) => {
|
|
179
|
-
this.log.warn(`Automation bridge connection failed after ${maxAttempts} attempts:`, err.message);
|
|
180
|
-
this.log.warn('⚠️ Ensure Unreal Editor is running with MCP Automation Bridge plugin enabled');
|
|
181
|
-
this.log.warn(`⚠️ Plugin should listen on ws://${DEFAULT_AUTOMATION_HOST}:${DEFAULT_AUTOMATION_PORT} for MCP server connections`);
|
|
182
|
-
});
|
|
183
|
-
|
|
184
|
-
try {
|
|
185
|
-
await this.connectPromise;
|
|
186
|
-
} finally {
|
|
187
|
-
this.connectPromise = undefined;
|
|
188
|
-
}
|
|
189
|
-
|
|
190
|
-
this.connected = this.automationBridge?.isConnected() ?? false;
|
|
191
|
-
return this.connected;
|
|
192
|
-
}
|
|
193
|
-
|
|
194
|
-
async connect(timeoutMs: number = 15000): Promise<void> {
|
|
195
|
-
const automationBridge = this.automationBridge;
|
|
196
|
-
if (!automationBridge) {
|
|
197
|
-
throw new Error('Automation bridge not configured');
|
|
198
|
-
}
|
|
199
|
-
|
|
200
|
-
if (automationBridge.isConnected()) {
|
|
201
|
-
this.connected = true;
|
|
202
|
-
return;
|
|
203
|
-
}
|
|
204
|
-
|
|
205
|
-
// Start the bridge connection if it's not active
|
|
206
|
-
// This supports lazy connection where the bridge doesn't start until a tool is used
|
|
207
|
-
automationBridge.start();
|
|
208
|
-
|
|
209
|
-
const success = await this.waitForAutomationConnection(timeoutMs);
|
|
210
|
-
if (!success) {
|
|
211
|
-
throw new Error('Automation bridge connection timeout');
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
this.connected = true;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
private async waitForAutomationConnection(timeoutMs: number): Promise<boolean> {
|
|
218
|
-
const automationBridge = this.automationBridge;
|
|
219
|
-
if (!automationBridge) {
|
|
220
|
-
return false;
|
|
221
|
-
}
|
|
222
|
-
|
|
223
|
-
if (automationBridge.isConnected()) {
|
|
224
|
-
return true;
|
|
225
|
-
}
|
|
226
|
-
|
|
227
|
-
return new Promise<boolean>((resolve) => {
|
|
228
|
-
let settled = false;
|
|
229
|
-
|
|
230
|
-
const cleanup = () => {
|
|
231
|
-
if (settled) {
|
|
232
|
-
return;
|
|
233
|
-
}
|
|
234
|
-
settled = true;
|
|
235
|
-
automationBridge.off('connected', onConnected);
|
|
236
|
-
automationBridge.off('handshakeFailed', onHandshakeFailed);
|
|
237
|
-
automationBridge.off('error', onError);
|
|
238
|
-
automationBridge.off('disconnected', onDisconnected);
|
|
239
|
-
clearTimeout(timer);
|
|
240
|
-
};
|
|
241
|
-
|
|
242
|
-
const onConnected = (info: any) => {
|
|
243
|
-
cleanup();
|
|
244
|
-
this.log.debug('Automation bridge connected while waiting', info);
|
|
245
|
-
resolve(true);
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
const onHandshakeFailed = (info: any) => {
|
|
249
|
-
this.log.warn('Automation bridge handshake failed while waiting', info);
|
|
250
|
-
// We don't resolve false immediately here? The original code didn't.
|
|
251
|
-
// But handshake failed usually means we should stop waiting.
|
|
252
|
-
cleanup();
|
|
253
|
-
resolve(false);
|
|
254
|
-
};
|
|
255
|
-
|
|
256
|
-
const onError = (err: any) => {
|
|
257
|
-
this.log.warn('Automation bridge error while waiting', err);
|
|
258
|
-
cleanup();
|
|
259
|
-
resolve(false);
|
|
260
|
-
};
|
|
261
|
-
|
|
262
|
-
const onDisconnected = (info: any) => {
|
|
263
|
-
this.log.warn('Automation bridge disconnected while waiting', info);
|
|
264
|
-
cleanup();
|
|
265
|
-
resolve(false);
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
const timer = setTimeout(() => {
|
|
269
|
-
cleanup();
|
|
270
|
-
resolve(false);
|
|
271
|
-
}, Math.max(0, timeoutMs));
|
|
272
|
-
|
|
273
|
-
automationBridge.on('connected', onConnected);
|
|
274
|
-
automationBridge.on('handshakeFailed', onHandshakeFailed);
|
|
275
|
-
automationBridge.on('error', onError);
|
|
276
|
-
automationBridge.on('disconnected', onDisconnected);
|
|
277
|
-
});
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
async getObjectProperty(params: {
|
|
281
|
-
objectPath: string;
|
|
282
|
-
propertyName: string;
|
|
283
|
-
timeoutMs?: number;
|
|
284
|
-
allowAlternate?: boolean;
|
|
285
|
-
}): Promise<Record<string, any>> {
|
|
286
|
-
const { objectPath, propertyName, timeoutMs } = params;
|
|
287
|
-
if (!objectPath || typeof objectPath !== 'string') {
|
|
288
|
-
throw new Error('Invalid objectPath: must be a non-empty string');
|
|
289
|
-
}
|
|
290
|
-
if (!propertyName || typeof propertyName !== 'string') {
|
|
291
|
-
throw new Error('Invalid propertyName: must be a non-empty string');
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
const bridge = this.automationBridge;
|
|
295
|
-
|
|
296
|
-
if (process.env.MOCK_UNREAL_CONNECTION === 'true') {
|
|
297
|
-
return {
|
|
298
|
-
success: true,
|
|
299
|
-
objectPath,
|
|
300
|
-
propertyName,
|
|
301
|
-
value: 'MockValue',
|
|
302
|
-
propertyValue: 'MockValue',
|
|
303
|
-
transport: 'mock_bridge',
|
|
304
|
-
message: 'Mock property read successful'
|
|
305
|
-
};
|
|
306
|
-
}
|
|
307
|
-
|
|
308
|
-
if (!bridge || typeof bridge.sendAutomationRequest !== 'function') {
|
|
309
|
-
return {
|
|
310
|
-
success: false,
|
|
311
|
-
objectPath,
|
|
312
|
-
propertyName,
|
|
313
|
-
error: 'Automation bridge not connected',
|
|
314
|
-
transport: 'automation_bridge'
|
|
315
|
-
};
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
try {
|
|
319
|
-
const response = await bridge.sendAutomationRequest(
|
|
320
|
-
'get_object_property',
|
|
321
|
-
{
|
|
322
|
-
objectPath,
|
|
323
|
-
propertyName
|
|
324
|
-
},
|
|
325
|
-
timeoutMs ? { timeoutMs } : undefined
|
|
326
|
-
);
|
|
327
|
-
|
|
328
|
-
const success = response.success !== false;
|
|
329
|
-
const rawResult: AutomationResult | undefined =
|
|
330
|
-
response.result && typeof response.result === 'object'
|
|
331
|
-
? { ...(response.result as Record<string, unknown>) }
|
|
332
|
-
: undefined;
|
|
333
|
-
const value =
|
|
334
|
-
rawResult?.value ??
|
|
335
|
-
rawResult?.propertyValue ??
|
|
336
|
-
(success ? rawResult : undefined);
|
|
337
|
-
|
|
338
|
-
if (success) {
|
|
339
|
-
return {
|
|
340
|
-
success: true,
|
|
341
|
-
objectPath,
|
|
342
|
-
propertyName,
|
|
343
|
-
value,
|
|
344
|
-
propertyValue: value,
|
|
345
|
-
transport: 'automation_bridge',
|
|
346
|
-
message: response.message,
|
|
347
|
-
warnings: Array.isArray(rawResult?.warnings)
|
|
348
|
-
? rawResult.warnings
|
|
349
|
-
: undefined,
|
|
350
|
-
raw: rawResult,
|
|
351
|
-
bridge: {
|
|
352
|
-
requestId: response.requestId,
|
|
353
|
-
success: true,
|
|
354
|
-
error: response.error
|
|
355
|
-
}
|
|
356
|
-
};
|
|
357
|
-
}
|
|
358
|
-
|
|
359
|
-
return {
|
|
360
|
-
success: false,
|
|
361
|
-
objectPath,
|
|
362
|
-
propertyName,
|
|
363
|
-
error: response.error || response.message || 'AUTOMATION_BRIDGE_FAILURE',
|
|
364
|
-
transport: 'automation_bridge',
|
|
365
|
-
raw: rawResult,
|
|
366
|
-
bridge: {
|
|
367
|
-
requestId: response.requestId,
|
|
368
|
-
success: false,
|
|
369
|
-
error: response.error
|
|
370
|
-
}
|
|
371
|
-
};
|
|
372
|
-
} catch (err) {
|
|
373
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
374
|
-
return {
|
|
375
|
-
success: false,
|
|
376
|
-
objectPath,
|
|
377
|
-
propertyName,
|
|
378
|
-
error: message,
|
|
379
|
-
transport: 'automation_bridge'
|
|
380
|
-
};
|
|
381
|
-
}
|
|
382
|
-
}
|
|
383
|
-
|
|
384
|
-
async setObjectProperty(params: {
|
|
385
|
-
objectPath: string;
|
|
386
|
-
propertyName: string;
|
|
387
|
-
value: unknown;
|
|
388
|
-
markDirty?: boolean;
|
|
389
|
-
timeoutMs?: number;
|
|
390
|
-
allowAlternate?: boolean;
|
|
391
|
-
}): Promise<Record<string, any>> {
|
|
392
|
-
const { objectPath, propertyName, value, markDirty, timeoutMs } = params;
|
|
393
|
-
if (!objectPath || typeof objectPath !== 'string') {
|
|
394
|
-
throw new Error('Invalid objectPath: must be a non-empty string');
|
|
395
|
-
}
|
|
396
|
-
if (!propertyName || typeof propertyName !== 'string') {
|
|
397
|
-
throw new Error('Invalid propertyName: must be a non-empty string');
|
|
398
|
-
}
|
|
399
|
-
|
|
400
|
-
const bridge = this.automationBridge;
|
|
401
|
-
|
|
402
|
-
if (process.env.MOCK_UNREAL_CONNECTION === 'true') {
|
|
403
|
-
return {
|
|
404
|
-
success: true,
|
|
405
|
-
objectPath,
|
|
406
|
-
propertyName,
|
|
407
|
-
message: 'Mock property set successful',
|
|
408
|
-
transport: 'mock_bridge'
|
|
409
|
-
};
|
|
410
|
-
}
|
|
411
|
-
|
|
412
|
-
if (!bridge || typeof bridge.sendAutomationRequest !== 'function') {
|
|
413
|
-
return {
|
|
414
|
-
success: false,
|
|
415
|
-
objectPath,
|
|
416
|
-
propertyName,
|
|
417
|
-
error: 'Automation bridge not connected',
|
|
418
|
-
transport: 'automation_bridge'
|
|
419
|
-
};
|
|
420
|
-
}
|
|
421
|
-
|
|
422
|
-
const payload: Record<string, unknown> = {
|
|
423
|
-
objectPath,
|
|
424
|
-
propertyName,
|
|
425
|
-
value
|
|
426
|
-
};
|
|
427
|
-
if (markDirty !== undefined) {
|
|
428
|
-
payload.markDirty = Boolean(markDirty);
|
|
429
|
-
}
|
|
430
|
-
|
|
431
|
-
try {
|
|
432
|
-
const response = await bridge.sendAutomationRequest(
|
|
433
|
-
'set_object_property',
|
|
434
|
-
payload,
|
|
435
|
-
timeoutMs ? { timeoutMs } : undefined
|
|
436
|
-
);
|
|
437
|
-
|
|
438
|
-
const success = response.success !== false;
|
|
439
|
-
const rawResult: AutomationResult | undefined =
|
|
440
|
-
response.result && typeof response.result === 'object'
|
|
441
|
-
? { ...(response.result as Record<string, unknown>) }
|
|
442
|
-
: undefined;
|
|
443
|
-
|
|
444
|
-
if (success) {
|
|
445
|
-
return {
|
|
446
|
-
success: true,
|
|
447
|
-
objectPath,
|
|
448
|
-
propertyName,
|
|
449
|
-
message:
|
|
450
|
-
response.message ||
|
|
451
|
-
(typeof rawResult?.message === 'string' ? rawResult.message : undefined),
|
|
452
|
-
transport: 'automation_bridge',
|
|
453
|
-
raw: rawResult,
|
|
454
|
-
bridge: {
|
|
455
|
-
requestId: response.requestId,
|
|
456
|
-
success: true,
|
|
457
|
-
error: response.error
|
|
458
|
-
}
|
|
459
|
-
};
|
|
460
|
-
}
|
|
461
|
-
|
|
462
|
-
return {
|
|
463
|
-
success: false,
|
|
464
|
-
objectPath,
|
|
465
|
-
propertyName,
|
|
466
|
-
error: response.error || response.message || 'AUTOMATION_BRIDGE_FAILURE',
|
|
467
|
-
transport: 'automation_bridge',
|
|
468
|
-
raw: rawResult,
|
|
469
|
-
bridge: {
|
|
470
|
-
requestId: response.requestId,
|
|
471
|
-
success: false,
|
|
472
|
-
error: response.error
|
|
473
|
-
}
|
|
474
|
-
};
|
|
475
|
-
} catch (err) {
|
|
476
|
-
const message = err instanceof Error ? err.message : String(err);
|
|
477
|
-
return {
|
|
478
|
-
success: false,
|
|
479
|
-
objectPath,
|
|
480
|
-
propertyName,
|
|
481
|
-
error: message,
|
|
482
|
-
transport: 'automation_bridge'
|
|
483
|
-
};
|
|
484
|
-
}
|
|
485
|
-
}
|
|
486
|
-
|
|
487
|
-
// Execute a console command safely with validation and throttling
|
|
488
|
-
async executeConsoleCommand(command: string): Promise<any> {
|
|
489
|
-
const automationAvailable = Boolean(
|
|
490
|
-
this.automationBridge && typeof this.automationBridge.sendAutomationRequest === 'function'
|
|
491
|
-
);
|
|
492
|
-
if (!automationAvailable) {
|
|
493
|
-
throw new Error('Automation bridge not connected');
|
|
494
|
-
}
|
|
495
|
-
|
|
496
|
-
// Validate command
|
|
497
|
-
CommandValidator.validate(command);
|
|
498
|
-
const cmdTrimmed = command.trim();
|
|
499
|
-
if (cmdTrimmed.length === 0) {
|
|
500
|
-
return { success: true, message: 'Empty command ignored' };
|
|
501
|
-
}
|
|
502
|
-
|
|
503
|
-
if (CommandValidator.isLikelyInvalid(cmdTrimmed)) {
|
|
504
|
-
this.log.warn(`Command appears invalid: ${cmdTrimmed}`);
|
|
505
|
-
}
|
|
506
|
-
|
|
507
|
-
const priority = CommandValidator.getPriority(cmdTrimmed);
|
|
508
|
-
|
|
509
|
-
const executeCommand = async (): Promise<any> => {
|
|
510
|
-
if (process.env.MOCK_UNREAL_CONNECTION === 'true') {
|
|
511
|
-
this.log.info(`[MOCK] Executing console command: ${cmdTrimmed}`);
|
|
512
|
-
return { success: true, message: `Mock execution of '${cmdTrimmed}' successful`, transport: 'mock_bridge' };
|
|
513
|
-
}
|
|
514
|
-
|
|
515
|
-
if (!this.automationBridge || !this.automationBridge.isConnected()) {
|
|
516
|
-
throw new Error('Automation bridge not connected');
|
|
517
|
-
}
|
|
518
|
-
|
|
519
|
-
const pluginResp: ConsoleCommandResponse = await this.automationBridge.sendAutomationRequest(
|
|
520
|
-
'console_command',
|
|
521
|
-
{ command: cmdTrimmed },
|
|
522
|
-
{ timeoutMs: CONSOLE_COMMAND_TIMEOUT_MS }
|
|
523
|
-
);
|
|
524
|
-
|
|
525
|
-
if (pluginResp && pluginResp.success) {
|
|
526
|
-
return { ...pluginResp, transport: 'automation_bridge' };
|
|
527
|
-
}
|
|
528
|
-
|
|
529
|
-
const errMsg = pluginResp?.message || pluginResp?.error || 'Plugin execution failed';
|
|
530
|
-
throw new Error(errMsg);
|
|
531
|
-
};
|
|
532
|
-
|
|
533
|
-
try {
|
|
534
|
-
const result = await this.executeThrottledCommand(executeCommand, priority);
|
|
535
|
-
return result;
|
|
536
|
-
} catch (error) {
|
|
537
|
-
this.log.error(`Console command failed: ${cmdTrimmed}`, error);
|
|
538
|
-
throw error;
|
|
539
|
-
}
|
|
540
|
-
}
|
|
541
|
-
|
|
542
|
-
async executeConsoleCommands(
|
|
543
|
-
commands: Iterable<string | { command: string; priority?: number }>,
|
|
544
|
-
options: { continueOnError?: boolean; delayMs?: number } = {}
|
|
545
|
-
): Promise<any[]> {
|
|
546
|
-
const { continueOnError = false, delayMs = 0 } = options;
|
|
547
|
-
const results: any[] = [];
|
|
548
|
-
|
|
549
|
-
for (const rawCommand of commands) {
|
|
550
|
-
const descriptor = typeof rawCommand === 'string' ? { command: rawCommand } : rawCommand;
|
|
551
|
-
const command = descriptor.command?.trim();
|
|
552
|
-
if (!command) {
|
|
553
|
-
continue;
|
|
554
|
-
}
|
|
555
|
-
try {
|
|
556
|
-
const result = await this.executeConsoleCommand(command);
|
|
557
|
-
results.push(result);
|
|
558
|
-
} catch (error) {
|
|
559
|
-
if (!continueOnError) {
|
|
560
|
-
throw error;
|
|
561
|
-
}
|
|
562
|
-
this.log.warn(`Console batch command failed: ${command}`, error);
|
|
563
|
-
results.push(error);
|
|
564
|
-
}
|
|
565
|
-
|
|
566
|
-
if (delayMs > 0) {
|
|
567
|
-
await this.delay(delayMs);
|
|
568
|
-
}
|
|
569
|
-
}
|
|
570
|
-
|
|
571
|
-
return results;
|
|
572
|
-
}
|
|
573
|
-
|
|
574
|
-
async executeEditorFunction(
|
|
575
|
-
functionName: string,
|
|
576
|
-
params?: Record<string, any>,
|
|
577
|
-
_options?: { timeoutMs?: number }
|
|
578
|
-
): Promise<any> {
|
|
579
|
-
if (process.env.MOCK_UNREAL_CONNECTION === 'true') {
|
|
580
|
-
return { success: true, result: { status: 'mock_success', function: functionName } };
|
|
581
|
-
}
|
|
582
|
-
|
|
583
|
-
if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
|
|
584
|
-
return { success: false, error: 'AUTOMATION_BRIDGE_UNAVAILABLE' };
|
|
585
|
-
}
|
|
586
|
-
|
|
587
|
-
const resp: any = await this.automationBridge.sendAutomationRequest('execute_editor_function', {
|
|
588
|
-
functionName,
|
|
589
|
-
params: params ?? {}
|
|
590
|
-
}, _options?.timeoutMs ? { timeoutMs: _options.timeoutMs } : undefined);
|
|
591
|
-
|
|
592
|
-
return resp && resp.success !== false ? (resp.result ?? resp) : resp;
|
|
593
|
-
}
|
|
594
|
-
|
|
595
|
-
/** Get Unreal Engine version */
|
|
596
|
-
async getEngineVersion(): Promise<{ version: string; major: number; minor: number; patch: number; isUE56OrAbove: boolean; }> {
|
|
597
|
-
if (process.env.MOCK_UNREAL_CONNECTION === 'true') {
|
|
598
|
-
return { version: '5.6.0-Mock', major: 5, minor: 6, patch: 0, isUE56OrAbove: true };
|
|
599
|
-
}
|
|
600
|
-
|
|
601
|
-
const bridge = this.getAutomationBridge();
|
|
602
|
-
try {
|
|
603
|
-
const resp = await bridge.sendAutomationRequest(
|
|
604
|
-
'system_control',
|
|
605
|
-
{ action: 'get_engine_version' },
|
|
606
|
-
{ timeoutMs: ENGINE_QUERY_TIMEOUT_MS }
|
|
607
|
-
);
|
|
608
|
-
const raw: EngineVersionResult = resp && typeof resp.result === 'object'
|
|
609
|
-
? (resp.result as Record<string, unknown>)
|
|
610
|
-
: (resp?.result as Record<string, unknown>) ?? resp ?? {};
|
|
611
|
-
const version = typeof raw.version === 'string' ? raw.version : 'unknown';
|
|
612
|
-
const major = typeof raw.major === 'number' ? raw.major : 0;
|
|
613
|
-
const minor = typeof raw.minor === 'number' ? raw.minor : 0;
|
|
614
|
-
const patch = typeof raw.patch === 'number' ? raw.patch : 0;
|
|
615
|
-
const isUE56OrAbove =
|
|
616
|
-
typeof raw.isUE56OrAbove === 'boolean'
|
|
617
|
-
? raw.isUE56OrAbove
|
|
618
|
-
: (major > 5 || (major === 5 && minor >= 6));
|
|
619
|
-
return { version, major, minor, patch, isUE56OrAbove };
|
|
620
|
-
} catch (error) {
|
|
621
|
-
this.log.warn('getEngineVersion failed', error);
|
|
622
|
-
return {
|
|
623
|
-
version: 'unknown',
|
|
624
|
-
major: 0,
|
|
625
|
-
minor: 0,
|
|
626
|
-
patch: 0,
|
|
627
|
-
isUE56OrAbove: false
|
|
628
|
-
};
|
|
629
|
-
}
|
|
630
|
-
}
|
|
631
|
-
|
|
632
|
-
/** Query feature flags */
|
|
633
|
-
async getFeatureFlags(): Promise<{ subsystems: { unrealEditor: boolean; levelEditor: boolean; editorActor: boolean; } }> {
|
|
634
|
-
if (process.env.MOCK_UNREAL_CONNECTION === 'true') {
|
|
635
|
-
return {
|
|
636
|
-
subsystems: {
|
|
637
|
-
unrealEditor: true,
|
|
638
|
-
levelEditor: true,
|
|
639
|
-
editorActor: true
|
|
640
|
-
}
|
|
641
|
-
};
|
|
642
|
-
}
|
|
643
|
-
|
|
644
|
-
const bridge = this.getAutomationBridge();
|
|
645
|
-
try {
|
|
646
|
-
const resp = await bridge.sendAutomationRequest(
|
|
647
|
-
'system_control',
|
|
648
|
-
{ action: 'get_feature_flags' },
|
|
649
|
-
{ timeoutMs: ENGINE_QUERY_TIMEOUT_MS }
|
|
650
|
-
);
|
|
651
|
-
const raw = resp && typeof resp.result === 'object'
|
|
652
|
-
? (resp.result as Record<string, unknown>)
|
|
653
|
-
: (resp?.result as Record<string, unknown>) ?? resp ?? {};
|
|
654
|
-
const subs: SubsystemFlags = raw && typeof raw.subsystems === 'object'
|
|
655
|
-
? (raw.subsystems as SubsystemFlags)
|
|
656
|
-
: {};
|
|
657
|
-
return {
|
|
658
|
-
subsystems: {
|
|
659
|
-
unrealEditor: Boolean(subs.unrealEditor),
|
|
660
|
-
levelEditor: Boolean(subs.levelEditor),
|
|
661
|
-
editorActor: Boolean(subs.editorActor)
|
|
662
|
-
}
|
|
663
|
-
};
|
|
664
|
-
} catch (error) {
|
|
665
|
-
this.log.warn('getFeatureFlags failed', error);
|
|
666
|
-
return {
|
|
667
|
-
subsystems: {
|
|
668
|
-
unrealEditor: false,
|
|
669
|
-
levelEditor: false,
|
|
670
|
-
editorActor: false
|
|
671
|
-
}
|
|
672
|
-
};
|
|
673
|
-
}
|
|
674
|
-
}
|
|
675
|
-
|
|
676
|
-
/**
|
|
677
|
-
* SOLUTION 3: Command Throttling and Queueing
|
|
678
|
-
* Prevent rapid command execution that can overwhelm the engine
|
|
679
|
-
*/
|
|
680
|
-
private async executeThrottledCommand<T>(
|
|
681
|
-
command: () => Promise<T>,
|
|
682
|
-
priority: number = 5
|
|
683
|
-
): Promise<T> {
|
|
684
|
-
return this.commandQueue.execute(command, priority);
|
|
685
|
-
}
|
|
686
|
-
|
|
687
|
-
/**
|
|
688
|
-
* Helper delay function
|
|
689
|
-
*/
|
|
690
|
-
private delay(ms: number): Promise<void> {
|
|
691
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
692
|
-
}
|
|
693
|
-
}
|