unreal-engine-mcp-server 0.4.7 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.env.example +26 -0
- package/.env.production +38 -7
- package/.eslintrc.json +0 -54
- package/.eslintrc.override.json +8 -0
- package/.github/ISSUE_TEMPLATE/bug_report.yml +94 -0
- package/.github/ISSUE_TEMPLATE/config.yml +8 -0
- package/.github/ISSUE_TEMPLATE/feature_request.yml +56 -0
- package/.github/copilot-instructions.md +478 -45
- package/.github/dependabot.yml +19 -0
- package/.github/labeler.yml +24 -0
- package/.github/labels.yml +70 -0
- package/.github/pull_request_template.md +42 -0
- package/.github/release-drafter.yml +148 -0
- package/.github/workflows/auto-merge.yml +38 -0
- package/.github/workflows/ci.yml +38 -0
- package/.github/workflows/dependency-review.yml +17 -0
- package/.github/workflows/gemini-issue-triage.yml +172 -0
- package/.github/workflows/greetings.yml +23 -0
- package/.github/workflows/labeler.yml +16 -0
- package/.github/workflows/links.yml +80 -0
- package/.github/workflows/pr-size-labeler.yml +137 -0
- package/.github/workflows/publish-mcp.yml +12 -7
- package/.github/workflows/release-drafter.yml +23 -0
- package/.github/workflows/release.yml +112 -0
- package/.github/workflows/semantic-pull-request.yml +35 -0
- package/.github/workflows/smoke-test.yml +36 -0
- package/.github/workflows/stale.yml +28 -0
- package/CHANGELOG.md +267 -31
- package/CONTRIBUTING.md +140 -0
- package/README.md +166 -71
- package/claude_desktop_config_example.json +7 -6
- package/dist/automation/bridge.d.ts +50 -0
- package/dist/automation/bridge.js +452 -0
- package/dist/automation/connection-manager.d.ts +23 -0
- package/dist/automation/connection-manager.js +107 -0
- package/dist/automation/handshake.d.ts +11 -0
- package/dist/automation/handshake.js +89 -0
- package/dist/automation/index.d.ts +3 -0
- package/dist/automation/index.js +3 -0
- package/dist/automation/message-handler.d.ts +12 -0
- package/dist/automation/message-handler.js +149 -0
- package/dist/automation/request-tracker.d.ts +25 -0
- package/dist/automation/request-tracker.js +98 -0
- package/dist/automation/types.d.ts +130 -0
- package/dist/automation/types.js +2 -0
- package/dist/cli.js +32 -5
- package/dist/config.d.ts +27 -0
- package/dist/config.js +60 -0
- package/dist/constants.d.ts +12 -0
- package/dist/constants.js +12 -0
- package/dist/graphql/resolvers.d.ts +268 -0
- package/dist/graphql/resolvers.js +743 -0
- package/dist/graphql/schema.d.ts +5 -0
- package/dist/graphql/schema.js +437 -0
- package/dist/graphql/server.d.ts +26 -0
- package/dist/graphql/server.js +115 -0
- package/dist/graphql/types.d.ts +7 -0
- package/dist/graphql/types.js +2 -0
- package/dist/handlers/resource-handlers.d.ts +20 -0
- package/dist/handlers/resource-handlers.js +180 -0
- package/dist/index.d.ts +31 -18
- package/dist/index.js +119 -619
- package/dist/prompts/index.js +4 -4
- package/dist/resources/actors.d.ts +17 -12
- package/dist/resources/actors.js +56 -76
- package/dist/resources/assets.d.ts +6 -14
- package/dist/resources/assets.js +115 -147
- package/dist/resources/levels.d.ts +13 -13
- package/dist/resources/levels.js +25 -34
- package/dist/server/resource-registry.d.ts +20 -0
- package/dist/server/resource-registry.js +37 -0
- package/dist/server/tool-registry.d.ts +23 -0
- package/dist/server/tool-registry.js +322 -0
- package/dist/server-setup.d.ts +21 -0
- package/dist/server-setup.js +111 -0
- package/dist/services/health-monitor.d.ts +34 -0
- package/dist/services/health-monitor.js +105 -0
- package/dist/services/metrics-server.d.ts +11 -0
- package/dist/services/metrics-server.js +105 -0
- package/dist/tools/actors.d.ts +147 -9
- package/dist/tools/actors.js +350 -311
- package/dist/tools/animation.d.ts +135 -4
- package/dist/tools/animation.js +510 -411
- package/dist/tools/assets.d.ts +117 -19
- package/dist/tools/assets.js +259 -284
- package/dist/tools/audio.d.ts +102 -42
- package/dist/tools/audio.js +272 -685
- package/dist/tools/base-tool.d.ts +17 -0
- package/dist/tools/base-tool.js +46 -0
- package/dist/tools/behavior-tree.d.ts +94 -0
- package/dist/tools/behavior-tree.js +39 -0
- package/dist/tools/blueprint/helpers.d.ts +29 -0
- package/dist/tools/blueprint/helpers.js +182 -0
- package/dist/tools/blueprint.d.ts +228 -118
- package/dist/tools/blueprint.js +685 -832
- package/dist/tools/consolidated-tool-definitions.d.ts +5462 -1781
- package/dist/tools/consolidated-tool-definitions.js +829 -496
- package/dist/tools/consolidated-tool-handlers.d.ts +2 -1
- package/dist/tools/consolidated-tool-handlers.js +211 -1026
- package/dist/tools/debug.d.ts +143 -85
- package/dist/tools/debug.js +234 -180
- package/dist/tools/dynamic-handler-registry.d.ts +11 -0
- package/dist/tools/dynamic-handler-registry.js +101 -0
- package/dist/tools/editor.d.ts +139 -18
- package/dist/tools/editor.js +239 -244
- package/dist/tools/engine.d.ts +10 -4
- package/dist/tools/engine.js +13 -5
- package/dist/tools/environment.d.ts +36 -0
- package/dist/tools/environment.js +267 -0
- package/dist/tools/foliage.d.ts +105 -14
- package/dist/tools/foliage.js +219 -331
- package/dist/tools/handlers/actor-handlers.d.ts +3 -0
- package/dist/tools/handlers/actor-handlers.js +232 -0
- package/dist/tools/handlers/animation-handlers.d.ts +3 -0
- package/dist/tools/handlers/animation-handlers.js +185 -0
- package/dist/tools/handlers/argument-helper.d.ts +16 -0
- package/dist/tools/handlers/argument-helper.js +80 -0
- package/dist/tools/handlers/asset-handlers.d.ts +3 -0
- package/dist/tools/handlers/asset-handlers.js +496 -0
- package/dist/tools/handlers/audio-handlers.d.ts +3 -0
- package/dist/tools/handlers/audio-handlers.js +166 -0
- package/dist/tools/handlers/blueprint-handlers.d.ts +4 -0
- package/dist/tools/handlers/blueprint-handlers.js +358 -0
- package/dist/tools/handlers/common-handlers.d.ts +14 -0
- package/dist/tools/handlers/common-handlers.js +56 -0
- package/dist/tools/handlers/editor-handlers.d.ts +3 -0
- package/dist/tools/handlers/editor-handlers.js +119 -0
- package/dist/tools/handlers/effect-handlers.d.ts +3 -0
- package/dist/tools/handlers/effect-handlers.js +171 -0
- package/dist/tools/handlers/environment-handlers.d.ts +3 -0
- package/dist/tools/handlers/environment-handlers.js +170 -0
- package/dist/tools/handlers/graph-handlers.d.ts +3 -0
- package/dist/tools/handlers/graph-handlers.js +90 -0
- package/dist/tools/handlers/input-handlers.d.ts +3 -0
- package/dist/tools/handlers/input-handlers.js +21 -0
- package/dist/tools/handlers/inspect-handlers.d.ts +3 -0
- package/dist/tools/handlers/inspect-handlers.js +383 -0
- package/dist/tools/handlers/level-handlers.d.ts +3 -0
- package/dist/tools/handlers/level-handlers.js +237 -0
- package/dist/tools/handlers/lighting-handlers.d.ts +3 -0
- package/dist/tools/handlers/lighting-handlers.js +144 -0
- package/dist/tools/handlers/performance-handlers.d.ts +3 -0
- package/dist/tools/handlers/performance-handlers.js +130 -0
- package/dist/tools/handlers/pipeline-handlers.d.ts +3 -0
- package/dist/tools/handlers/pipeline-handlers.js +110 -0
- package/dist/tools/handlers/sequence-handlers.d.ts +3 -0
- package/dist/tools/handlers/sequence-handlers.js +376 -0
- package/dist/tools/handlers/system-handlers.d.ts +4 -0
- package/dist/tools/handlers/system-handlers.js +506 -0
- package/dist/tools/input.d.ts +19 -0
- package/dist/tools/input.js +89 -0
- package/dist/tools/introspection.d.ts +103 -40
- package/dist/tools/introspection.js +425 -568
- package/dist/tools/landscape.d.ts +97 -36
- package/dist/tools/landscape.js +280 -409
- package/dist/tools/level.d.ts +130 -10
- package/dist/tools/level.js +639 -675
- package/dist/tools/lighting.d.ts +77 -38
- package/dist/tools/lighting.js +441 -943
- package/dist/tools/logs.d.ts +3 -3
- package/dist/tools/logs.js +5 -57
- package/dist/tools/materials.d.ts +91 -24
- package/dist/tools/materials.js +190 -118
- package/dist/tools/niagara.d.ts +149 -39
- package/dist/tools/niagara.js +232 -182
- package/dist/tools/performance.d.ts +27 -12
- package/dist/tools/performance.js +204 -122
- package/dist/tools/physics.d.ts +32 -77
- package/dist/tools/physics.js +171 -582
- package/dist/tools/property-dictionary.d.ts +13 -0
- package/dist/tools/property-dictionary.js +82 -0
- package/dist/tools/sequence.d.ts +73 -48
- package/dist/tools/sequence.js +196 -748
- package/dist/tools/tool-definition-utils.d.ts +59 -0
- package/dist/tools/tool-definition-utils.js +35 -0
- package/dist/tools/ui.d.ts +66 -34
- package/dist/tools/ui.js +134 -214
- package/dist/types/env.d.ts +0 -3
- package/dist/types/env.js +0 -7
- package/dist/types/tool-interfaces.d.ts +898 -0
- package/dist/types/tool-interfaces.js +2 -0
- package/dist/types/tool-types.d.ts +183 -19
- package/dist/types/tool-types.js +0 -4
- package/dist/unreal-bridge.d.ts +24 -131
- package/dist/unreal-bridge.js +364 -1506
- package/dist/utils/command-validator.d.ts +9 -0
- package/dist/utils/command-validator.js +67 -0
- package/dist/utils/elicitation.d.ts +1 -1
- package/dist/utils/elicitation.js +12 -15
- package/dist/utils/error-handler.d.ts +2 -51
- package/dist/utils/error-handler.js +11 -87
- package/dist/utils/ini-reader.d.ts +3 -0
- package/dist/utils/ini-reader.js +69 -0
- package/dist/utils/logger.js +9 -6
- package/dist/utils/normalize.d.ts +3 -0
- package/dist/utils/normalize.js +56 -0
- package/dist/utils/response-factory.d.ts +7 -0
- package/dist/utils/response-factory.js +33 -0
- package/dist/utils/response-validator.d.ts +3 -24
- package/dist/utils/response-validator.js +130 -81
- package/dist/utils/result-helpers.d.ts +4 -5
- package/dist/utils/result-helpers.js +15 -16
- package/dist/utils/safe-json.js +5 -11
- package/dist/utils/unreal-command-queue.d.ts +24 -0
- package/dist/utils/unreal-command-queue.js +120 -0
- package/dist/utils/validation.d.ts +0 -40
- package/dist/utils/validation.js +1 -78
- package/dist/wasm/index.d.ts +70 -0
- package/dist/wasm/index.js +535 -0
- package/docs/GraphQL-API.md +888 -0
- package/docs/Migration-Guide-v0.5.0.md +692 -0
- package/docs/Roadmap.md +53 -0
- package/docs/WebAssembly-Integration.md +628 -0
- package/docs/editor-plugin-extension.md +370 -0
- package/docs/handler-mapping.md +242 -0
- package/docs/native-automation-progress.md +128 -0
- package/docs/testing-guide.md +423 -0
- package/mcp-config-example.json +6 -6
- package/package.json +60 -27
- package/plugins/McpAutomationBridge/Config/FilterPlugin.ini +8 -0
- package/plugins/McpAutomationBridge/McpAutomationBridge.uplugin +64 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/McpAutomationBridge.Build.cs +189 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.cpp +22 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeGlobals.h +30 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeHelpers.h +1983 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeModule.cpp +72 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSettings.cpp +46 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +581 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +2394 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetQueryHandlers.cpp +300 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AssetWorkflowHandlers.cpp +2807 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AudioHandlers.cpp +1087 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BehaviorTreeHandlers.cpp +488 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.cpp +643 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintCreationHandlers.h +31 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +1184 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +5652 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers_List.cpp +152 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ControlHandlers.cpp +2614 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_DebugHandlers.cpp +42 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EditorFunctionHandlers.cpp +1237 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +1701 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +2145 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_FoliageHandlers.cpp +954 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InputHandlers.cpp +209 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_InsightsHandlers.cpp +41 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LandscapeHandlers.cpp +1164 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LevelHandlers.cpp +762 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +634 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LogHandlers.cpp +136 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_MaterialGraphHandlers.cpp +494 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraGraphHandlers.cpp +278 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_NiagaraHandlers.cpp +625 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PerformanceHandlers.cpp +401 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PipelineHandlers.cpp +67 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +735 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_PropertyHandlers.cpp +2634 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_RenderHandlers.cpp +189 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.cpp +917 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SCSHandlers.h +39 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +2670 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequencerHandlers.cpp +519 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_TestHandlers.cpp +38 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_UiHandlers.cpp +668 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_WorldPartitionHandlers.cpp +346 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.cpp +1330 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpBridgeWebSocket.h +149 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +783 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSettings.h +115 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpAutomationBridgeSubsystem.h +796 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Public/McpConnectionManager.h +117 -0
- package/scripts/check-unreal-connection.mjs +19 -0
- package/scripts/clean-tmp.js +23 -0
- package/scripts/patch-wasm.js +26 -0
- package/scripts/run-all-tests.mjs +131 -0
- package/scripts/smoke-test.ts +94 -0
- package/scripts/sync-mcp-plugin.js +143 -0
- package/scripts/test-no-plugin-alternates.mjs +113 -0
- package/scripts/validate-server.js +46 -0
- package/scripts/verify-automation-bridge.js +200 -0
- package/server.json +57 -21
- package/src/automation/bridge.ts +558 -0
- package/src/automation/connection-manager.ts +130 -0
- package/src/automation/handshake.ts +99 -0
- package/src/automation/index.ts +2 -0
- package/src/automation/message-handler.ts +167 -0
- package/src/automation/request-tracker.ts +123 -0
- package/src/automation/types.ts +107 -0
- package/src/cli.ts +33 -6
- package/src/config.ts +73 -0
- package/src/constants.ts +12 -0
- package/src/graphql/resolvers.ts +1010 -0
- package/src/graphql/schema.ts +452 -0
- package/src/graphql/server.ts +154 -0
- package/src/graphql/types.ts +7 -0
- package/src/handlers/resource-handlers.ts +186 -0
- package/src/index.ts +152 -663
- package/src/prompts/index.ts +4 -4
- package/src/resources/actors.ts +58 -76
- package/src/resources/assets.ts +147 -134
- package/src/resources/levels.ts +28 -33
- package/src/server/resource-registry.ts +47 -0
- package/src/server/tool-registry.ts +354 -0
- package/src/server-setup.ts +148 -0
- package/src/services/health-monitor.ts +132 -0
- package/src/services/metrics-server.ts +142 -0
- package/src/tools/actors.ts +417 -322
- package/src/tools/animation.ts +671 -461
- package/src/tools/assets.ts +353 -289
- package/src/tools/audio.ts +323 -766
- package/src/tools/base-tool.ts +52 -0
- package/src/tools/behavior-tree.ts +45 -0
- package/src/tools/blueprint/helpers.ts +189 -0
- package/src/tools/blueprint.ts +787 -965
- package/src/tools/consolidated-tool-definitions.ts +993 -515
- package/src/tools/consolidated-tool-handlers.ts +272 -1139
- package/src/tools/debug.ts +292 -187
- package/src/tools/dynamic-handler-registry.ts +151 -0
- package/src/tools/editor.ts +309 -246
- package/src/tools/engine.ts +14 -3
- package/src/tools/environment.ts +287 -0
- package/src/tools/foliage.ts +314 -379
- package/src/tools/handlers/actor-handlers.ts +271 -0
- package/src/tools/handlers/animation-handlers.ts +237 -0
- package/src/tools/handlers/argument-helper.ts +142 -0
- package/src/tools/handlers/asset-handlers.ts +532 -0
- package/src/tools/handlers/audio-handlers.ts +194 -0
- package/src/tools/handlers/blueprint-handlers.ts +380 -0
- package/src/tools/handlers/common-handlers.ts +87 -0
- package/src/tools/handlers/editor-handlers.ts +123 -0
- package/src/tools/handlers/effect-handlers.ts +220 -0
- package/src/tools/handlers/environment-handlers.ts +183 -0
- package/src/tools/handlers/graph-handlers.ts +116 -0
- package/src/tools/handlers/input-handlers.ts +28 -0
- package/src/tools/handlers/inspect-handlers.ts +450 -0
- package/src/tools/handlers/level-handlers.ts +252 -0
- package/src/tools/handlers/lighting-handlers.ts +147 -0
- package/src/tools/handlers/performance-handlers.ts +132 -0
- package/src/tools/handlers/pipeline-handlers.ts +127 -0
- package/src/tools/handlers/sequence-handlers.ts +415 -0
- package/src/tools/handlers/system-handlers.ts +564 -0
- package/src/tools/input.ts +101 -0
- package/src/tools/introspection.ts +493 -584
- package/src/tools/landscape.ts +394 -489
- package/src/tools/level.ts +752 -694
- package/src/tools/lighting.ts +583 -984
- package/src/tools/logs.ts +9 -57
- package/src/tools/materials.ts +231 -121
- package/src/tools/niagara.ts +293 -168
- package/src/tools/performance.ts +320 -168
- package/src/tools/physics.ts +268 -613
- package/src/tools/property-dictionary.ts +98 -0
- package/src/tools/sequence.ts +255 -815
- package/src/tools/tool-definition-utils.ts +35 -0
- package/src/tools/ui.ts +207 -283
- package/src/types/env.ts +0 -10
- package/src/types/tool-interfaces.ts +250 -0
- package/src/types/tool-types.ts +243 -21
- package/src/unreal-bridge.ts +460 -1550
- package/src/utils/command-validator.ts +75 -0
- package/src/utils/elicitation.ts +10 -7
- package/src/utils/error-handler.ts +14 -90
- package/src/utils/ini-reader.ts +86 -0
- package/src/utils/logger.ts +8 -3
- package/src/utils/normalize.ts +60 -0
- package/src/utils/response-factory.ts +39 -0
- package/src/utils/response-validator.ts +176 -56
- package/src/utils/result-helpers.ts +21 -19
- package/src/utils/safe-json.ts +14 -11
- package/src/utils/unreal-command-queue.ts +152 -0
- package/src/utils/validation.ts +4 -1
- package/src/wasm/index.ts +838 -0
- package/test-server.mjs +100 -0
- package/tests/run-unreal-tool-tests.mjs +242 -14
- package/tests/test-animation.mjs +44 -0
- package/tests/test-asset-advanced.mjs +82 -0
- package/tests/test-asset-errors.mjs +35 -0
- package/tests/test-audio.mjs +219 -0
- package/tests/test-automation-timeouts.mjs +98 -0
- package/tests/test-behavior-tree.mjs +261 -0
- package/tests/test-blueprint-events.mjs +35 -0
- package/tests/test-blueprint-graph.mjs +79 -0
- package/tests/test-blueprint.mjs +577 -0
- package/tests/test-client-mode.mjs +86 -0
- package/tests/test-console-command.mjs +56 -0
- package/tests/test-control-actor.mjs +425 -0
- package/tests/test-control-editor.mjs +80 -0
- package/tests/test-extra-tools.mjs +38 -0
- package/tests/test-graphql.mjs +322 -0
- package/tests/test-inspect.mjs +72 -0
- package/tests/test-landscape.mjs +60 -0
- package/tests/test-manage-asset.mjs +438 -0
- package/tests/test-manage-level.mjs +70 -0
- package/tests/test-materials.mjs +356 -0
- package/tests/test-niagara.mjs +185 -0
- package/tests/test-no-inline-python.mjs +122 -0
- package/tests/test-plugin-handshake.mjs +82 -0
- package/tests/test-render.mjs +33 -0
- package/tests/test-runner.mjs +933 -0
- package/tests/test-search-assets.mjs +66 -0
- package/tests/test-sequence.mjs +68 -0
- package/tests/test-system.mjs +57 -0
- package/tests/test-wasm.mjs +193 -0
- package/tests/test-world-partition.mjs +215 -0
- package/tsconfig.json +3 -3
- package/wasm/Cargo.lock +363 -0
- package/wasm/Cargo.toml +42 -0
- package/wasm/LICENSE +21 -0
- package/wasm/README.md +253 -0
- package/wasm/src/dependency_resolver.rs +377 -0
- package/wasm/src/lib.rs +153 -0
- package/wasm/src/property_parser.rs +271 -0
- package/wasm/src/transform_math.rs +396 -0
- package/wasm/tests/integration.rs +109 -0
- package/.github/workflows/smithery-build.yml +0 -29
- package/dist/tools/build_environment_advanced.d.ts +0 -65
- package/dist/tools/build_environment_advanced.js +0 -633
- package/dist/tools/rc.d.ts +0 -110
- package/dist/tools/rc.js +0 -437
- package/dist/tools/visual.d.ts +0 -40
- package/dist/tools/visual.js +0 -282
- package/dist/utils/http.d.ts +0 -6
- package/dist/utils/http.js +0 -151
- package/dist/utils/python-output.d.ts +0 -18
- package/dist/utils/python-output.js +0 -290
- package/dist/utils/python.d.ts +0 -2
- package/dist/utils/python.js +0 -4
- package/dist/utils/stdio-redirect.d.ts +0 -2
- package/dist/utils/stdio-redirect.js +0 -20
- package/docs/unreal-tool-test-cases.md +0 -574
- package/smithery.yaml +0 -29
- package/src/tools/build_environment_advanced.ts +0 -732
- package/src/tools/rc.ts +0 -515
- package/src/tools/visual.ts +0 -281
- package/src/utils/http.ts +0 -187
- package/src/utils/python-output.ts +0 -351
- package/src/utils/python.ts +0 -3
- package/src/utils/stdio-redirect.ts +0 -18
package/dist/prompts/index.js
CHANGED
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
function clampChoice(value, choices,
|
|
1
|
+
function clampChoice(value, choices, defaultChoice) {
|
|
2
2
|
if (typeof value === 'string') {
|
|
3
3
|
const normalized = value.toLowerCase();
|
|
4
4
|
if (choices.includes(normalized)) {
|
|
5
5
|
return normalized;
|
|
6
6
|
}
|
|
7
7
|
}
|
|
8
|
-
return
|
|
8
|
+
return defaultChoice;
|
|
9
9
|
}
|
|
10
|
-
function coerceNumber(value,
|
|
10
|
+
function coerceNumber(value, defaultValue, min, max) {
|
|
11
11
|
const num = typeof value === 'number' ? value : Number(value);
|
|
12
12
|
if (!Number.isFinite(num)) {
|
|
13
|
-
return
|
|
13
|
+
return defaultValue;
|
|
14
14
|
}
|
|
15
15
|
if (min !== undefined && num < min) {
|
|
16
16
|
return min;
|
|
@@ -1,31 +1,36 @@
|
|
|
1
1
|
import { UnrealBridge } from '../unreal-bridge.js';
|
|
2
2
|
export declare class ActorResources {
|
|
3
3
|
private bridge;
|
|
4
|
+
private automationBridge?;
|
|
4
5
|
private cache;
|
|
5
6
|
private readonly CACHE_TTL_MS;
|
|
6
|
-
|
|
7
|
+
private automationBridgeAvailable;
|
|
8
|
+
constructor(bridge: UnrealBridge, automationBridge?: any | undefined);
|
|
7
9
|
private getFromCache;
|
|
8
10
|
private setCache;
|
|
9
11
|
listActors(): Promise<any>;
|
|
10
12
|
getActorByName(actorName: string): Promise<{
|
|
13
|
+
success: boolean;
|
|
14
|
+
error: string;
|
|
15
|
+
name?: undefined;
|
|
16
|
+
path?: undefined;
|
|
17
|
+
class?: undefined;
|
|
18
|
+
} | {
|
|
11
19
|
success: true;
|
|
12
20
|
name: string;
|
|
13
21
|
path: string | undefined;
|
|
14
22
|
class: string | undefined;
|
|
15
23
|
error?: undefined;
|
|
16
|
-
}
|
|
17
|
-
|
|
24
|
+
}>;
|
|
25
|
+
getActorTransform(actorPath: string): Promise<Record<string, any>>;
|
|
26
|
+
listActorComponents(actorPath: string): Promise<{
|
|
27
|
+
success: boolean;
|
|
18
28
|
error: string;
|
|
19
|
-
|
|
20
|
-
path?: undefined;
|
|
21
|
-
class?: undefined;
|
|
29
|
+
components?: undefined;
|
|
22
30
|
} | {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
path?: undefined;
|
|
27
|
-
class?: undefined;
|
|
31
|
+
success: true;
|
|
32
|
+
components: any;
|
|
33
|
+
error?: undefined;
|
|
28
34
|
}>;
|
|
29
|
-
getActorTransform(actorPath: string): Promise<any>;
|
|
30
35
|
}
|
|
31
36
|
//# sourceMappingURL=actors.d.ts.map
|
package/dist/resources/actors.js
CHANGED
|
@@ -1,10 +1,14 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { coerceNumber, coerceString } from '../utils/result-helpers.js';
|
|
2
2
|
export class ActorResources {
|
|
3
3
|
bridge;
|
|
4
|
+
automationBridge;
|
|
4
5
|
cache = new Map();
|
|
5
|
-
CACHE_TTL_MS = 5000;
|
|
6
|
-
|
|
6
|
+
CACHE_TTL_MS = 5000;
|
|
7
|
+
automationBridgeAvailable = false;
|
|
8
|
+
constructor(bridge, automationBridge) {
|
|
7
9
|
this.bridge = bridge;
|
|
10
|
+
this.automationBridge = automationBridge;
|
|
11
|
+
this.automationBridgeAvailable = Boolean(automationBridge && typeof automationBridge.sendAutomationRequest === 'function');
|
|
8
12
|
}
|
|
9
13
|
getFromCache(key) {
|
|
10
14
|
const entry = this.cache.get(key);
|
|
@@ -18,115 +22,91 @@ export class ActorResources {
|
|
|
18
22
|
this.cache.set(key, { data, timestamp: Date.now() });
|
|
19
23
|
}
|
|
20
24
|
async listActors() {
|
|
21
|
-
// Check cache first
|
|
22
25
|
const cached = this.getFromCache('listActors');
|
|
23
26
|
if (cached !== null) {
|
|
24
27
|
return cached;
|
|
25
28
|
}
|
|
26
|
-
// Use Python to get actors via EditorActorSubsystem
|
|
27
29
|
try {
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
actor_list.append({
|
|
37
|
-
'name': actor.get_name(),
|
|
38
|
-
'class': actor.get_class().get_name(),
|
|
39
|
-
'path': actor.get_path_name()
|
|
40
|
-
})
|
|
41
|
-
except Exception:
|
|
42
|
-
pass
|
|
43
|
-
print('RESULT:' + json.dumps({'success': True, 'count': len(actor_list), 'actors': actor_list}))
|
|
44
|
-
`.trim();
|
|
45
|
-
const response = await this.bridge.executePython(pythonCode);
|
|
46
|
-
const interpreted = interpretStandardResult(response, {
|
|
47
|
-
successMessage: 'Retrieved actor list',
|
|
48
|
-
failureMessage: 'Failed to retrieve actor list'
|
|
49
|
-
});
|
|
50
|
-
if (interpreted.success && Array.isArray(interpreted.payload.actors)) {
|
|
51
|
-
const actors = interpreted.payload.actors;
|
|
52
|
-
const count = coerceNumber(interpreted.payload.count) ?? actors.length;
|
|
53
|
-
const payload = {
|
|
54
|
-
success: true,
|
|
55
|
-
count,
|
|
56
|
-
actors
|
|
57
|
-
};
|
|
30
|
+
if (!this.automationBridgeAvailable) {
|
|
31
|
+
return { success: false, error: 'Automation bridge is not available. Please ensure Unreal Engine is running with the MCP Automation Bridge plugin.' };
|
|
32
|
+
}
|
|
33
|
+
const resp = await this.automationBridge.sendAutomationRequest('control_actor', { action: 'list' });
|
|
34
|
+
if (resp && resp.success !== false && Array.isArray((resp.result || resp).actors)) {
|
|
35
|
+
const actors = (resp.result || resp).actors;
|
|
36
|
+
const count = coerceNumber((resp.result || resp).count) ?? actors.length;
|
|
37
|
+
const payload = { success: true, count, actors };
|
|
58
38
|
this.setCache('listActors', payload);
|
|
59
39
|
return payload;
|
|
60
40
|
}
|
|
61
|
-
return {
|
|
62
|
-
success: false,
|
|
63
|
-
error: coerceString(interpreted.payload.error) ?? interpreted.error ?? 'Failed to parse actors list',
|
|
64
|
-
note: bestEffortInterpretedText(interpreted)
|
|
65
|
-
};
|
|
41
|
+
return { success: false, error: 'Failed to retrieve actor list from automation bridge' };
|
|
66
42
|
}
|
|
67
43
|
catch (err) {
|
|
68
44
|
return { success: false, error: `Failed to list actors: ${err}` };
|
|
69
45
|
}
|
|
70
46
|
}
|
|
71
47
|
async getActorByName(actorName) {
|
|
72
|
-
// GetActorOfClass expects a class, not a name. Use Python to find by name
|
|
73
48
|
try {
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
found = None
|
|
82
|
-
for actor in actors:
|
|
83
|
-
if actor and actor.get_name() == ${JSON.stringify(actorName)}:
|
|
84
|
-
found = {
|
|
85
|
-
'success': True,
|
|
86
|
-
'name': actor.get_name(),
|
|
87
|
-
'path': actor.get_path_name(),
|
|
88
|
-
'class': actor.get_class().get_name()
|
|
89
|
-
}
|
|
90
|
-
break
|
|
91
|
-
|
|
92
|
-
if not found:
|
|
93
|
-
found = {'success': False, 'error': f"Actor not found: {actorName}"}
|
|
94
|
-
|
|
95
|
-
print('RESULT:' + json.dumps(found))
|
|
96
|
-
`.trim();
|
|
97
|
-
const response = await this.bridge.executePython(pythonCode);
|
|
98
|
-
const interpreted = interpretStandardResult(response, {
|
|
99
|
-
successMessage: `Actor resolved: ${actorName}`,
|
|
100
|
-
failureMessage: `Actor not found: ${actorName}`
|
|
49
|
+
if (!this.automationBridgeAvailable) {
|
|
50
|
+
return { success: false, error: 'Automation bridge is not available' };
|
|
51
|
+
}
|
|
52
|
+
const resp = await this.automationBridge.sendAutomationRequest('control_actor', {
|
|
53
|
+
action: 'find_by_name',
|
|
54
|
+
name: actorName
|
|
101
55
|
});
|
|
102
|
-
if (
|
|
56
|
+
if (resp && resp.success !== false && resp.result) {
|
|
103
57
|
return {
|
|
104
58
|
success: true,
|
|
105
|
-
name: coerceString(
|
|
106
|
-
path: coerceString(
|
|
107
|
-
class: coerceString(
|
|
59
|
+
name: coerceString(resp.result.name) ?? actorName,
|
|
60
|
+
path: coerceString(resp.result.path),
|
|
61
|
+
class: coerceString(resp.result.class)
|
|
108
62
|
};
|
|
109
63
|
}
|
|
110
64
|
return {
|
|
111
65
|
success: false,
|
|
112
|
-
error:
|
|
66
|
+
error: `Actor not found: ${actorName}`
|
|
113
67
|
};
|
|
114
68
|
}
|
|
115
69
|
catch (err) {
|
|
116
|
-
return { error: `Failed to get actor: ${err}` };
|
|
70
|
+
return { success: false, error: `Failed to get actor: ${err}` };
|
|
117
71
|
}
|
|
118
72
|
}
|
|
119
73
|
async getActorTransform(actorPath) {
|
|
120
74
|
try {
|
|
121
|
-
|
|
75
|
+
return await this.bridge.getObjectProperty({
|
|
122
76
|
objectPath: actorPath,
|
|
123
77
|
propertyName: 'ActorTransform'
|
|
124
78
|
});
|
|
125
|
-
return res;
|
|
126
79
|
}
|
|
127
80
|
catch (err) {
|
|
128
81
|
return { error: `Failed to get transform: ${err}` };
|
|
129
82
|
}
|
|
130
83
|
}
|
|
84
|
+
async listActorComponents(actorPath) {
|
|
85
|
+
try {
|
|
86
|
+
if (!this.automationBridgeAvailable) {
|
|
87
|
+
return { success: false, error: 'Automation bridge is not available' };
|
|
88
|
+
}
|
|
89
|
+
const resp = await this.automationBridge.sendAutomationRequest('control_actor', {
|
|
90
|
+
action: 'list_components',
|
|
91
|
+
actor_path: actorPath
|
|
92
|
+
});
|
|
93
|
+
if (resp && resp.success !== false && Array.isArray(resp.result?.components)) {
|
|
94
|
+
return {
|
|
95
|
+
success: true,
|
|
96
|
+
components: resp.result.components
|
|
97
|
+
};
|
|
98
|
+
}
|
|
99
|
+
return {
|
|
100
|
+
success: false,
|
|
101
|
+
error: `Failed to resolve components for ${actorPath}`
|
|
102
|
+
};
|
|
103
|
+
}
|
|
104
|
+
catch (err) {
|
|
105
|
+
return {
|
|
106
|
+
success: false,
|
|
107
|
+
error: `Component lookup failed: ${err}`
|
|
108
|
+
};
|
|
109
|
+
}
|
|
110
|
+
}
|
|
131
111
|
}
|
|
132
112
|
//# sourceMappingURL=actors.js.map
|
|
@@ -1,24 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
constructor(bridge: UnrealBridge);
|
|
1
|
+
import { BaseTool } from '../tools/base-tool.js';
|
|
2
|
+
import { IAssetResources } from '../types/tool-interfaces.js';
|
|
3
|
+
export declare class AssetResources extends BaseTool implements IAssetResources {
|
|
5
4
|
private cache;
|
|
6
5
|
private get ttlMs();
|
|
7
6
|
private makeKey;
|
|
8
7
|
private normalizeDir;
|
|
8
|
+
clearCache(dir?: string): void;
|
|
9
|
+
invalidateAssetPaths(paths: string[]): void;
|
|
9
10
|
list(dir?: string, _recursive?: boolean, limit?: number): Promise<any>;
|
|
10
|
-
/**
|
|
11
|
-
* List assets with pagination support
|
|
12
|
-
* @param dir Directory to list assets from
|
|
13
|
-
* @param page Page number (0-based)
|
|
14
|
-
* @param pageSize Number of assets per page (max 50 to avoid socket failures)
|
|
15
|
-
*/
|
|
16
11
|
listPaged(dir?: string, page?: number, pageSize?: number, recursive?: boolean): Promise<any>;
|
|
17
|
-
/**
|
|
18
|
-
* Directory-based listing of immediate children using AssetRegistry.
|
|
19
|
-
* Returns both subfolders and assets at the given path.
|
|
20
|
-
*/
|
|
21
12
|
private listDirectoryOnly;
|
|
22
13
|
find(assetPath: string): Promise<boolean>;
|
|
14
|
+
private parentDirectory;
|
|
23
15
|
}
|
|
24
16
|
//# sourceMappingURL=assets.d.ts.map
|
package/dist/resources/assets.js
CHANGED
|
@@ -1,18 +1,11 @@
|
|
|
1
|
-
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
constructor(bridge) {
|
|
5
|
-
this.bridge = bridge;
|
|
6
|
-
}
|
|
7
|
-
// Simple in-memory cache for asset listing
|
|
1
|
+
import { BaseTool } from '../tools/base-tool.js';
|
|
2
|
+
import { coerceString } from '../utils/result-helpers.js';
|
|
3
|
+
export class AssetResources extends BaseTool {
|
|
8
4
|
cache = new Map();
|
|
9
5
|
get ttlMs() { return Number(process.env.ASSET_LIST_TTL_MS || 10000); }
|
|
10
6
|
makeKey(dir, recursive, page) {
|
|
11
7
|
return page !== undefined ? `${dir}::${recursive ? 1 : 0}::${page}` : `${dir}::${recursive ? 1 : 0}`;
|
|
12
8
|
}
|
|
13
|
-
// Normalize UE content paths:
|
|
14
|
-
// - Map '/Content' -> '/Game'
|
|
15
|
-
// - Ensure forward slashes
|
|
16
9
|
normalizeDir(dir) {
|
|
17
10
|
try {
|
|
18
11
|
if (!dir || typeof dir !== 'string')
|
|
@@ -23,9 +16,7 @@ export class AssetResources {
|
|
|
23
16
|
if (d.toLowerCase().startsWith('/content')) {
|
|
24
17
|
d = '/Game' + d.substring('/Content'.length);
|
|
25
18
|
}
|
|
26
|
-
// Collapse multiple slashes
|
|
27
19
|
d = d.replace(/\/+/g, '/');
|
|
28
|
-
// Remove trailing slash except root
|
|
29
20
|
if (d.length > 1)
|
|
30
21
|
d = d.replace(/\/$/, '');
|
|
31
22
|
return d;
|
|
@@ -34,45 +25,64 @@ export class AssetResources {
|
|
|
34
25
|
return '/Game';
|
|
35
26
|
}
|
|
36
27
|
}
|
|
28
|
+
clearCache(dir) {
|
|
29
|
+
if (!dir) {
|
|
30
|
+
this.cache.clear();
|
|
31
|
+
return;
|
|
32
|
+
}
|
|
33
|
+
const normalized = this.normalizeDir(dir);
|
|
34
|
+
for (const key of Array.from(this.cache.keys())) {
|
|
35
|
+
if (key.startsWith(`${normalized}::`)) {
|
|
36
|
+
this.cache.delete(key);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
invalidateAssetPaths(paths) {
|
|
41
|
+
if (!Array.isArray(paths) || paths.length === 0) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const dirs = new Set();
|
|
45
|
+
for (const rawPath of paths) {
|
|
46
|
+
if (typeof rawPath !== 'string' || rawPath.trim().length === 0) {
|
|
47
|
+
continue;
|
|
48
|
+
}
|
|
49
|
+
const normalized = this.normalizeDir(rawPath);
|
|
50
|
+
dirs.add(normalized);
|
|
51
|
+
const parent = this.parentDirectory(normalized);
|
|
52
|
+
if (parent) {
|
|
53
|
+
dirs.add(parent);
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
for (const dir of dirs) {
|
|
57
|
+
this.clearCache(dir);
|
|
58
|
+
}
|
|
59
|
+
}
|
|
37
60
|
async list(dir = '/Game', _recursive = false, limit = 50) {
|
|
38
|
-
|
|
39
|
-
// This prevents timeouts and makes navigation clearer
|
|
40
|
-
_recursive = false; // Force non-recursive
|
|
41
|
-
// Normalize directory first
|
|
61
|
+
_recursive = false;
|
|
42
62
|
dir = this.normalizeDir(dir);
|
|
43
|
-
// Cache fast-path
|
|
44
63
|
try {
|
|
45
64
|
const key = this.makeKey(dir, false);
|
|
46
65
|
const entry = this.cache.get(key);
|
|
47
66
|
const now = Date.now();
|
|
48
67
|
if (entry && (now - entry.timestamp) < this.ttlMs) {
|
|
49
|
-
return entry.data;
|
|
68
|
+
return { success: true, ...entry.data };
|
|
50
69
|
}
|
|
51
70
|
}
|
|
52
71
|
catch { }
|
|
53
|
-
// Check if bridge is connected
|
|
54
72
|
if (!this.bridge.isConnected) {
|
|
55
73
|
return {
|
|
74
|
+
success: false,
|
|
56
75
|
assets: [],
|
|
57
|
-
warning: 'Unreal Engine is not connected. Please ensure Unreal Engine is running with
|
|
76
|
+
warning: 'Unreal Engine is not connected. Please ensure Unreal Engine is running with the MCP server enabled.',
|
|
58
77
|
connectionStatus: 'disconnected'
|
|
59
78
|
};
|
|
60
79
|
}
|
|
61
|
-
|
|
62
|
-
return
|
|
63
|
-
// End of list method - all logic is now in listDirectoryOnly
|
|
80
|
+
const listed = await this.listDirectoryOnly(dir, false, limit);
|
|
81
|
+
return { ...listed, success: listed && listed.success === false ? false : true };
|
|
64
82
|
}
|
|
65
|
-
/**
|
|
66
|
-
* List assets with pagination support
|
|
67
|
-
* @param dir Directory to list assets from
|
|
68
|
-
* @param page Page number (0-based)
|
|
69
|
-
* @param pageSize Number of assets per page (max 50 to avoid socket failures)
|
|
70
|
-
*/
|
|
71
83
|
async listPaged(dir = '/Game', page = 0, pageSize = 30, recursive = false) {
|
|
72
|
-
// Ensure pageSize doesn't exceed safe limit
|
|
73
84
|
const safePageSize = Math.min(pageSize, 50);
|
|
74
85
|
const offset = page * safePageSize;
|
|
75
|
-
// Normalize directory and check cache for this specific page
|
|
76
86
|
dir = this.normalizeDir(dir);
|
|
77
87
|
const cacheKey = this.makeKey(dir, recursive, page);
|
|
78
88
|
const cached = this.cache.get(cacheKey);
|
|
@@ -89,10 +99,7 @@ export class AssetResources {
|
|
|
89
99
|
};
|
|
90
100
|
}
|
|
91
101
|
try {
|
|
92
|
-
// Use search API with pagination
|
|
93
|
-
// Use the same directory listing approach but with pagination
|
|
94
102
|
const allAssets = await this.listDirectoryOnly(dir, false, 1000);
|
|
95
|
-
// Paginate the results
|
|
96
103
|
const start = offset;
|
|
97
104
|
const end = offset + safePageSize;
|
|
98
105
|
const pagedAssets = allAssets.assets ? allAssets.assets.slice(start, end) : [];
|
|
@@ -118,136 +125,97 @@ export class AssetResources {
|
|
|
118
125
|
error: 'Failed to fetch page'
|
|
119
126
|
};
|
|
120
127
|
}
|
|
121
|
-
/**
|
|
122
|
-
* Directory-based listing of immediate children using AssetRegistry.
|
|
123
|
-
* Returns both subfolders and assets at the given path.
|
|
124
|
-
*/
|
|
125
128
|
async listDirectoryOnly(dir, _recursive, limit) {
|
|
126
|
-
// Always return only immediate children to avoid timeout and improve navigation
|
|
127
129
|
try {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
'files': len(assets),
|
|
164
|
-
'folders_list': folders_list,
|
|
165
|
-
'assets': assets
|
|
166
|
-
}))
|
|
167
|
-
except Exception as e:
|
|
168
|
-
print("RESULT:" + json.dumps({'success': False, 'error': str(e), 'path': _dir}))
|
|
169
|
-
`.trim();
|
|
170
|
-
const resp = await this.bridge.executePython(py);
|
|
171
|
-
const interpreted = interpretStandardResult(resp, {
|
|
172
|
-
successMessage: 'Directory contents retrieved',
|
|
173
|
-
failureMessage: 'Failed to list directory contents'
|
|
174
|
-
});
|
|
175
|
-
if (interpreted.success) {
|
|
176
|
-
const payload = interpreted.payload;
|
|
177
|
-
const foldersArr = Array.isArray(payload.folders_list)
|
|
178
|
-
? payload.folders_list.map((f) => ({
|
|
179
|
-
Name: coerceString(f?.n) ?? '',
|
|
180
|
-
Path: coerceString(f?.p) ?? '',
|
|
181
|
-
Class: 'Folder',
|
|
182
|
-
isFolder: true
|
|
183
|
-
}))
|
|
184
|
-
: [];
|
|
185
|
-
const assetsArr = Array.isArray(payload.assets)
|
|
186
|
-
? payload.assets.map((a) => ({
|
|
187
|
-
Name: coerceString(a?.n) ?? '',
|
|
188
|
-
Path: coerceString(a?.p) ?? '',
|
|
189
|
-
Class: coerceString(a?.c) ?? 'Asset',
|
|
190
|
-
isFolder: false
|
|
191
|
-
}))
|
|
192
|
-
: [];
|
|
193
|
-
const total = foldersArr.length + assetsArr.length;
|
|
194
|
-
const summary = {
|
|
195
|
-
total,
|
|
196
|
-
folders: foldersArr.length,
|
|
197
|
-
assets: assetsArr.length
|
|
198
|
-
};
|
|
199
|
-
const resolvedPath = coerceString(payload.path) ?? this.normalizeDir(dir);
|
|
200
|
-
return {
|
|
201
|
-
success: true,
|
|
202
|
-
path: resolvedPath,
|
|
203
|
-
summary,
|
|
204
|
-
foldersList: foldersArr,
|
|
205
|
-
assets: assetsArr,
|
|
206
|
-
count: total,
|
|
207
|
-
note: `Immediate children of ${resolvedPath}: ${foldersArr.length} folder(s), ${assetsArr.length} asset(s)`,
|
|
208
|
-
method: 'asset_registry_listing'
|
|
209
|
-
};
|
|
130
|
+
try {
|
|
131
|
+
const normalizedDir = this.normalizeDir(dir);
|
|
132
|
+
const response = await this.sendAutomationRequest('list', { directory: normalizedDir, limit, recursive: false }, { timeoutMs: 30000 });
|
|
133
|
+
if (response.success !== false && response.result) {
|
|
134
|
+
const payload = response.result;
|
|
135
|
+
const foldersArr = Array.isArray(payload.folders_list)
|
|
136
|
+
? payload.folders_list.map((f) => ({
|
|
137
|
+
Name: coerceString(f?.n ?? f?.Name ?? f?.name) ?? '',
|
|
138
|
+
Path: coerceString(f?.p ?? f?.Path ?? f?.path) ?? '',
|
|
139
|
+
Class: 'Folder',
|
|
140
|
+
isFolder: true
|
|
141
|
+
}))
|
|
142
|
+
: [];
|
|
143
|
+
const assetsArr = Array.isArray(payload.assets)
|
|
144
|
+
? payload.assets.map((a) => ({
|
|
145
|
+
Name: coerceString(a?.n ?? a?.Name ?? a?.name) ?? '',
|
|
146
|
+
Path: coerceString(a?.p ?? a?.Path ?? a?.path) ?? '',
|
|
147
|
+
Class: coerceString(a?.c ?? a?.Class ?? a?.class) ?? 'Object'
|
|
148
|
+
}))
|
|
149
|
+
: [];
|
|
150
|
+
const result = {
|
|
151
|
+
success: true,
|
|
152
|
+
assets: [...foldersArr, ...assetsArr],
|
|
153
|
+
count: foldersArr.length + assetsArr.length,
|
|
154
|
+
folders: foldersArr.length,
|
|
155
|
+
files: assetsArr.length,
|
|
156
|
+
path: normalizedDir,
|
|
157
|
+
recursive: false,
|
|
158
|
+
method: 'automation_bridge',
|
|
159
|
+
cached: false
|
|
160
|
+
};
|
|
161
|
+
const key = this.makeKey(dir, false);
|
|
162
|
+
this.cache.set(key, { timestamp: Date.now(), data: result });
|
|
163
|
+
return result;
|
|
164
|
+
}
|
|
210
165
|
}
|
|
166
|
+
catch { }
|
|
211
167
|
}
|
|
212
168
|
catch (err) {
|
|
213
|
-
|
|
169
|
+
const errorMessage = err?.message ? String(err.message) : 'Asset registry request failed';
|
|
170
|
+
console.warn('Engine asset listing failed:', errorMessage);
|
|
171
|
+
return {
|
|
172
|
+
success: false,
|
|
173
|
+
path: this.normalizeDir(dir),
|
|
174
|
+
summary: { total: 0, folders: 0, assets: 0 },
|
|
175
|
+
foldersList: [],
|
|
176
|
+
assets: [],
|
|
177
|
+
error: errorMessage,
|
|
178
|
+
warning: 'AssetRegistry query failed. Ensure the MCP Automation Bridge is connected.',
|
|
179
|
+
transport: 'automation_bridge',
|
|
180
|
+
method: 'asset_registry_alternate'
|
|
181
|
+
};
|
|
214
182
|
}
|
|
215
|
-
// Fallback: return empty with explanation
|
|
216
183
|
return {
|
|
217
|
-
success:
|
|
184
|
+
success: false,
|
|
218
185
|
path: this.normalizeDir(dir),
|
|
219
186
|
summary: { total: 0, folders: 0, assets: 0 },
|
|
220
187
|
foldersList: [],
|
|
221
188
|
assets: [],
|
|
222
|
-
|
|
223
|
-
|
|
189
|
+
error: 'Asset registry returned no payload.',
|
|
190
|
+
warning: 'No items returned from AssetRegistry request.',
|
|
191
|
+
transport: 'automation_bridge',
|
|
192
|
+
method: 'asset_registry_empty'
|
|
224
193
|
};
|
|
225
194
|
}
|
|
226
195
|
async find(assetPath) {
|
|
227
|
-
// Guard against invalid paths (trailing slash, empty, whitespace)
|
|
228
196
|
if (!assetPath || typeof assetPath !== 'string' || assetPath.trim() === '' || assetPath.endsWith('/')) {
|
|
229
197
|
return false;
|
|
230
198
|
}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
return
|
|
199
|
+
try {
|
|
200
|
+
const normalizedPath = this.normalizeDir(assetPath);
|
|
201
|
+
const response = await this.sendAutomationRequest('asset_exists', { asset_path: normalizedPath });
|
|
202
|
+
return response?.success !== false && response?.result?.exists === true;
|
|
203
|
+
}
|
|
204
|
+
catch {
|
|
205
|
+
return false;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
parentDirectory(path) {
|
|
209
|
+
if (!path || typeof path !== 'string') {
|
|
210
|
+
return null;
|
|
211
|
+
}
|
|
212
|
+
const normalized = this.normalizeDir(path);
|
|
213
|
+
const lastSlash = normalized.lastIndexOf('/');
|
|
214
|
+
if (lastSlash <= 0) {
|
|
215
|
+
return normalized === '/' ? '/' : null;
|
|
216
|
+
}
|
|
217
|
+
const parent = normalized.substring(0, lastSlash);
|
|
218
|
+
return parent.length > 0 ? parent : '/';
|
|
251
219
|
}
|
|
252
220
|
}
|
|
253
221
|
//# sourceMappingURL=assets.js.map
|