unreal-engine-mcp-server 0.5.0 → 0.5.2
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 +1 -1
- package/.github/release-drafter-config.yml +51 -0
- package/.github/workflows/greetings.yml +5 -1
- package/.github/workflows/labeler.yml +2 -1
- package/.github/workflows/publish-mcp.yml +2 -4
- package/.github/workflows/release-drafter.yml +3 -2
- package/.github/workflows/release.yml +3 -3
- package/CHANGELOG.md +109 -0
- package/CONTRIBUTING.md +1 -1
- package/GEMINI.md +115 -0
- package/Public/Plugin_setup_guide.mp4 +0 -0
- package/README.md +166 -200
- package/dist/automation/bridge.d.ts +1 -2
- package/dist/automation/bridge.js +24 -23
- package/dist/automation/connection-manager.d.ts +1 -0
- package/dist/automation/connection-manager.js +10 -0
- package/dist/automation/message-handler.js +5 -4
- package/dist/automation/request-tracker.d.ts +4 -0
- package/dist/automation/request-tracker.js +11 -3
- package/dist/config.d.ts +0 -1
- package/dist/config.js +0 -1
- package/dist/constants.d.ts +4 -0
- package/dist/constants.js +4 -0
- package/dist/graphql/loaders.d.ts +64 -0
- package/dist/graphql/loaders.js +117 -0
- package/dist/graphql/resolvers.d.ts +3 -3
- package/dist/graphql/resolvers.js +33 -30
- package/dist/graphql/server.js +3 -1
- package/dist/graphql/types.d.ts +2 -0
- package/dist/index.d.ts +2 -0
- package/dist/index.js +13 -2
- package/dist/server-setup.d.ts +0 -1
- package/dist/server-setup.js +0 -40
- package/dist/tools/actors.d.ts +58 -24
- package/dist/tools/actors.js +22 -6
- package/dist/tools/assets.d.ts +19 -71
- package/dist/tools/assets.js +28 -22
- package/dist/tools/base-tool.d.ts +4 -4
- package/dist/tools/base-tool.js +1 -1
- package/dist/tools/blueprint.d.ts +45 -61
- package/dist/tools/blueprint.js +43 -14
- package/dist/tools/consolidated-tool-definitions.js +2 -1
- package/dist/tools/consolidated-tool-handlers.js +96 -110
- package/dist/tools/dynamic-handler-registry.d.ts +11 -9
- package/dist/tools/dynamic-handler-registry.js +17 -95
- package/dist/tools/editor.d.ts +19 -193
- package/dist/tools/editor.js +11 -2
- package/dist/tools/environment.d.ts +8 -14
- package/dist/tools/foliage.d.ts +18 -143
- package/dist/tools/foliage.js +4 -2
- package/dist/tools/handlers/actor-handlers.d.ts +1 -1
- package/dist/tools/handlers/actor-handlers.js +14 -13
- package/dist/tools/handlers/asset-handlers.js +454 -454
- package/dist/tools/handlers/sequence-handlers.d.ts +1 -1
- package/dist/tools/handlers/sequence-handlers.js +24 -13
- package/dist/tools/introspection.d.ts +1 -1
- package/dist/tools/introspection.js +1 -1
- package/dist/tools/landscape.d.ts +16 -116
- package/dist/tools/landscape.js +7 -3
- package/dist/tools/level.d.ts +22 -103
- package/dist/tools/level.js +26 -18
- package/dist/tools/lighting.d.ts +54 -7
- package/dist/tools/lighting.js +9 -5
- package/dist/tools/materials.d.ts +1 -1
- package/dist/tools/materials.js +5 -1
- package/dist/tools/niagara.js +37 -2
- package/dist/tools/performance.d.ts +0 -1
- package/dist/tools/performance.js +0 -1
- package/dist/tools/physics.js +5 -1
- package/dist/tools/sequence.d.ts +24 -24
- package/dist/tools/sequence.js +13 -0
- package/dist/tools/ui.d.ts +0 -2
- package/dist/types/automation-responses.d.ts +115 -0
- package/dist/types/automation-responses.js +2 -0
- package/dist/types/responses.d.ts +249 -0
- package/dist/types/responses.js +2 -0
- package/dist/types/tool-interfaces.d.ts +135 -135
- package/dist/types/tool-types.d.ts +2 -0
- package/dist/unreal-bridge.js +4 -4
- package/dist/utils/command-validator.js +7 -5
- package/dist/utils/error-handler.d.ts +24 -2
- package/dist/utils/error-handler.js +58 -23
- package/dist/utils/normalize.d.ts +7 -4
- package/dist/utils/normalize.js +12 -10
- package/dist/utils/path-security.d.ts +2 -0
- package/dist/utils/path-security.js +24 -0
- package/dist/utils/response-factory.d.ts +4 -4
- package/dist/utils/response-factory.js +15 -21
- package/dist/utils/response-validator.js +88 -73
- package/dist/utils/unreal-command-queue.d.ts +2 -0
- package/dist/utils/unreal-command-queue.js +8 -1
- package/docs/Migration-Guide-v0.5.0.md +1 -9
- package/docs/handler-mapping.md +4 -2
- package/docs/testing-guide.md +2 -2
- package/package.json +12 -6
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridgeSubsystem.cpp +298 -33
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_AnimationHandlers.cpp +7 -8
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintGraphHandlers.cpp +229 -319
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_BlueprintHandlers.cpp +98 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EffectHandlers.cpp +24 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_EnvironmentHandlers.cpp +96 -0
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_LightingHandlers.cpp +52 -5
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_ProcessRequest.cpp +5 -268
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpAutomationBridge_SequenceHandlers.cpp +57 -2
- package/plugins/McpAutomationBridge/Source/McpAutomationBridge/Private/McpConnectionManager.cpp +0 -1
- package/scripts/run-all-tests.mjs +25 -20
- package/server.json +3 -2
- package/src/automation/bridge.ts +27 -25
- package/src/automation/connection-manager.ts +18 -0
- package/src/automation/message-handler.ts +33 -8
- package/src/automation/request-tracker.ts +39 -7
- package/src/config.ts +1 -1
- package/src/constants.ts +7 -0
- package/src/graphql/loaders.ts +244 -0
- package/src/graphql/resolvers.ts +47 -49
- package/src/graphql/server.ts +3 -1
- package/src/graphql/types.ts +3 -0
- package/src/index.ts +15 -2
- package/src/resources/assets.ts +5 -4
- package/src/server/tool-registry.ts +3 -3
- package/src/server-setup.ts +3 -37
- package/src/tools/actors.ts +77 -44
- package/src/tools/animation.ts +1 -0
- package/src/tools/assets.ts +76 -65
- package/src/tools/base-tool.ts +3 -3
- package/src/tools/blueprint.ts +170 -104
- package/src/tools/consolidated-tool-definitions.ts +2 -1
- package/src/tools/consolidated-tool-handlers.ts +129 -150
- package/src/tools/dynamic-handler-registry.ts +22 -140
- package/src/tools/editor.ts +43 -29
- package/src/tools/environment.ts +21 -27
- package/src/tools/foliage.ts +28 -25
- package/src/tools/handlers/actor-handlers.ts +16 -17
- package/src/tools/handlers/asset-handlers.ts +484 -484
- package/src/tools/handlers/sequence-handlers.ts +85 -62
- package/src/tools/introspection.ts +7 -7
- package/src/tools/landscape.ts +34 -28
- package/src/tools/level.ts +100 -80
- package/src/tools/lighting.ts +25 -20
- package/src/tools/materials.ts +9 -3
- package/src/tools/niagara.ts +44 -2
- package/src/tools/performance.ts +1 -2
- package/src/tools/physics.ts +7 -1
- package/src/tools/sequence.ts +42 -26
- package/src/tools/ui.ts +1 -3
- package/src/types/automation-responses.ts +119 -0
- package/src/types/responses.ts +355 -0
- package/src/types/tool-interfaces.ts +135 -135
- package/src/types/tool-types.ts +4 -0
- package/src/unreal-bridge.ts +71 -26
- package/src/utils/command-validator.ts +47 -5
- package/src/utils/error-handler.ts +128 -45
- package/src/utils/normalize.test.ts +162 -0
- package/src/utils/normalize.ts +38 -16
- package/src/utils/path-security.ts +43 -0
- package/src/utils/response-factory.ts +29 -24
- package/src/utils/response-validator.ts +103 -87
- package/src/utils/safe-json.test.ts +90 -0
- package/src/utils/unreal-command-queue.ts +13 -1
- package/src/utils/validation.test.ts +184 -0
- package/tests/test-animation.mjs +358 -33
- package/tests/test-asset-graph.mjs +311 -0
- package/tests/test-audio.mjs +314 -116
- package/tests/test-behavior-tree.mjs +327 -144
- package/tests/test-blueprint-graph.mjs +343 -12
- package/tests/test-control-editor.mjs +85 -53
- package/tests/test-graphql.mjs +58 -8
- package/tests/test-input.mjs +349 -0
- package/tests/test-inspect.mjs +291 -61
- package/tests/test-landscape.mjs +304 -48
- package/tests/test-lighting.mjs +428 -0
- package/tests/test-manage-level.mjs +70 -51
- package/tests/test-performance.mjs +539 -0
- package/tests/test-sequence.mjs +82 -46
- package/tests/test-system.mjs +72 -33
- package/tests/test-wasm.mjs +98 -8
- package/vitest.config.ts +35 -0
- package/.github/release-drafter.yml +0 -148
- package/dist/prompts/index.d.ts +0 -21
- package/dist/prompts/index.js +0 -217
- package/dist/tools/blueprint/helpers.d.ts +0 -29
- package/dist/tools/blueprint/helpers.js +0 -182
- package/src/prompts/index.ts +0 -249
- package/src/tools/blueprint/helpers.ts +0 -189
- package/tests/test-blueprint-events.mjs +0 -35
- package/tests/test-extra-tools.mjs +0 -38
- package/tests/test-render.mjs +0 -33
- package/tests/test-search-assets.mjs +0 -66
package/dist/tools/level.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { BaseTool } from './base-tool.js';
|
|
2
|
+
import { sanitizePath } from '../utils/path-security.js';
|
|
3
|
+
import { DEFAULT_OPERATION_TIMEOUT_MS, DEFAULT_ASSET_OP_TIMEOUT_MS, LONG_RUNNING_OP_TIMEOUT_MS } from '../constants.js';
|
|
2
4
|
export class LevelTools extends BaseTool {
|
|
3
5
|
managedLevels = new Map();
|
|
4
6
|
listCache;
|
|
@@ -18,6 +20,12 @@ export class LevelTools extends BaseTool {
|
|
|
18
20
|
if (!formatted.startsWith('/Game/')) {
|
|
19
21
|
formatted = `/Game/${formatted.replace(/^\/+/, '')}`;
|
|
20
22
|
}
|
|
23
|
+
try {
|
|
24
|
+
formatted = sanitizePath(formatted);
|
|
25
|
+
}
|
|
26
|
+
catch (e) {
|
|
27
|
+
throw new Error(`Security validation failed for level path: ${e instanceof Error ? e.message : String(e)}`);
|
|
28
|
+
}
|
|
21
29
|
formatted = formatted.replace(/\.umap$/i, '');
|
|
22
30
|
if (formatted.endsWith('/')) {
|
|
23
31
|
formatted = formatted.slice(0, -1);
|
|
@@ -180,6 +188,7 @@ export class LevelTools extends BaseTool {
|
|
|
180
188
|
const managedOnly = managed.levels.filter(m => !ueLevels.some(u => u.path === m.path));
|
|
181
189
|
const finalLevels = [...ueLevels, ...managedOnly];
|
|
182
190
|
const result = {
|
|
191
|
+
...response,
|
|
183
192
|
success: true,
|
|
184
193
|
message: 'Levels listed from Unreal Engine',
|
|
185
194
|
levels: finalLevels,
|
|
@@ -190,7 +199,6 @@ export class LevelTools extends BaseTool {
|
|
|
190
199
|
levels: finalLevels,
|
|
191
200
|
count: finalLevels.length
|
|
192
201
|
},
|
|
193
|
-
...response,
|
|
194
202
|
managedLevels: managed.levels,
|
|
195
203
|
managedLevelCount: managed.count
|
|
196
204
|
};
|
|
@@ -234,7 +242,7 @@ export class LevelTools extends BaseTool {
|
|
|
234
242
|
action: 'export_level',
|
|
235
243
|
levelPath: resolved,
|
|
236
244
|
exportPath: params.exportPath
|
|
237
|
-
}, { timeoutMs: params.timeoutMs ??
|
|
245
|
+
}, { timeoutMs: params.timeoutMs ?? LONG_RUNNING_OP_TIMEOUT_MS });
|
|
238
246
|
if (res?.success === false) {
|
|
239
247
|
return {
|
|
240
248
|
success: false,
|
|
@@ -253,7 +261,7 @@ export class LevelTools extends BaseTool {
|
|
|
253
261
|
};
|
|
254
262
|
}
|
|
255
263
|
catch (e) {
|
|
256
|
-
return { success: false, error: `Export failed: ${e.message}` };
|
|
264
|
+
return { success: false, error: `Export failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
257
265
|
}
|
|
258
266
|
}
|
|
259
267
|
async importLevel(params) {
|
|
@@ -265,7 +273,7 @@ export class LevelTools extends BaseTool {
|
|
|
265
273
|
action: 'import_level',
|
|
266
274
|
packagePath: params.packagePath,
|
|
267
275
|
destinationPath: destination.path
|
|
268
|
-
}, { timeoutMs: params.timeoutMs ??
|
|
276
|
+
}, { timeoutMs: params.timeoutMs ?? LONG_RUNNING_OP_TIMEOUT_MS });
|
|
269
277
|
if (res?.success === false) {
|
|
270
278
|
return {
|
|
271
279
|
success: false,
|
|
@@ -284,7 +292,7 @@ export class LevelTools extends BaseTool {
|
|
|
284
292
|
};
|
|
285
293
|
}
|
|
286
294
|
catch (e) {
|
|
287
|
-
return { success: false, error: `Import failed: ${e.message}` };
|
|
295
|
+
return { success: false, error: `Import failed: ${e instanceof Error ? e.message : String(e)}` };
|
|
288
296
|
}
|
|
289
297
|
}
|
|
290
298
|
async saveLevelAs(params) {
|
|
@@ -295,7 +303,7 @@ export class LevelTools extends BaseTool {
|
|
|
295
303
|
action: 'save_level_as',
|
|
296
304
|
savePath: target.path
|
|
297
305
|
}, {
|
|
298
|
-
timeoutMs:
|
|
306
|
+
timeoutMs: DEFAULT_ASSET_OP_TIMEOUT_MS
|
|
299
307
|
});
|
|
300
308
|
if (response.success === false) {
|
|
301
309
|
return { success: false, error: response.error || response.message || 'Failed to save level as' };
|
|
@@ -382,7 +390,7 @@ export class LevelTools extends BaseTool {
|
|
|
382
390
|
const response = await this.sendAutomationRequest('manage_level', {
|
|
383
391
|
action: 'load',
|
|
384
392
|
levelPath: params.levelPath
|
|
385
|
-
}, { timeoutMs:
|
|
393
|
+
}, { timeoutMs: DEFAULT_OPERATION_TIMEOUT_MS });
|
|
386
394
|
if (response.success) {
|
|
387
395
|
this.setCurrentLevel(normalizedPath);
|
|
388
396
|
this.mutateRecord(normalizedPath, {
|
|
@@ -391,11 +399,11 @@ export class LevelTools extends BaseTool {
|
|
|
391
399
|
visible: true
|
|
392
400
|
});
|
|
393
401
|
return {
|
|
402
|
+
...response,
|
|
394
403
|
success: true,
|
|
395
404
|
message: `Level loaded: ${params.levelPath}`,
|
|
396
405
|
level: normalizedPath,
|
|
397
|
-
streaming: false
|
|
398
|
-
...response
|
|
406
|
+
streaming: false
|
|
399
407
|
};
|
|
400
408
|
}
|
|
401
409
|
}
|
|
@@ -461,15 +469,15 @@ export class LevelTools extends BaseTool {
|
|
|
461
469
|
payload.savePath = params.savePath;
|
|
462
470
|
}
|
|
463
471
|
const response = await this.sendAutomationRequest('manage_level', payload, {
|
|
464
|
-
timeoutMs:
|
|
472
|
+
timeoutMs: DEFAULT_ASSET_OP_TIMEOUT_MS
|
|
465
473
|
});
|
|
466
474
|
if (response.success === false) {
|
|
467
475
|
return { success: false, error: response.error || response.message || 'Failed to save level' };
|
|
468
476
|
}
|
|
469
477
|
const result = {
|
|
478
|
+
...response,
|
|
470
479
|
success: true,
|
|
471
|
-
message: response.message || 'Level saved'
|
|
472
|
-
...response
|
|
480
|
+
message: response.message || 'Level saved'
|
|
473
481
|
};
|
|
474
482
|
if (response.skipped) {
|
|
475
483
|
result.skipped = response.skipped;
|
|
@@ -498,7 +506,7 @@ export class LevelTools extends BaseTool {
|
|
|
498
506
|
levelPath: fullPath,
|
|
499
507
|
useWorldPartition: isPartitioned
|
|
500
508
|
}, {
|
|
501
|
-
timeoutMs:
|
|
509
|
+
timeoutMs: DEFAULT_ASSET_OP_TIMEOUT_MS
|
|
502
510
|
});
|
|
503
511
|
if (response.success === false) {
|
|
504
512
|
return {
|
|
@@ -509,13 +517,13 @@ export class LevelTools extends BaseTool {
|
|
|
509
517
|
};
|
|
510
518
|
}
|
|
511
519
|
const result = {
|
|
520
|
+
...response,
|
|
512
521
|
success: true,
|
|
513
522
|
message: response.message || 'Level created',
|
|
514
523
|
path: response.levelPath || fullPath,
|
|
515
524
|
packagePath: response.packagePath ?? fullPath,
|
|
516
525
|
objectPath: response.objectPath,
|
|
517
|
-
partitioned: isPartitioned
|
|
518
|
-
...response
|
|
526
|
+
partitioned: isPartitioned
|
|
519
527
|
};
|
|
520
528
|
if (response.warnings) {
|
|
521
529
|
result.warnings = response.warnings;
|
|
@@ -551,7 +559,7 @@ export class LevelTools extends BaseTool {
|
|
|
551
559
|
subLevelPath: sub,
|
|
552
560
|
parentPath: parent,
|
|
553
561
|
streamingMethod: params.streamingMethod
|
|
554
|
-
}, { timeoutMs:
|
|
562
|
+
}, { timeoutMs: DEFAULT_OPERATION_TIMEOUT_MS });
|
|
555
563
|
if (response && (response.error === 'PACKAGE_NOT_FOUND' || response.error === 'ADD_FAILED') && !sub.endsWith('.umap')) {
|
|
556
564
|
const subWithExt = sub + '.umap';
|
|
557
565
|
response = await this.sendAutomationRequest('manage_level', {
|
|
@@ -560,7 +568,7 @@ export class LevelTools extends BaseTool {
|
|
|
560
568
|
subLevelPath: subWithExt,
|
|
561
569
|
parentPath: parent,
|
|
562
570
|
streamingMethod: params.streamingMethod
|
|
563
|
-
}, { timeoutMs:
|
|
571
|
+
}, { timeoutMs: DEFAULT_OPERATION_TIMEOUT_MS });
|
|
564
572
|
}
|
|
565
573
|
if (response.success) {
|
|
566
574
|
this.ensureRecord(sub, { loaded: true, visible: true, streaming: true });
|
|
@@ -608,7 +616,7 @@ export class LevelTools extends BaseTool {
|
|
|
608
616
|
shouldBeLoaded: params.shouldBeLoaded,
|
|
609
617
|
shouldBeVisible
|
|
610
618
|
}, {
|
|
611
|
-
timeoutMs:
|
|
619
|
+
timeoutMs: DEFAULT_ASSET_OP_TIMEOUT_MS
|
|
612
620
|
});
|
|
613
621
|
if (response.success === false) {
|
|
614
622
|
const errorCode = typeof response.error === 'string' ? response.error : '';
|
package/dist/tools/lighting.d.ts
CHANGED
|
@@ -19,8 +19,16 @@ export declare class LightingTools {
|
|
|
19
19
|
castShadows?: boolean;
|
|
20
20
|
temperature?: number;
|
|
21
21
|
useAsAtmosphereSunLight?: boolean;
|
|
22
|
-
properties?: Record<string,
|
|
23
|
-
}): Promise<
|
|
22
|
+
properties?: Record<string, unknown>;
|
|
23
|
+
}): Promise<{
|
|
24
|
+
success: boolean;
|
|
25
|
+
message: string;
|
|
26
|
+
error?: undefined;
|
|
27
|
+
} | {
|
|
28
|
+
success: boolean;
|
|
29
|
+
error: string;
|
|
30
|
+
message?: undefined;
|
|
31
|
+
}>;
|
|
24
32
|
createPointLight(params: {
|
|
25
33
|
name: string;
|
|
26
34
|
location?: [number, number, number];
|
|
@@ -34,7 +42,15 @@ export declare class LightingTools {
|
|
|
34
42
|
yaw: number;
|
|
35
43
|
roll: number;
|
|
36
44
|
};
|
|
37
|
-
}): Promise<
|
|
45
|
+
}): Promise<{
|
|
46
|
+
success: boolean;
|
|
47
|
+
message: string;
|
|
48
|
+
error?: undefined;
|
|
49
|
+
} | {
|
|
50
|
+
success: boolean;
|
|
51
|
+
error: string;
|
|
52
|
+
message?: undefined;
|
|
53
|
+
}>;
|
|
38
54
|
createSpotLight(params: {
|
|
39
55
|
name: string;
|
|
40
56
|
location: [number, number, number];
|
|
@@ -49,7 +65,15 @@ export declare class LightingTools {
|
|
|
49
65
|
radius?: number;
|
|
50
66
|
color?: [number, number, number];
|
|
51
67
|
castShadows?: boolean;
|
|
52
|
-
}): Promise<
|
|
68
|
+
}): Promise<{
|
|
69
|
+
success: boolean;
|
|
70
|
+
message: string;
|
|
71
|
+
error?: undefined;
|
|
72
|
+
} | {
|
|
73
|
+
success: boolean;
|
|
74
|
+
error: string;
|
|
75
|
+
message?: undefined;
|
|
76
|
+
}>;
|
|
53
77
|
createRectLight(params: {
|
|
54
78
|
name: string;
|
|
55
79
|
location: [number, number, number];
|
|
@@ -63,7 +87,15 @@ export declare class LightingTools {
|
|
|
63
87
|
intensity?: number;
|
|
64
88
|
color?: [number, number, number];
|
|
65
89
|
castShadows?: boolean;
|
|
66
|
-
}): Promise<
|
|
90
|
+
}): Promise<{
|
|
91
|
+
success: boolean;
|
|
92
|
+
message: string;
|
|
93
|
+
error?: undefined;
|
|
94
|
+
} | {
|
|
95
|
+
success: boolean;
|
|
96
|
+
error: string;
|
|
97
|
+
message?: undefined;
|
|
98
|
+
}>;
|
|
67
99
|
createDynamicLight(params: {
|
|
68
100
|
name?: string;
|
|
69
101
|
lightType?: 'Point' | 'Spot' | 'Directional' | 'Rect' | string;
|
|
@@ -84,7 +116,15 @@ export declare class LightingTools {
|
|
|
84
116
|
enabled?: boolean;
|
|
85
117
|
frequency?: number;
|
|
86
118
|
};
|
|
87
|
-
}): Promise<
|
|
119
|
+
}): Promise<{
|
|
120
|
+
success: boolean;
|
|
121
|
+
message: string;
|
|
122
|
+
error?: undefined;
|
|
123
|
+
} | {
|
|
124
|
+
success: boolean;
|
|
125
|
+
error: string;
|
|
126
|
+
message?: undefined;
|
|
127
|
+
}>;
|
|
88
128
|
createSkyLight(params: {
|
|
89
129
|
name: string;
|
|
90
130
|
sourceType?: 'CapturedScene' | 'SpecifiedCubemap';
|
|
@@ -148,7 +188,14 @@ export declare class LightingTools {
|
|
|
148
188
|
buildOnlySelected?: boolean;
|
|
149
189
|
buildReflectionCaptures?: boolean;
|
|
150
190
|
levelPath?: string;
|
|
151
|
-
}): Promise<
|
|
191
|
+
}): Promise<{
|
|
192
|
+
success: boolean;
|
|
193
|
+
error: string;
|
|
194
|
+
} | {
|
|
195
|
+
success: boolean;
|
|
196
|
+
message: string;
|
|
197
|
+
error?: undefined;
|
|
198
|
+
}>;
|
|
152
199
|
createLightingEnabledLevel(params?: {
|
|
153
200
|
levelName?: string;
|
|
154
201
|
copyActors?: boolean;
|
package/dist/tools/lighting.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { ensureVector3 } from '../utils/validation.js';
|
|
2
|
+
import { wasmIntegration } from '../wasm/index.js';
|
|
2
3
|
export class LightingTools {
|
|
3
4
|
bridge;
|
|
4
5
|
automationBridge;
|
|
@@ -32,7 +33,10 @@ export class LightingTools {
|
|
|
32
33
|
name: params.name,
|
|
33
34
|
};
|
|
34
35
|
if (params.location) {
|
|
35
|
-
|
|
36
|
+
const zeroVector = [0, 0, 0];
|
|
37
|
+
const processedLocation = wasmIntegration.vectorAdd(zeroVector, params.location);
|
|
38
|
+
console.error('[WASM] Using vectorAdd for light positioning');
|
|
39
|
+
payload.location = { x: processedLocation[0], y: processedLocation[1], z: processedLocation[2] };
|
|
36
40
|
}
|
|
37
41
|
if (params.rotation) {
|
|
38
42
|
if (Array.isArray(params.rotation)) {
|
|
@@ -124,7 +128,7 @@ export class LightingTools {
|
|
|
124
128
|
return { success: true, message: `Directional light '${name}' spawned` };
|
|
125
129
|
}
|
|
126
130
|
catch (e) {
|
|
127
|
-
return { success: false, error: `Failed to create directional light: ${e
|
|
131
|
+
return { success: false, error: `Failed to create directional light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
128
132
|
}
|
|
129
133
|
}
|
|
130
134
|
async createPointLight(params) {
|
|
@@ -198,7 +202,7 @@ export class LightingTools {
|
|
|
198
202
|
return { success: true, message: `Point light '${name}' spawned at ${location.join(', ')}` };
|
|
199
203
|
}
|
|
200
204
|
catch (e) {
|
|
201
|
-
return { success: false, error: `Failed to create point light: ${e
|
|
205
|
+
return { success: false, error: `Failed to create point light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
202
206
|
}
|
|
203
207
|
}
|
|
204
208
|
async createSpotLight(params) {
|
|
@@ -298,7 +302,7 @@ export class LightingTools {
|
|
|
298
302
|
return { success: true, message: `Spot light '${name}' spawned at ${params.location.join(', ')}` };
|
|
299
303
|
}
|
|
300
304
|
catch (e) {
|
|
301
|
-
return { success: false, error: `Failed to create spot light: ${e
|
|
305
|
+
return { success: false, error: `Failed to create spot light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
302
306
|
}
|
|
303
307
|
}
|
|
304
308
|
async createRectLight(params) {
|
|
@@ -384,7 +388,7 @@ export class LightingTools {
|
|
|
384
388
|
return { success: true, message: `Rect light '${name}' spawned at ${params.location.join(', ')}` };
|
|
385
389
|
}
|
|
386
390
|
catch (e) {
|
|
387
|
-
return { success: false, error: `Failed to create rect light: ${e
|
|
391
|
+
return { success: false, error: `Failed to create rect light: ${(e instanceof Error ? e.message : String(e)) ?? e}` };
|
|
388
392
|
}
|
|
389
393
|
}
|
|
390
394
|
async createDynamicLight(params) {
|
|
@@ -43,7 +43,7 @@ export declare class MaterialTools {
|
|
|
43
43
|
transport?: undefined;
|
|
44
44
|
warnings?: undefined;
|
|
45
45
|
}>;
|
|
46
|
-
createMaterialInstance(name: string, path: string, parentMaterial: string, parameters?: Record<string,
|
|
46
|
+
createMaterialInstance(name: string, path: string, parentMaterial: string, parameters?: Record<string, unknown>): Promise<any>;
|
|
47
47
|
addNode(params: {
|
|
48
48
|
materialPath: string;
|
|
49
49
|
nodeType: string;
|
package/dist/tools/materials.js
CHANGED
|
@@ -129,7 +129,11 @@ export class MaterialTools {
|
|
|
129
129
|
return { success: false, error: resp?.error ?? resp?.message ?? 'CREATE_MATERIAL_INSTANCE_FAILED' };
|
|
130
130
|
}
|
|
131
131
|
}
|
|
132
|
-
catch (
|
|
132
|
+
catch (e) {
|
|
133
|
+
const msg = e instanceof Error ? e.message : String(e);
|
|
134
|
+
if (!msg.includes('unknown') && !msg.includes('UNKNOWN_PLUGIN_ACTION')) {
|
|
135
|
+
console.warn(`[MaterialTools] Plugin create_material_instance failed with specific error (falling back to python): ${msg}`);
|
|
136
|
+
}
|
|
133
137
|
}
|
|
134
138
|
}
|
|
135
139
|
const createParams = {
|
package/dist/tools/niagara.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { sanitizeAssetName, validateAssetParams } from '../utils/validation.js';
|
|
2
|
+
import { wasmIntegration } from '../wasm/index.js';
|
|
2
3
|
export class NiagaraTools {
|
|
3
4
|
bridge;
|
|
4
5
|
automationBridge;
|
|
@@ -12,6 +13,16 @@ export class NiagaraTools {
|
|
|
12
13
|
if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
|
|
13
14
|
throw new Error('Automation Bridge not available. Niagara system creation requires plugin support.');
|
|
14
15
|
}
|
|
16
|
+
if (params.emitters) {
|
|
17
|
+
for (const emitter of params.emitters) {
|
|
18
|
+
if (emitter.shapeSize) {
|
|
19
|
+
const zeroVector = [0, 0, 0];
|
|
20
|
+
const processedSize = wasmIntegration.vectorAdd(zeroVector, emitter.shapeSize);
|
|
21
|
+
console.error('[WASM] Using vectorAdd for Niagara emitter shape size');
|
|
22
|
+
emitter.shapeSize = [processedSize[0], processedSize[1], processedSize[2]];
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
}
|
|
15
26
|
const path = params.savePath || '/Game/Effects/Niagara';
|
|
16
27
|
const response = await this.automationBridge.sendAutomationRequest('create_niagara_system', { name: params.name, savePath: path, template: params.template }, { timeoutMs: 60000 });
|
|
17
28
|
if (response && response.success !== false) {
|
|
@@ -82,8 +93,19 @@ export class NiagaraTools {
|
|
|
82
93
|
return [value.x ?? 0, value.y ?? 0, value.z ?? 0];
|
|
83
94
|
};
|
|
84
95
|
const requestPayload = { systemPath: params.systemPath };
|
|
85
|
-
|
|
86
|
-
|
|
96
|
+
let start = toVector(params.start);
|
|
97
|
+
let end = toVector(params.end);
|
|
98
|
+
const zeroVector = [0, 0, 0];
|
|
99
|
+
if (start) {
|
|
100
|
+
const processed = wasmIntegration.vectorAdd(zeroVector, start);
|
|
101
|
+
console.error('[WASM] Using vectorAdd for Niagara ribbon start');
|
|
102
|
+
start = [processed[0], processed[1], processed[2]];
|
|
103
|
+
}
|
|
104
|
+
if (end) {
|
|
105
|
+
const processed = wasmIntegration.vectorAdd(zeroVector, end);
|
|
106
|
+
console.error('[WASM] Using vectorAdd for Niagara ribbon end');
|
|
107
|
+
end = [processed[0], processed[1], processed[2]];
|
|
108
|
+
}
|
|
87
109
|
if (start)
|
|
88
110
|
requestPayload.start = start;
|
|
89
111
|
if (end)
|
|
@@ -148,6 +170,19 @@ export class NiagaraTools {
|
|
|
148
170
|
if (!this.automationBridge || typeof this.automationBridge.sendAutomationRequest !== 'function') {
|
|
149
171
|
return { success: false, error: 'AUTOMATION_BRIDGE_UNAVAILABLE', message: 'addEmitter requires automation bridge' };
|
|
150
172
|
}
|
|
173
|
+
if (params.properties) {
|
|
174
|
+
const zeroVector = [0, 0, 0];
|
|
175
|
+
if (params.properties.velocityMin) {
|
|
176
|
+
const processed = wasmIntegration.vectorAdd(zeroVector, params.properties.velocityMin);
|
|
177
|
+
console.error('[WASM] Using vectorAdd for Niagara velocity min');
|
|
178
|
+
params.properties.velocityMin = [processed[0], processed[1], processed[2]];
|
|
179
|
+
}
|
|
180
|
+
if (params.properties.velocityMax) {
|
|
181
|
+
const processed = wasmIntegration.vectorAdd(zeroVector, params.properties.velocityMax);
|
|
182
|
+
console.error('[WASM] Using vectorAdd for Niagara velocity max');
|
|
183
|
+
params.properties.velocityMax = [processed[0], processed[1], processed[2]];
|
|
184
|
+
}
|
|
185
|
+
}
|
|
151
186
|
try {
|
|
152
187
|
const resp = await this.automationBridge.sendAutomationRequest('manage_niagara_graph', {
|
|
153
188
|
subAction: 'add_emitter',
|
package/dist/tools/physics.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { validateAssetParams, resolveSkeletalMeshPath, concurrencyDelay } from '../utils/validation.js';
|
|
2
2
|
import { coerceString, coerceStringArray } from '../utils/result-helpers.js';
|
|
3
|
+
import { wasmIntegration } from '../wasm/index.js';
|
|
3
4
|
export class PhysicsTools {
|
|
4
5
|
bridge;
|
|
5
6
|
automationBridge;
|
|
@@ -309,10 +310,13 @@ export class PhysicsTools {
|
|
|
309
310
|
throw new Error('Automation Bridge not available. Physics force application requires plugin support.');
|
|
310
311
|
}
|
|
311
312
|
try {
|
|
313
|
+
const zeroVector = [0, 0, 0];
|
|
314
|
+
const normalizedVector = wasmIntegration.vectorAdd(zeroVector, params.vector);
|
|
315
|
+
console.error('[WASM] Using vectorAdd for physics force vector processing');
|
|
312
316
|
const response = await this.automationBridge.sendAutomationRequest('apply_force', {
|
|
313
317
|
actorName: params.actorName,
|
|
314
318
|
forceType: params.forceType,
|
|
315
|
-
vector:
|
|
319
|
+
vector: normalizedVector,
|
|
316
320
|
boneName: params.boneName,
|
|
317
321
|
isLocal: params.isLocal
|
|
318
322
|
}, {
|
package/dist/tools/sequence.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { BaseTool } from './base-tool.js';
|
|
2
|
-
import { ISequenceTools } from '../types/tool-interfaces.js';
|
|
2
|
+
import { ISequenceTools, StandardActionResponse } from '../types/tool-interfaces.js';
|
|
3
3
|
export interface LevelSequence {
|
|
4
4
|
path: string;
|
|
5
5
|
name: string;
|
|
@@ -28,80 +28,80 @@ export declare class SequenceTools extends BaseTool implements ISequenceTools {
|
|
|
28
28
|
name: string;
|
|
29
29
|
path?: string;
|
|
30
30
|
timeoutMs?: number;
|
|
31
|
-
}): Promise<
|
|
31
|
+
}): Promise<StandardActionResponse>;
|
|
32
32
|
open(params: {
|
|
33
33
|
path: string;
|
|
34
|
-
}): Promise<
|
|
34
|
+
}): Promise<StandardActionResponse>;
|
|
35
35
|
addCamera(params: {
|
|
36
36
|
spawnable?: boolean;
|
|
37
37
|
path?: string;
|
|
38
|
-
}): Promise<
|
|
38
|
+
}): Promise<StandardActionResponse>;
|
|
39
39
|
addActor(params: {
|
|
40
40
|
actorName: string;
|
|
41
41
|
createBinding?: boolean;
|
|
42
42
|
path?: string;
|
|
43
|
-
}): Promise<
|
|
43
|
+
}): Promise<StandardActionResponse>;
|
|
44
44
|
play(params?: {
|
|
45
45
|
path?: string;
|
|
46
46
|
startTime?: number;
|
|
47
47
|
loopMode?: 'once' | 'loop' | 'pingpong';
|
|
48
|
-
}): Promise<
|
|
48
|
+
}): Promise<StandardActionResponse>;
|
|
49
49
|
pause(params?: {
|
|
50
50
|
path?: string;
|
|
51
|
-
}): Promise<
|
|
51
|
+
}): Promise<StandardActionResponse>;
|
|
52
52
|
stop(params?: {
|
|
53
53
|
path?: string;
|
|
54
|
-
}): Promise<
|
|
54
|
+
}): Promise<StandardActionResponse>;
|
|
55
55
|
setSequenceProperties(params: {
|
|
56
56
|
path?: string;
|
|
57
57
|
frameRate?: number;
|
|
58
58
|
lengthInFrames?: number;
|
|
59
59
|
playbackStart?: number;
|
|
60
60
|
playbackEnd?: number;
|
|
61
|
-
}): Promise<
|
|
61
|
+
}): Promise<StandardActionResponse>;
|
|
62
62
|
setDisplayRate(params: {
|
|
63
63
|
path?: string;
|
|
64
64
|
frameRate: string | number;
|
|
65
|
-
}): Promise<
|
|
65
|
+
}): Promise<StandardActionResponse>;
|
|
66
66
|
getSequenceProperties(params: {
|
|
67
67
|
path?: string;
|
|
68
|
-
}): Promise<
|
|
68
|
+
}): Promise<StandardActionResponse>;
|
|
69
69
|
setPlaybackSpeed(params: {
|
|
70
70
|
speed: number;
|
|
71
71
|
path?: string;
|
|
72
|
-
}): Promise<
|
|
72
|
+
}): Promise<StandardActionResponse>;
|
|
73
73
|
getBindings(params?: {
|
|
74
74
|
path?: string;
|
|
75
|
-
}): Promise<
|
|
75
|
+
}): Promise<StandardActionResponse>;
|
|
76
76
|
addActors(params: {
|
|
77
77
|
actorNames: string[];
|
|
78
78
|
path?: string;
|
|
79
|
-
}): Promise<
|
|
79
|
+
}): Promise<StandardActionResponse>;
|
|
80
80
|
removeActors(params: {
|
|
81
81
|
actorNames: string[];
|
|
82
82
|
path?: string;
|
|
83
|
-
}): Promise<
|
|
83
|
+
}): Promise<StandardActionResponse>;
|
|
84
84
|
addSpawnableFromClass(params: {
|
|
85
85
|
className: string;
|
|
86
86
|
path?: string;
|
|
87
|
-
}): Promise<
|
|
87
|
+
}): Promise<StandardActionResponse>;
|
|
88
88
|
list(params?: {
|
|
89
89
|
path?: string;
|
|
90
|
-
}): Promise<
|
|
90
|
+
}): Promise<StandardActionResponse>;
|
|
91
91
|
duplicate(params: {
|
|
92
92
|
path: string;
|
|
93
93
|
destinationPath: string;
|
|
94
|
-
}): Promise<
|
|
94
|
+
}): Promise<StandardActionResponse>;
|
|
95
95
|
rename(params: {
|
|
96
96
|
path: string;
|
|
97
97
|
newName: string;
|
|
98
|
-
}): Promise<
|
|
98
|
+
}): Promise<StandardActionResponse>;
|
|
99
99
|
deleteSequence(params: {
|
|
100
100
|
path: string;
|
|
101
|
-
}): Promise<
|
|
101
|
+
}): Promise<StandardActionResponse>;
|
|
102
102
|
getMetadata(params: {
|
|
103
103
|
path?: string;
|
|
104
|
-
}): Promise<
|
|
104
|
+
}): Promise<StandardActionResponse>;
|
|
105
105
|
addKeyframe(params: {
|
|
106
106
|
path?: string;
|
|
107
107
|
bindingId?: string;
|
|
@@ -125,14 +125,14 @@ export declare class SequenceTools extends BaseTool implements ISequenceTools {
|
|
|
125
125
|
z: number;
|
|
126
126
|
};
|
|
127
127
|
};
|
|
128
|
-
}): Promise<
|
|
128
|
+
}): Promise<StandardActionResponse>;
|
|
129
129
|
listTracks(params: {
|
|
130
130
|
path: string;
|
|
131
|
-
}): Promise<
|
|
131
|
+
}): Promise<StandardActionResponse>;
|
|
132
132
|
setWorkRange(params: {
|
|
133
133
|
path?: string;
|
|
134
134
|
start: number;
|
|
135
135
|
end: number;
|
|
136
|
-
}): Promise<
|
|
136
|
+
}): Promise<StandardActionResponse>;
|
|
137
137
|
}
|
|
138
138
|
//# sourceMappingURL=sequence.d.ts.map
|
package/dist/tools/sequence.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { BaseTool } from './base-tool.js';
|
|
2
|
+
import { wasmIntegration } from '../wasm/index.js';
|
|
2
3
|
export class SequenceTools extends BaseTool {
|
|
3
4
|
sequenceCache = new Map();
|
|
4
5
|
activeSequencePath;
|
|
@@ -214,6 +215,18 @@ export class SequenceTools extends BaseTool {
|
|
|
214
215
|
frame: params.frame,
|
|
215
216
|
value: params.value
|
|
216
217
|
});
|
|
218
|
+
if (params.property === 'Transform' && params.value) {
|
|
219
|
+
const loc = params.value.location;
|
|
220
|
+
const rot = params.value.rotation;
|
|
221
|
+
const scale = params.value.scale;
|
|
222
|
+
if (loc && rot && scale) {
|
|
223
|
+
const locArr = [loc.x, loc.y, loc.z];
|
|
224
|
+
const rotArr = [rot.pitch, rot.yaw, rot.roll];
|
|
225
|
+
const scaleArr = [scale.x, scale.y, scale.z];
|
|
226
|
+
wasmIntegration.composeTransform(locArr, rotArr, scaleArr);
|
|
227
|
+
console.error('[WASM] Using composeTransform for keyframe validation');
|
|
228
|
+
}
|
|
229
|
+
}
|
|
217
230
|
if (!resp.success && this.isUnknownActionResponse(resp)) {
|
|
218
231
|
return { success: false, error: 'UNKNOWN_PLUGIN_ACTION', message: 'Automation plugin does not implement sequence_add_keyframe' };
|
|
219
232
|
}
|
package/dist/tools/ui.d.ts
CHANGED
|
@@ -69,7 +69,6 @@ export declare class UITools {
|
|
|
69
69
|
setWidgetText(_params: {
|
|
70
70
|
key: string;
|
|
71
71
|
value: string;
|
|
72
|
-
componentName?: string;
|
|
73
72
|
}): Promise<{
|
|
74
73
|
success: boolean;
|
|
75
74
|
message: string;
|
|
@@ -81,7 +80,6 @@ export declare class UITools {
|
|
|
81
80
|
setWidgetImage(_params: {
|
|
82
81
|
key: string;
|
|
83
82
|
texturePath: string;
|
|
84
|
-
componentName?: string;
|
|
85
83
|
}): Promise<{
|
|
86
84
|
success: boolean;
|
|
87
85
|
message: string;
|