@uemcp/server 0.3.0 → 1.0.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/README.md +75 -0
- package/dist/index.mjs +1630 -269
- package/package.json +1 -1
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import os, { tmpdir } from "node:os";
|
|
3
3
|
import path from "node:path";
|
|
4
|
-
import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
4
|
+
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
5
5
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
6
6
|
import { randomUUID } from "node:crypto";
|
|
7
7
|
import { z } from "zod";
|
|
@@ -420,6 +420,45 @@ const BRIDGE_STOP_TRACE_STATES = [
|
|
|
420
420
|
"not_tracing",
|
|
421
421
|
"unsupported"
|
|
422
422
|
];
|
|
423
|
+
const BRIDGE_LIST_ACTORS_REQUEST_TYPE = "list_actors";
|
|
424
|
+
const BRIDGE_GET_ACTOR_DETAILS_REQUEST_TYPE = "get_actor_details";
|
|
425
|
+
const BRIDGE_GET_CURRENT_LEVEL_REQUEST_TYPE = "get_current_level";
|
|
426
|
+
const BRIDGE_SPAWN_ACTOR_REQUEST_TYPE = "spawn_actor";
|
|
427
|
+
const BRIDGE_DESTROY_ACTOR_REQUEST_TYPE = "destroy_actor";
|
|
428
|
+
const BRIDGE_UNDO_REQUEST_TYPE = "undo";
|
|
429
|
+
const BRIDGE_REDO_REQUEST_TYPE = "redo";
|
|
430
|
+
const BRIDGE_LEVEL_EDIT_STATES = [
|
|
431
|
+
"applied",
|
|
432
|
+
"validated",
|
|
433
|
+
"unsupported"
|
|
434
|
+
];
|
|
435
|
+
const BRIDGE_SET_ACTOR_TRANSFORM_REQUEST_TYPE = "set_actor_transform";
|
|
436
|
+
const BRIDGE_SET_ACTOR_PROPERTY_REQUEST_TYPE = "set_actor_property";
|
|
437
|
+
const BRIDGE_SELECT_ACTORS_REQUEST_TYPE = "select_actors";
|
|
438
|
+
const BRIDGE_PROPERTY_VALUE_MAX_CHARS = 4096;
|
|
439
|
+
const BRIDGE_UNDO_STATES = [
|
|
440
|
+
"undone",
|
|
441
|
+
"nothing_to_undo",
|
|
442
|
+
"unsupported"
|
|
443
|
+
];
|
|
444
|
+
const BRIDGE_REDO_STATES = [
|
|
445
|
+
"redone",
|
|
446
|
+
"nothing_to_redo",
|
|
447
|
+
"unsupported"
|
|
448
|
+
];
|
|
449
|
+
const BRIDGE_OPEN_LEVEL_REQUEST_TYPE = "open_level";
|
|
450
|
+
const BRIDGE_GET_OPEN_LEVEL_STATUS_REQUEST_TYPE = "get_open_level_status";
|
|
451
|
+
const BRIDGE_OPEN_LEVEL_STATES = [
|
|
452
|
+
"opening",
|
|
453
|
+
"validated",
|
|
454
|
+
"unsupported"
|
|
455
|
+
];
|
|
456
|
+
const BRIDGE_OPEN_LEVEL_STATUS_STATES = [
|
|
457
|
+
"opening",
|
|
458
|
+
"succeeded",
|
|
459
|
+
"failed",
|
|
460
|
+
"unknown_job"
|
|
461
|
+
];
|
|
423
462
|
const requestIdSchema = z.string().trim().min(1);
|
|
424
463
|
const nonEmptyStringSchema = z.string().trim().min(1);
|
|
425
464
|
const boundedStringSchema = z.string().trim().max(512);
|
|
@@ -490,7 +529,11 @@ const parentClassSchema = z.string().trim().min(1).max(128);
|
|
|
490
529
|
const moduleNameSchema = z.string().trim().min(1).max(128);
|
|
491
530
|
const classPathSchema = z.string().trim().min(1).max(512);
|
|
492
531
|
const sourceFilePathSchema = z.string().trim().min(1);
|
|
493
|
-
const
|
|
532
|
+
const bridgeSelectedActorSchema = z.object({
|
|
533
|
+
actorPath: z.string(),
|
|
534
|
+
label: z.string()
|
|
535
|
+
});
|
|
536
|
+
const selectedActorArraySchema = z.array(bridgeSelectedActorSchema).max(100);
|
|
494
537
|
const activeModeArraySchema = z.array(z.string()).max(32);
|
|
495
538
|
const packageNameArraySchema = z.array(z.string()).max(100);
|
|
496
539
|
const screenshotPathSchema = z.string().trim().min(1);
|
|
@@ -511,35 +554,76 @@ const stopTraceStateSchema = z.enum(BRIDGE_STOP_TRACE_STATES);
|
|
|
511
554
|
const traceChannelSchema = z.string().trim().min(1).max(64).regex(/^[A-Za-z0-9_]+$/);
|
|
512
555
|
const traceChannelArraySchema = z.array(traceChannelSchema).max(32);
|
|
513
556
|
const traceFileNameSchema = z.string().trim().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/);
|
|
557
|
+
const actorPathSchema = z.string().trim().min(1).max(512);
|
|
558
|
+
const levelCursorSchema = z.number().int().min(0);
|
|
559
|
+
const levelMaxResultsSchema = z.number().int().min(1).max(100);
|
|
560
|
+
const actorDetailMemberLimitSchema = z.number().int().min(1).max(200);
|
|
561
|
+
const actorClassFilterArraySchema = z.array(assetPathSchema).max(32);
|
|
562
|
+
const levelEditStateSchema = z.enum(BRIDGE_LEVEL_EDIT_STATES);
|
|
563
|
+
const undoStateSchema = z.enum(BRIDGE_UNDO_STATES);
|
|
564
|
+
const redoStateSchema = z.enum(BRIDGE_REDO_STATES);
|
|
565
|
+
const openLevelStateSchema = z.enum(BRIDGE_OPEN_LEVEL_STATES);
|
|
566
|
+
const openLevelStatusStateSchema = z.enum(BRIDGE_OPEN_LEVEL_STATUS_STATES);
|
|
567
|
+
const openLevelJobIdSchema = z.string().trim().min(1);
|
|
568
|
+
const levelPathSchema = z.string().trim().min(1).max(512);
|
|
569
|
+
const actorPathBatchSchema = z.array(actorPathSchema).min(1).max(64);
|
|
570
|
+
const actorTagArraySchema = z.array(boundedStringSchema).max(16);
|
|
571
|
+
const vectorInputSchema = z.object({
|
|
572
|
+
x: z.number().default(0),
|
|
573
|
+
y: z.number().default(0),
|
|
574
|
+
z: z.number().default(0)
|
|
575
|
+
});
|
|
576
|
+
const rotatorInputSchema = z.object({
|
|
577
|
+
pitch: z.number().default(0),
|
|
578
|
+
roll: z.number().default(0),
|
|
579
|
+
yaw: z.number().default(0)
|
|
580
|
+
});
|
|
581
|
+
const transformInputSchema = z.object({
|
|
582
|
+
location: vectorInputSchema.default({
|
|
583
|
+
x: 0,
|
|
584
|
+
y: 0,
|
|
585
|
+
z: 0
|
|
586
|
+
}),
|
|
587
|
+
rotation: rotatorInputSchema.default({
|
|
588
|
+
pitch: 0,
|
|
589
|
+
roll: 0,
|
|
590
|
+
yaw: 0
|
|
591
|
+
}),
|
|
592
|
+
scale: vectorInputSchema.default({
|
|
593
|
+
x: 1,
|
|
594
|
+
y: 1,
|
|
595
|
+
z: 1
|
|
596
|
+
})
|
|
597
|
+
});
|
|
514
598
|
const memoryMegabytesSchema = z.number().min(0);
|
|
515
599
|
const frameTimingMillisecondsSchema = z.number().min(0);
|
|
516
600
|
z.object({
|
|
517
601
|
requestId: requestIdSchema,
|
|
518
602
|
type: z.literal(BRIDGE_PING_REQUEST_TYPE),
|
|
519
|
-
version: z.literal(
|
|
603
|
+
version: z.literal(2)
|
|
520
604
|
});
|
|
521
605
|
z.object({
|
|
522
606
|
requestId: requestIdSchema,
|
|
523
607
|
type: z.literal(BRIDGE_START_LIVE_COMPILE_REQUEST_TYPE),
|
|
524
|
-
version: z.literal(
|
|
608
|
+
version: z.literal(2)
|
|
525
609
|
});
|
|
526
610
|
z.object({
|
|
527
611
|
requestId: requestIdSchema,
|
|
528
612
|
type: z.literal(BRIDGE_START_HOT_RELOAD_REQUEST_TYPE),
|
|
529
|
-
version: z.literal(
|
|
613
|
+
version: z.literal(2)
|
|
530
614
|
});
|
|
531
615
|
const bridgeGetCompileStatusRequestSchema = z.object({
|
|
532
616
|
compileJobId: compileJobIdSchema,
|
|
533
617
|
requestId: requestIdSchema,
|
|
534
618
|
type: z.literal(BRIDGE_GET_COMPILE_STATUS_REQUEST_TYPE),
|
|
535
|
-
version: z.literal(
|
|
619
|
+
version: z.literal(2)
|
|
536
620
|
});
|
|
537
621
|
const bridgeGetCrashCallstackRequestSchema = z.object({
|
|
538
622
|
maxFrames: crashMaxFramesSchema,
|
|
539
623
|
maxRecords: crashMaxRecordsSchema,
|
|
540
624
|
requestId: requestIdSchema,
|
|
541
625
|
type: z.literal(BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE),
|
|
542
|
-
version: z.literal(
|
|
626
|
+
version: z.literal(2)
|
|
543
627
|
});
|
|
544
628
|
const bridgeErrorSchema = z.object({
|
|
545
629
|
code: z.string().trim().min(1),
|
|
@@ -567,21 +651,21 @@ const bridgeLogSubscribeRequestSchema = z.union([
|
|
|
567
651
|
requestId: requestIdSchema,
|
|
568
652
|
source: z.literal("output_log"),
|
|
569
653
|
type: z.literal(BRIDGE_SUBSCRIBE_LOGS_REQUEST_TYPE),
|
|
570
|
-
version: z.literal(
|
|
654
|
+
version: z.literal(2)
|
|
571
655
|
}),
|
|
572
656
|
z.object({
|
|
573
657
|
filters: bridgeMessageLogFilterSchema,
|
|
574
658
|
requestId: requestIdSchema,
|
|
575
659
|
source: z.literal("message_log"),
|
|
576
660
|
type: z.literal(BRIDGE_SUBSCRIBE_LOGS_REQUEST_TYPE),
|
|
577
|
-
version: z.literal(
|
|
661
|
+
version: z.literal(2)
|
|
578
662
|
}),
|
|
579
663
|
z.object({
|
|
580
664
|
filters: bridgeDeviceOutputLogFilterSchema,
|
|
581
665
|
requestId: requestIdSchema,
|
|
582
666
|
source: z.literal("device_output_log"),
|
|
583
667
|
type: z.literal(BRIDGE_SUBSCRIBE_LOGS_REQUEST_TYPE),
|
|
584
|
-
version: z.literal(
|
|
668
|
+
version: z.literal(2)
|
|
585
669
|
})
|
|
586
670
|
]);
|
|
587
671
|
const bridgeLogDrainRequestSchema = z.object({
|
|
@@ -590,13 +674,13 @@ const bridgeLogDrainRequestSchema = z.object({
|
|
|
590
674
|
requestId: requestIdSchema,
|
|
591
675
|
subscriptionId: subscriptionIdSchema,
|
|
592
676
|
type: z.literal(BRIDGE_DRAIN_LOGS_REQUEST_TYPE),
|
|
593
|
-
version: z.literal(
|
|
677
|
+
version: z.literal(2)
|
|
594
678
|
});
|
|
595
679
|
z.object({
|
|
596
680
|
requestId: requestIdSchema,
|
|
597
681
|
subscriptionId: subscriptionIdSchema,
|
|
598
682
|
type: z.literal(BRIDGE_UNSUBSCRIBE_LOGS_REQUEST_TYPE),
|
|
599
|
-
version: z.literal(
|
|
683
|
+
version: z.literal(2)
|
|
600
684
|
});
|
|
601
685
|
const bridgeStartPieRequestSchema = z.object({
|
|
602
686
|
map: pieMapSchema.optional(),
|
|
@@ -606,31 +690,31 @@ const bridgeStartPieRequestSchema = z.object({
|
|
|
606
690
|
requestId: requestIdSchema,
|
|
607
691
|
runUnderOneProcess: z.boolean().optional(),
|
|
608
692
|
type: z.literal(BRIDGE_START_PIE_REQUEST_TYPE),
|
|
609
|
-
version: z.literal(
|
|
693
|
+
version: z.literal(2)
|
|
610
694
|
});
|
|
611
695
|
const bridgeGetPieStatusRequestSchema = z.object({
|
|
612
696
|
pieSessionId: pieSessionIdSchema.optional(),
|
|
613
697
|
requestId: requestIdSchema,
|
|
614
698
|
type: z.literal(BRIDGE_GET_PIE_STATUS_REQUEST_TYPE),
|
|
615
|
-
version: z.literal(
|
|
699
|
+
version: z.literal(2)
|
|
616
700
|
});
|
|
617
701
|
z.object({
|
|
618
702
|
requestId: requestIdSchema,
|
|
619
703
|
type: z.literal(BRIDGE_LIST_LAUNCH_DEVICES_REQUEST_TYPE),
|
|
620
|
-
version: z.literal(
|
|
704
|
+
version: z.literal(2)
|
|
621
705
|
});
|
|
622
706
|
const bridgeLaunchOnDeviceRequestSchema = z.object({
|
|
623
707
|
deviceId: launchDeviceIdSchema,
|
|
624
708
|
map: pieMapSchema.optional(),
|
|
625
709
|
requestId: requestIdSchema,
|
|
626
710
|
type: z.literal(BRIDGE_LAUNCH_ON_DEVICE_REQUEST_TYPE),
|
|
627
|
-
version: z.literal(
|
|
711
|
+
version: z.literal(2)
|
|
628
712
|
});
|
|
629
713
|
const bridgeStopPieRequestSchema = z.object({
|
|
630
714
|
pieSessionId: pieSessionIdSchema.optional(),
|
|
631
715
|
requestId: requestIdSchema,
|
|
632
716
|
type: z.literal(BRIDGE_STOP_PIE_REQUEST_TYPE),
|
|
633
|
-
version: z.literal(
|
|
717
|
+
version: z.literal(2)
|
|
634
718
|
});
|
|
635
719
|
const bridgeListAutomationTestsRequestSchema = z.object({
|
|
636
720
|
cursor: automationTestCursorSchema.default(0),
|
|
@@ -639,7 +723,7 @@ const bridgeListAutomationTestsRequestSchema = z.object({
|
|
|
639
723
|
nameFilter: boundedStringSchema.optional(),
|
|
640
724
|
requestId: requestIdSchema,
|
|
641
725
|
type: z.literal(BRIDGE_LIST_AUTOMATION_TESTS_REQUEST_TYPE),
|
|
642
|
-
version: z.literal(
|
|
726
|
+
version: z.literal(2)
|
|
643
727
|
});
|
|
644
728
|
const bridgeAutomationTestSchema = z.object({
|
|
645
729
|
displayName: z.string(),
|
|
@@ -655,7 +739,7 @@ const bridgeStartAutomationRunRequestSchema = z.object({
|
|
|
655
739
|
requestId: requestIdSchema,
|
|
656
740
|
testNames: automationTestNamesSchema.default([]),
|
|
657
741
|
type: z.literal(BRIDGE_START_AUTOMATION_RUN_REQUEST_TYPE),
|
|
658
|
-
version: z.literal(
|
|
742
|
+
version: z.literal(2)
|
|
659
743
|
}).refine((value) => value.testNames.length > 0 || value.nameFilter !== void 0 && value.nameFilter.length > 0, {
|
|
660
744
|
message: "A start_automation_run request requires at least one of testNames or nameFilter.",
|
|
661
745
|
path: ["testNames"]
|
|
@@ -666,30 +750,30 @@ const bridgeGetAutomationRunStatusRequestSchema = z.object({
|
|
|
666
750
|
requestId: requestIdSchema,
|
|
667
751
|
testRunId: testRunIdSchema,
|
|
668
752
|
type: z.literal(BRIDGE_GET_AUTOMATION_RUN_STATUS_REQUEST_TYPE),
|
|
669
|
-
version: z.literal(
|
|
753
|
+
version: z.literal(2)
|
|
670
754
|
});
|
|
671
755
|
const bridgeCancelAutomationRunRequestSchema = z.object({
|
|
672
756
|
requestId: requestIdSchema,
|
|
673
757
|
testRunId: testRunIdSchema,
|
|
674
758
|
type: z.literal(BRIDGE_CANCEL_AUTOMATION_RUN_REQUEST_TYPE),
|
|
675
|
-
version: z.literal(
|
|
759
|
+
version: z.literal(2)
|
|
676
760
|
});
|
|
677
761
|
z.object({
|
|
678
762
|
requestId: requestIdSchema,
|
|
679
763
|
type: z.literal(BRIDGE_GET_EDITOR_STATE_REQUEST_TYPE),
|
|
680
|
-
version: z.literal(
|
|
764
|
+
version: z.literal(2)
|
|
681
765
|
});
|
|
682
766
|
const bridgeSaveDirtyPackagesRequestSchema = z.object({
|
|
683
767
|
requestId: requestIdSchema,
|
|
684
768
|
saveContentPackages: z.boolean().default(true),
|
|
685
769
|
saveMapPackages: z.boolean().default(true),
|
|
686
770
|
type: z.literal(BRIDGE_SAVE_DIRTY_PACKAGES_REQUEST_TYPE),
|
|
687
|
-
version: z.literal(
|
|
771
|
+
version: z.literal(2)
|
|
688
772
|
});
|
|
689
773
|
z.object({
|
|
690
774
|
requestId: requestIdSchema,
|
|
691
775
|
type: z.literal(BRIDGE_CAPTURE_VIEWPORT_REQUEST_TYPE),
|
|
692
|
-
version: z.literal(
|
|
776
|
+
version: z.literal(2)
|
|
693
777
|
});
|
|
694
778
|
const bridgeGetClassReflectionRequestSchema = z.object({
|
|
695
779
|
className: reflectedTypeNameSchema,
|
|
@@ -700,7 +784,7 @@ const bridgeGetClassReflectionRequestSchema = z.object({
|
|
|
700
784
|
propertyCursor: reflectionCursorSchema.default(0),
|
|
701
785
|
requestId: requestIdSchema,
|
|
702
786
|
type: z.literal(BRIDGE_GET_CLASS_REFLECTION_REQUEST_TYPE),
|
|
703
|
-
version: z.literal(
|
|
787
|
+
version: z.literal(2)
|
|
704
788
|
});
|
|
705
789
|
const bridgeGetCdoDefaultsRequestSchema = z.object({
|
|
706
790
|
className: reflectedTypeNameSchema,
|
|
@@ -710,30 +794,30 @@ const bridgeGetCdoDefaultsRequestSchema = z.object({
|
|
|
710
794
|
nameFilter: boundedStringSchema.optional(),
|
|
711
795
|
requestId: requestIdSchema,
|
|
712
796
|
type: z.literal(BRIDGE_GET_CDO_DEFAULTS_REQUEST_TYPE),
|
|
713
|
-
version: z.literal(
|
|
797
|
+
version: z.literal(2)
|
|
714
798
|
});
|
|
715
799
|
const bridgeExecConsoleCommandRequestSchema = z.object({
|
|
716
800
|
command: consoleCommandSchema,
|
|
717
801
|
requestId: requestIdSchema,
|
|
718
802
|
type: z.literal(BRIDGE_EXEC_CONSOLE_COMMAND_REQUEST_TYPE),
|
|
719
|
-
version: z.literal(
|
|
803
|
+
version: z.literal(2)
|
|
720
804
|
});
|
|
721
805
|
const bridgeStatSnapshotRequestSchema = z.object({
|
|
722
806
|
requestId: requestIdSchema,
|
|
723
807
|
type: z.literal(BRIDGE_STAT_SNAPSHOT_REQUEST_TYPE),
|
|
724
|
-
version: z.literal(
|
|
808
|
+
version: z.literal(2)
|
|
725
809
|
});
|
|
726
810
|
const bridgeStartTraceRequestSchema = z.object({
|
|
727
811
|
channels: traceChannelArraySchema.default([]),
|
|
728
812
|
fileName: traceFileNameSchema.optional(),
|
|
729
813
|
requestId: requestIdSchema,
|
|
730
814
|
type: z.literal(BRIDGE_START_TRACE_REQUEST_TYPE),
|
|
731
|
-
version: z.literal(
|
|
815
|
+
version: z.literal(2)
|
|
732
816
|
});
|
|
733
817
|
const bridgeStopTraceRequestSchema = z.object({
|
|
734
818
|
requestId: requestIdSchema,
|
|
735
819
|
type: z.literal(BRIDGE_STOP_TRACE_REQUEST_TYPE),
|
|
736
|
-
version: z.literal(
|
|
820
|
+
version: z.literal(2)
|
|
737
821
|
});
|
|
738
822
|
const bridgeCreateCppClassRequestSchema = z.object({
|
|
739
823
|
className: classNameSchema,
|
|
@@ -742,13 +826,13 @@ const bridgeCreateCppClassRequestSchema = z.object({
|
|
|
742
826
|
parentClass: parentClassSchema,
|
|
743
827
|
requestId: requestIdSchema,
|
|
744
828
|
type: z.literal(BRIDGE_CREATE_CPP_CLASS_REQUEST_TYPE),
|
|
745
|
-
version: z.literal(
|
|
829
|
+
version: z.literal(2)
|
|
746
830
|
});
|
|
747
831
|
const bridgeGetCreateClassStatusRequestSchema = z.object({
|
|
748
832
|
createClassJobId: createClassJobIdSchema,
|
|
749
833
|
requestId: requestIdSchema,
|
|
750
834
|
type: z.literal(BRIDGE_GET_CREATE_CLASS_STATUS_REQUEST_TYPE),
|
|
751
|
-
version: z.literal(
|
|
835
|
+
version: z.literal(2)
|
|
752
836
|
});
|
|
753
837
|
const bridgeFindAssetsRequestSchema = z.object({
|
|
754
838
|
classNames: assetPathArraySchema.default([]),
|
|
@@ -760,11 +844,134 @@ const bridgeFindAssetsRequestSchema = z.object({
|
|
|
760
844
|
recursivePaths: z.boolean().default(true),
|
|
761
845
|
requestId: requestIdSchema,
|
|
762
846
|
type: z.literal(BRIDGE_FIND_ASSETS_REQUEST_TYPE),
|
|
763
|
-
version: z.literal(
|
|
847
|
+
version: z.literal(2)
|
|
764
848
|
}).refine((value) => value.classNames.length > 0 || value.packagePaths.length > 0, {
|
|
765
849
|
message: "A find_assets request requires at least one of classNames or packagePaths.",
|
|
766
850
|
path: ["classNames"]
|
|
767
851
|
});
|
|
852
|
+
const bridgeListActorsRequestSchema = z.object({
|
|
853
|
+
classNames: actorClassFilterArraySchema.default([]),
|
|
854
|
+
cursor: levelCursorSchema.default(0),
|
|
855
|
+
levelName: boundedStringSchema.optional(),
|
|
856
|
+
maxResults: levelMaxResultsSchema,
|
|
857
|
+
nameFilter: boundedStringSchema.optional(),
|
|
858
|
+
requestId: requestIdSchema,
|
|
859
|
+
tag: boundedStringSchema.optional(),
|
|
860
|
+
type: z.literal(BRIDGE_LIST_ACTORS_REQUEST_TYPE),
|
|
861
|
+
version: z.literal(2)
|
|
862
|
+
});
|
|
863
|
+
const bridgeGetActorDetailsRequestSchema = z.object({
|
|
864
|
+
actorPath: actorPathSchema,
|
|
865
|
+
componentCursor: levelCursorSchema.default(0),
|
|
866
|
+
includeInherited: z.boolean().default(false),
|
|
867
|
+
maxResults: actorDetailMemberLimitSchema,
|
|
868
|
+
propertyCursor: levelCursorSchema.default(0),
|
|
869
|
+
requestId: requestIdSchema,
|
|
870
|
+
type: z.literal(BRIDGE_GET_ACTOR_DETAILS_REQUEST_TYPE),
|
|
871
|
+
version: z.literal(2)
|
|
872
|
+
});
|
|
873
|
+
const bridgeGetCurrentLevelRequestSchema = z.object({
|
|
874
|
+
requestId: requestIdSchema,
|
|
875
|
+
type: z.literal(BRIDGE_GET_CURRENT_LEVEL_REQUEST_TYPE),
|
|
876
|
+
version: z.literal(2)
|
|
877
|
+
});
|
|
878
|
+
const bridgeSpawnActorEntrySchema = z.object({
|
|
879
|
+
classPath: assetPathSchema,
|
|
880
|
+
folderPath: boundedStringSchema.optional(),
|
|
881
|
+
label: boundedStringSchema.optional(),
|
|
882
|
+
tags: actorTagArraySchema.default([]),
|
|
883
|
+
transform: transformInputSchema.default({
|
|
884
|
+
location: {
|
|
885
|
+
x: 0,
|
|
886
|
+
y: 0,
|
|
887
|
+
z: 0
|
|
888
|
+
},
|
|
889
|
+
rotation: {
|
|
890
|
+
pitch: 0,
|
|
891
|
+
roll: 0,
|
|
892
|
+
yaw: 0
|
|
893
|
+
},
|
|
894
|
+
scale: {
|
|
895
|
+
x: 1,
|
|
896
|
+
y: 1,
|
|
897
|
+
z: 1
|
|
898
|
+
}
|
|
899
|
+
})
|
|
900
|
+
});
|
|
901
|
+
const bridgeSpawnActorRequestSchema = z.object({
|
|
902
|
+
dryRun: z.boolean().default(false),
|
|
903
|
+
requestId: requestIdSchema,
|
|
904
|
+
spawns: z.array(bridgeSpawnActorEntrySchema).min(1).max(64),
|
|
905
|
+
type: z.literal(BRIDGE_SPAWN_ACTOR_REQUEST_TYPE),
|
|
906
|
+
version: z.literal(2)
|
|
907
|
+
});
|
|
908
|
+
const bridgeDestroyActorRequestSchema = z.object({
|
|
909
|
+
actorPaths: actorPathBatchSchema,
|
|
910
|
+
dryRun: z.boolean().default(false),
|
|
911
|
+
requestId: requestIdSchema,
|
|
912
|
+
type: z.literal(BRIDGE_DESTROY_ACTOR_REQUEST_TYPE),
|
|
913
|
+
version: z.literal(2)
|
|
914
|
+
});
|
|
915
|
+
const bridgeSetActorTransformEntrySchema = z.object({
|
|
916
|
+
actorPath: actorPathSchema,
|
|
917
|
+
location: vectorInputSchema.optional(),
|
|
918
|
+
rotation: rotatorInputSchema.optional(),
|
|
919
|
+
scale: vectorInputSchema.optional()
|
|
920
|
+
}).refine((entry) => entry.location !== void 0 || entry.rotation !== void 0 || entry.scale !== void 0, {
|
|
921
|
+
message: "A set_actor_transform entry must supply at least one of location, rotation or scale.",
|
|
922
|
+
path: ["location"]
|
|
923
|
+
});
|
|
924
|
+
const bridgeSetActorTransformRequestSchema = z.object({
|
|
925
|
+
dryRun: z.boolean().default(false),
|
|
926
|
+
requestId: requestIdSchema,
|
|
927
|
+
transforms: z.array(bridgeSetActorTransformEntrySchema).min(1).max(64),
|
|
928
|
+
type: z.literal(BRIDGE_SET_ACTOR_TRANSFORM_REQUEST_TYPE),
|
|
929
|
+
version: z.literal(2)
|
|
930
|
+
});
|
|
931
|
+
const bridgeSetActorPropertyEntrySchema = z.object({
|
|
932
|
+
actorPath: actorPathSchema,
|
|
933
|
+
propertyPath: z.string().trim().min(1).max(512),
|
|
934
|
+
value: z.string().max(BRIDGE_PROPERTY_VALUE_MAX_CHARS)
|
|
935
|
+
});
|
|
936
|
+
const bridgeSetActorPropertyRequestSchema = z.object({
|
|
937
|
+
dryRun: z.boolean().default(false),
|
|
938
|
+
properties: z.array(bridgeSetActorPropertyEntrySchema).min(1).max(64),
|
|
939
|
+
requestId: requestIdSchema,
|
|
940
|
+
type: z.literal(BRIDGE_SET_ACTOR_PROPERTY_REQUEST_TYPE),
|
|
941
|
+
version: z.literal(2)
|
|
942
|
+
});
|
|
943
|
+
const bridgeSelectActorsRequestSchema = z.object({
|
|
944
|
+
actorPaths: z.array(actorPathSchema).max(64).default([]),
|
|
945
|
+
addToSelection: z.boolean().default(false),
|
|
946
|
+
dryRun: z.boolean().default(false),
|
|
947
|
+
requestId: requestIdSchema,
|
|
948
|
+
type: z.literal(BRIDGE_SELECT_ACTORS_REQUEST_TYPE),
|
|
949
|
+
version: z.literal(2)
|
|
950
|
+
});
|
|
951
|
+
const bridgeUndoRequestSchema = z.object({
|
|
952
|
+
requestId: requestIdSchema,
|
|
953
|
+
type: z.literal(BRIDGE_UNDO_REQUEST_TYPE),
|
|
954
|
+
version: z.literal(2)
|
|
955
|
+
});
|
|
956
|
+
const bridgeRedoRequestSchema = z.object({
|
|
957
|
+
requestId: requestIdSchema,
|
|
958
|
+
type: z.literal(BRIDGE_REDO_REQUEST_TYPE),
|
|
959
|
+
version: z.literal(2)
|
|
960
|
+
});
|
|
961
|
+
const bridgeOpenLevelRequestSchema = z.object({
|
|
962
|
+
dryRun: z.boolean().default(false),
|
|
963
|
+
levelPath: levelPathSchema,
|
|
964
|
+
requestId: requestIdSchema,
|
|
965
|
+
saveDirtyPackages: z.boolean().default(false),
|
|
966
|
+
type: z.literal(BRIDGE_OPEN_LEVEL_REQUEST_TYPE),
|
|
967
|
+
version: z.literal(2)
|
|
968
|
+
});
|
|
969
|
+
const bridgeGetOpenLevelStatusRequestSchema = z.object({
|
|
970
|
+
openLevelJobId: openLevelJobIdSchema,
|
|
971
|
+
requestId: requestIdSchema,
|
|
972
|
+
type: z.literal(BRIDGE_GET_OPEN_LEVEL_STATUS_REQUEST_TYPE),
|
|
973
|
+
version: z.literal(2)
|
|
974
|
+
});
|
|
768
975
|
const bridgeGetAssetDependenciesRequestSchema = z.object({
|
|
769
976
|
assetPath: assetPathSchema,
|
|
770
977
|
categories: z.array(assetDependencyCategorySchema).max(BRIDGE_ASSET_DEPENDENCY_CATEGORIES.length).default(["package"]),
|
|
@@ -774,7 +981,7 @@ const bridgeGetAssetDependenciesRequestSchema = z.object({
|
|
|
774
981
|
referencerCursor: assetCursorSchema.default(0),
|
|
775
982
|
requestId: requestIdSchema,
|
|
776
983
|
type: z.literal(BRIDGE_GET_ASSET_DEPENDENCIES_REQUEST_TYPE),
|
|
777
|
-
version: z.literal(
|
|
984
|
+
version: z.literal(2)
|
|
778
985
|
});
|
|
779
986
|
const bridgeFindBlueprintReferencesRequestSchema = z.object({
|
|
780
987
|
className: assetPathSchema,
|
|
@@ -783,7 +990,7 @@ const bridgeFindBlueprintReferencesRequestSchema = z.object({
|
|
|
783
990
|
referenceKinds: z.array(blueprintReferenceKindSchema).max(BRIDGE_BLUEPRINT_REFERENCE_KINDS.length).default([]),
|
|
784
991
|
requestId: requestIdSchema,
|
|
785
992
|
type: z.literal(BRIDGE_FIND_BLUEPRINT_REFERENCES_REQUEST_TYPE),
|
|
786
|
-
version: z.literal(
|
|
993
|
+
version: z.literal(2)
|
|
787
994
|
});
|
|
788
995
|
const bridgeGetBlueprintSummaryRequestSchema = z.object({
|
|
789
996
|
blueprintPath: assetPathSchema,
|
|
@@ -795,7 +1002,7 @@ const bridgeGetBlueprintSummaryRequestSchema = z.object({
|
|
|
795
1002
|
requestId: requestIdSchema,
|
|
796
1003
|
type: z.literal(BRIDGE_GET_BLUEPRINT_SUMMARY_REQUEST_TYPE),
|
|
797
1004
|
variableCursor: assetCursorSchema.default(0),
|
|
798
|
-
version: z.literal(
|
|
1005
|
+
version: z.literal(2)
|
|
799
1006
|
});
|
|
800
1007
|
const bridgeGetBlueprintGraphRequestSchema = z.object({
|
|
801
1008
|
blueprintPath: assetPathSchema,
|
|
@@ -805,7 +1012,7 @@ const bridgeGetBlueprintGraphRequestSchema = z.object({
|
|
|
805
1012
|
nodeCursor: assetCursorSchema.default(0),
|
|
806
1013
|
requestId: requestIdSchema,
|
|
807
1014
|
type: z.literal(BRIDGE_GET_BLUEPRINT_GRAPH_REQUEST_TYPE),
|
|
808
|
-
version: z.literal(
|
|
1015
|
+
version: z.literal(2)
|
|
809
1016
|
});
|
|
810
1017
|
const bridgeGetBlueprintCompileErrorsRequestSchema = z.object({
|
|
811
1018
|
blueprintPaths: blueprintPathArraySchema,
|
|
@@ -813,13 +1020,13 @@ const bridgeGetBlueprintCompileErrorsRequestSchema = z.object({
|
|
|
813
1020
|
maxResults: assetMaxResultsSchema,
|
|
814
1021
|
requestId: requestIdSchema,
|
|
815
1022
|
type: z.literal(BRIDGE_GET_BLUEPRINT_COMPILE_ERRORS_REQUEST_TYPE),
|
|
816
|
-
version: z.literal(
|
|
1023
|
+
version: z.literal(2)
|
|
817
1024
|
});
|
|
818
1025
|
const bridgeCompileBlueprintRequestSchema = z.object({
|
|
819
1026
|
blueprintPaths: blueprintPathArraySchema,
|
|
820
1027
|
requestId: requestIdSchema,
|
|
821
1028
|
type: z.literal(BRIDGE_COMPILE_BLUEPRINT_REQUEST_TYPE),
|
|
822
|
-
version: z.literal(
|
|
1029
|
+
version: z.literal(2)
|
|
823
1030
|
});
|
|
824
1031
|
const bridgeGetBlueprintCompileStatusRequestSchema = z.object({
|
|
825
1032
|
compileJobId: blueprintCompileJobIdSchema,
|
|
@@ -827,7 +1034,7 @@ const bridgeGetBlueprintCompileStatusRequestSchema = z.object({
|
|
|
827
1034
|
maxResults: assetMaxResultsSchema,
|
|
828
1035
|
requestId: requestIdSchema,
|
|
829
1036
|
type: z.literal(BRIDGE_GET_BLUEPRINT_COMPILE_STATUS_REQUEST_TYPE),
|
|
830
|
-
version: z.literal(
|
|
1037
|
+
version: z.literal(2)
|
|
831
1038
|
});
|
|
832
1039
|
const bridgeGetConfigValueRequestSchema = z.object({
|
|
833
1040
|
file: configFileSchema,
|
|
@@ -835,7 +1042,7 @@ const bridgeGetConfigValueRequestSchema = z.object({
|
|
|
835
1042
|
requestId: requestIdSchema,
|
|
836
1043
|
section: configSectionSchema,
|
|
837
1044
|
type: z.literal(BRIDGE_GET_CONFIG_VALUE_REQUEST_TYPE),
|
|
838
|
-
version: z.literal(
|
|
1045
|
+
version: z.literal(2)
|
|
839
1046
|
});
|
|
840
1047
|
const bridgeSetConfigValueRequestSchema = z.object({
|
|
841
1048
|
file: configFileSchema,
|
|
@@ -845,7 +1052,7 @@ const bridgeSetConfigValueRequestSchema = z.object({
|
|
|
845
1052
|
section: configSectionSchema,
|
|
846
1053
|
type: z.literal(BRIDGE_SET_CONFIG_VALUE_REQUEST_TYPE),
|
|
847
1054
|
value: configValueSchema,
|
|
848
|
-
version: z.literal(
|
|
1055
|
+
version: z.literal(2)
|
|
849
1056
|
});
|
|
850
1057
|
const bridgeListConfigSectionRequestSchema = z.object({
|
|
851
1058
|
cursor: assetCursorSchema.default(0),
|
|
@@ -854,7 +1061,7 @@ const bridgeListConfigSectionRequestSchema = z.object({
|
|
|
854
1061
|
requestId: requestIdSchema,
|
|
855
1062
|
section: configSectionSchema,
|
|
856
1063
|
type: z.literal(BRIDGE_LIST_CONFIG_SECTION_REQUEST_TYPE),
|
|
857
|
-
version: z.literal(
|
|
1064
|
+
version: z.literal(2)
|
|
858
1065
|
});
|
|
859
1066
|
const bridgePingSuccessResponseSchema = z.object({
|
|
860
1067
|
ok: z.literal(true),
|
|
@@ -864,7 +1071,7 @@ const bridgePingSuccessResponseSchema = z.object({
|
|
|
864
1071
|
projectPath: z.string().trim().min(1),
|
|
865
1072
|
requestId: requestIdSchema,
|
|
866
1073
|
type: z.literal(BRIDGE_PING_REQUEST_TYPE),
|
|
867
|
-
version: z.literal(
|
|
1074
|
+
version: z.literal(2)
|
|
868
1075
|
});
|
|
869
1076
|
const bridgeLogEventSchema = z.object({
|
|
870
1077
|
category: z.string().trim().min(1).optional(),
|
|
@@ -884,7 +1091,7 @@ const bridgeLogSubscribeSuccessResponseSchema = z.object({
|
|
|
884
1091
|
source: logSourceSchema,
|
|
885
1092
|
subscriptionId: subscriptionIdSchema,
|
|
886
1093
|
type: z.literal(BRIDGE_SUBSCRIBE_LOGS_REQUEST_TYPE),
|
|
887
|
-
version: z.literal(
|
|
1094
|
+
version: z.literal(2)
|
|
888
1095
|
});
|
|
889
1096
|
const bridgeLogDrainSuccessResponseSchema = z.object({
|
|
890
1097
|
droppedCount: z.number().int().min(0),
|
|
@@ -895,14 +1102,14 @@ const bridgeLogDrainSuccessResponseSchema = z.object({
|
|
|
895
1102
|
source: logSourceSchema,
|
|
896
1103
|
subscriptionId: subscriptionIdSchema,
|
|
897
1104
|
type: z.literal(BRIDGE_DRAIN_LOGS_REQUEST_TYPE),
|
|
898
|
-
version: z.literal(
|
|
1105
|
+
version: z.literal(2)
|
|
899
1106
|
});
|
|
900
1107
|
const bridgeLogUnsubscribeSuccessResponseSchema = z.object({
|
|
901
1108
|
ok: z.literal(true),
|
|
902
1109
|
requestId: requestIdSchema,
|
|
903
1110
|
subscriptionId: subscriptionIdSchema,
|
|
904
1111
|
type: z.literal(BRIDGE_UNSUBSCRIBE_LOGS_REQUEST_TYPE),
|
|
905
|
-
version: z.literal(
|
|
1112
|
+
version: z.literal(2)
|
|
906
1113
|
});
|
|
907
1114
|
const bridgeStartPieSuccessResponseSchema = z.object({
|
|
908
1115
|
message: z.string().trim().min(1).optional(),
|
|
@@ -911,7 +1118,7 @@ const bridgeStartPieSuccessResponseSchema = z.object({
|
|
|
911
1118
|
requestId: requestIdSchema,
|
|
912
1119
|
state: pieStateSchema,
|
|
913
1120
|
type: z.literal(BRIDGE_START_PIE_REQUEST_TYPE),
|
|
914
|
-
version: z.literal(
|
|
1121
|
+
version: z.literal(2)
|
|
915
1122
|
});
|
|
916
1123
|
const bridgeGetPieStatusSuccessResponseSchema = z.object({
|
|
917
1124
|
errorCount: z.number().int().min(0).optional(),
|
|
@@ -922,7 +1129,7 @@ const bridgeGetPieStatusSuccessResponseSchema = z.object({
|
|
|
922
1129
|
startedAt: z.string().trim().min(1).optional(),
|
|
923
1130
|
state: pieStatusStateSchema,
|
|
924
1131
|
type: z.literal(BRIDGE_GET_PIE_STATUS_REQUEST_TYPE),
|
|
925
|
-
version: z.literal(
|
|
1132
|
+
version: z.literal(2)
|
|
926
1133
|
});
|
|
927
1134
|
const bridgeLaunchDeviceSchema = z.object({
|
|
928
1135
|
deviceId: z.string(),
|
|
@@ -936,7 +1143,7 @@ const bridgeListLaunchDevicesSuccessResponseSchema = z.object({
|
|
|
936
1143
|
ok: z.literal(true),
|
|
937
1144
|
requestId: requestIdSchema,
|
|
938
1145
|
type: z.literal(BRIDGE_LIST_LAUNCH_DEVICES_REQUEST_TYPE),
|
|
939
|
-
version: z.literal(
|
|
1146
|
+
version: z.literal(2)
|
|
940
1147
|
});
|
|
941
1148
|
const bridgeLaunchOnDeviceSuccessResponseSchema = z.object({
|
|
942
1149
|
launchSessionId: pieSessionIdSchema,
|
|
@@ -945,7 +1152,7 @@ const bridgeLaunchOnDeviceSuccessResponseSchema = z.object({
|
|
|
945
1152
|
requestId: requestIdSchema,
|
|
946
1153
|
state: launchStateSchema,
|
|
947
1154
|
type: z.literal(BRIDGE_LAUNCH_ON_DEVICE_REQUEST_TYPE),
|
|
948
|
-
version: z.literal(
|
|
1155
|
+
version: z.literal(2)
|
|
949
1156
|
});
|
|
950
1157
|
const bridgeStopPieSuccessResponseSchema = z.object({
|
|
951
1158
|
message: z.string().trim().min(1).optional(),
|
|
@@ -954,7 +1161,7 @@ const bridgeStopPieSuccessResponseSchema = z.object({
|
|
|
954
1161
|
state: pieStatusStateSchema,
|
|
955
1162
|
stopped: z.boolean(),
|
|
956
1163
|
type: z.literal(BRIDGE_STOP_PIE_REQUEST_TYPE),
|
|
957
|
-
version: z.literal(
|
|
1164
|
+
version: z.literal(2)
|
|
958
1165
|
}).refine((value) => !value.stopped || value.state === "stopped", {
|
|
959
1166
|
message: "A stop_pie response with stopped=true must report state 'stopped'.",
|
|
960
1167
|
path: ["state"]
|
|
@@ -966,7 +1173,7 @@ const bridgeStartLiveCompileSuccessResponseSchema = z.object({
|
|
|
966
1173
|
requestId: requestIdSchema,
|
|
967
1174
|
state: liveCompileStateSchema,
|
|
968
1175
|
type: z.literal(BRIDGE_START_LIVE_COMPILE_REQUEST_TYPE),
|
|
969
|
-
version: z.literal(
|
|
1176
|
+
version: z.literal(2)
|
|
970
1177
|
});
|
|
971
1178
|
const bridgeStartHotReloadSuccessResponseSchema = z.object({
|
|
972
1179
|
compileJobId: z.string().trim().min(1),
|
|
@@ -975,7 +1182,7 @@ const bridgeStartHotReloadSuccessResponseSchema = z.object({
|
|
|
975
1182
|
requestId: requestIdSchema,
|
|
976
1183
|
state: hotReloadStateSchema,
|
|
977
1184
|
type: z.literal(BRIDGE_START_HOT_RELOAD_REQUEST_TYPE),
|
|
978
|
-
version: z.literal(
|
|
1185
|
+
version: z.literal(2)
|
|
979
1186
|
});
|
|
980
1187
|
const bridgeCompileDiagnosticSchema = z.object({
|
|
981
1188
|
file: z.string().trim().min(1).optional(),
|
|
@@ -994,7 +1201,7 @@ const bridgeGetCompileStatusSuccessResponseSchema = z.object({
|
|
|
994
1201
|
restartReason: z.string().trim().min(1).optional(),
|
|
995
1202
|
state: compileStatusStateSchema,
|
|
996
1203
|
type: z.literal(BRIDGE_GET_COMPILE_STATUS_REQUEST_TYPE),
|
|
997
|
-
version: z.literal(
|
|
1204
|
+
version: z.literal(2),
|
|
998
1205
|
warningCount: z.number().int().min(0),
|
|
999
1206
|
warnings: z.array(bridgeCompileDiagnosticSchema)
|
|
1000
1207
|
}).superRefine((value, ctx) => {
|
|
@@ -1023,7 +1230,7 @@ const bridgeListAutomationTestsSuccessResponseSchema = z.object({
|
|
|
1023
1230
|
totalCount: z.number().int().min(0),
|
|
1024
1231
|
truncated: z.boolean(),
|
|
1025
1232
|
type: z.literal(BRIDGE_LIST_AUTOMATION_TESTS_REQUEST_TYPE),
|
|
1026
|
-
version: z.literal(
|
|
1233
|
+
version: z.literal(2)
|
|
1027
1234
|
});
|
|
1028
1235
|
const bridgeStartAutomationRunSuccessResponseSchema = z.object({
|
|
1029
1236
|
message: nonEmptyStringSchema.optional(),
|
|
@@ -1033,7 +1240,7 @@ const bridgeStartAutomationRunSuccessResponseSchema = z.object({
|
|
|
1033
1240
|
state: automationRunStateSchema,
|
|
1034
1241
|
testRunId: testRunIdSchema,
|
|
1035
1242
|
type: z.literal(BRIDGE_START_AUTOMATION_RUN_REQUEST_TYPE),
|
|
1036
|
-
version: z.literal(
|
|
1243
|
+
version: z.literal(2)
|
|
1037
1244
|
});
|
|
1038
1245
|
const bridgeAutomationResultEntrySchema = z.object({
|
|
1039
1246
|
file: z.string().optional(),
|
|
@@ -1067,7 +1274,7 @@ const bridgeGetAutomationRunStatusSuccessResponseSchema = z.object({
|
|
|
1067
1274
|
totalCount: z.number().int().min(0),
|
|
1068
1275
|
truncated: z.boolean(),
|
|
1069
1276
|
type: z.literal(BRIDGE_GET_AUTOMATION_RUN_STATUS_REQUEST_TYPE),
|
|
1070
|
-
version: z.literal(
|
|
1277
|
+
version: z.literal(2)
|
|
1071
1278
|
});
|
|
1072
1279
|
const bridgeCancelAutomationRunSuccessResponseSchema = z.object({
|
|
1073
1280
|
cancelled: z.boolean(),
|
|
@@ -1077,7 +1284,7 @@ const bridgeCancelAutomationRunSuccessResponseSchema = z.object({
|
|
|
1077
1284
|
state: cancelAutomationRunStateSchema,
|
|
1078
1285
|
testRunId: testRunIdSchema,
|
|
1079
1286
|
type: z.literal(BRIDGE_CANCEL_AUTOMATION_RUN_REQUEST_TYPE),
|
|
1080
|
-
version: z.literal(
|
|
1287
|
+
version: z.literal(2)
|
|
1081
1288
|
}).refine((value) => value.cancelled === (value.state === "cancelled"), {
|
|
1082
1289
|
message: "A cancel_automation_run response must report cancelled=true exactly when state is 'cancelled'.",
|
|
1083
1290
|
path: ["state"]
|
|
@@ -1095,7 +1302,7 @@ const bridgeGetEditorStateSuccessResponseSchema = z.object({
|
|
|
1095
1302
|
selectedActors: selectedActorArraySchema,
|
|
1096
1303
|
truncated: z.boolean(),
|
|
1097
1304
|
type: z.literal(BRIDGE_GET_EDITOR_STATE_REQUEST_TYPE),
|
|
1098
|
-
version: z.literal(
|
|
1305
|
+
version: z.literal(2)
|
|
1099
1306
|
});
|
|
1100
1307
|
const bridgeSaveDirtyPackagesSuccessResponseSchema = z.object({
|
|
1101
1308
|
failedCount: z.number().int().min(0),
|
|
@@ -1107,7 +1314,7 @@ const bridgeSaveDirtyPackagesSuccessResponseSchema = z.object({
|
|
|
1107
1314
|
savedPackages: packageNameArraySchema,
|
|
1108
1315
|
truncated: z.boolean(),
|
|
1109
1316
|
type: z.literal(BRIDGE_SAVE_DIRTY_PACKAGES_REQUEST_TYPE),
|
|
1110
|
-
version: z.literal(
|
|
1317
|
+
version: z.literal(2)
|
|
1111
1318
|
});
|
|
1112
1319
|
const bridgeCaptureViewportSuccessResponseSchema = z.object({
|
|
1113
1320
|
height: z.number().int().min(1),
|
|
@@ -1115,7 +1322,7 @@ const bridgeCaptureViewportSuccessResponseSchema = z.object({
|
|
|
1115
1322
|
path: screenshotPathSchema,
|
|
1116
1323
|
requestId: requestIdSchema,
|
|
1117
1324
|
type: z.literal(BRIDGE_CAPTURE_VIEWPORT_REQUEST_TYPE),
|
|
1118
|
-
version: z.literal(
|
|
1325
|
+
version: z.literal(2),
|
|
1119
1326
|
width: z.number().int().min(1)
|
|
1120
1327
|
});
|
|
1121
1328
|
const bridgeReflectionMetadataEntrySchema = z.object({
|
|
@@ -1159,7 +1366,7 @@ const bridgeGetClassReflectionSuccessResponseSchema = z.object({
|
|
|
1159
1366
|
requestId: requestIdSchema,
|
|
1160
1367
|
truncated: z.boolean(),
|
|
1161
1368
|
type: z.literal(BRIDGE_GET_CLASS_REFLECTION_REQUEST_TYPE),
|
|
1162
|
-
version: z.literal(
|
|
1369
|
+
version: z.literal(2)
|
|
1163
1370
|
});
|
|
1164
1371
|
const bridgeCdoPropertyValueSchema = z.object({
|
|
1165
1372
|
name: z.string(),
|
|
@@ -1177,7 +1384,7 @@ const bridgeGetCdoDefaultsSuccessResponseSchema = z.object({
|
|
|
1177
1384
|
totalCount: z.number().int().min(0),
|
|
1178
1385
|
truncated: z.boolean(),
|
|
1179
1386
|
type: z.literal(BRIDGE_GET_CDO_DEFAULTS_REQUEST_TYPE),
|
|
1180
|
-
version: z.literal(
|
|
1387
|
+
version: z.literal(2)
|
|
1181
1388
|
});
|
|
1182
1389
|
const bridgeCrashFrameSchema = z.object({
|
|
1183
1390
|
address: nonEmptyStringSchema,
|
|
@@ -1204,7 +1411,7 @@ const bridgeGetCrashCallstackSuccessResponseSchema = z.object({
|
|
|
1204
1411
|
totalCount: z.number().int().min(0),
|
|
1205
1412
|
truncated: z.boolean(),
|
|
1206
1413
|
type: z.literal(BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE),
|
|
1207
|
-
version: z.literal(
|
|
1414
|
+
version: z.literal(2)
|
|
1208
1415
|
});
|
|
1209
1416
|
const bridgeExecConsoleCommandSuccessResponseSchema = z.object({
|
|
1210
1417
|
handled: z.boolean(),
|
|
@@ -1214,7 +1421,7 @@ const bridgeExecConsoleCommandSuccessResponseSchema = z.object({
|
|
|
1214
1421
|
target: execConsoleTargetSchema,
|
|
1215
1422
|
truncated: z.boolean(),
|
|
1216
1423
|
type: z.literal(BRIDGE_EXEC_CONSOLE_COMMAND_REQUEST_TYPE),
|
|
1217
|
-
version: z.literal(
|
|
1424
|
+
version: z.literal(2)
|
|
1218
1425
|
});
|
|
1219
1426
|
const bridgeMemorySnapshotSchema = z.object({
|
|
1220
1427
|
availablePhysicalMb: memoryMegabytesSchema,
|
|
@@ -1233,7 +1440,7 @@ const bridgeStatSnapshotSuccessResponseSchema = z.object({
|
|
|
1233
1440
|
renderThreadTimeMs: frameTimingMillisecondsSchema.optional(),
|
|
1234
1441
|
requestId: requestIdSchema,
|
|
1235
1442
|
type: z.literal(BRIDGE_STAT_SNAPSHOT_REQUEST_TYPE),
|
|
1236
|
-
version: z.literal(
|
|
1443
|
+
version: z.literal(2)
|
|
1237
1444
|
});
|
|
1238
1445
|
const bridgeStartTraceSuccessResponseSchema = z.object({
|
|
1239
1446
|
message: nonEmptyStringSchema.optional(),
|
|
@@ -1242,7 +1449,7 @@ const bridgeStartTraceSuccessResponseSchema = z.object({
|
|
|
1242
1449
|
state: startTraceStateSchema,
|
|
1243
1450
|
tracePath: nonEmptyStringSchema.optional(),
|
|
1244
1451
|
type: z.literal(BRIDGE_START_TRACE_REQUEST_TYPE),
|
|
1245
|
-
version: z.literal(
|
|
1452
|
+
version: z.literal(2)
|
|
1246
1453
|
}).refine((value) => value.state !== "unsupported" || value.tracePath === void 0, {
|
|
1247
1454
|
message: "A start_trace response with state 'unsupported' must not report a tracePath.",
|
|
1248
1455
|
path: ["tracePath"]
|
|
@@ -1254,7 +1461,7 @@ const bridgeStopTraceSuccessResponseSchema = z.object({
|
|
|
1254
1461
|
state: stopTraceStateSchema,
|
|
1255
1462
|
tracePath: nonEmptyStringSchema.optional(),
|
|
1256
1463
|
type: z.literal(BRIDGE_STOP_TRACE_REQUEST_TYPE),
|
|
1257
|
-
version: z.literal(
|
|
1464
|
+
version: z.literal(2)
|
|
1258
1465
|
}).refine((value) => value.state === "stopped" || value.tracePath === void 0, {
|
|
1259
1466
|
message: "A stop_trace response may only report a tracePath when state is 'stopped'.",
|
|
1260
1467
|
path: ["tracePath"]
|
|
@@ -1266,7 +1473,7 @@ const bridgeCreateCppClassSuccessResponseSchema = z.object({
|
|
|
1266
1473
|
requestId: requestIdSchema,
|
|
1267
1474
|
state: createClassStateSchema,
|
|
1268
1475
|
type: z.literal(BRIDGE_CREATE_CPP_CLASS_REQUEST_TYPE),
|
|
1269
|
-
version: z.literal(
|
|
1476
|
+
version: z.literal(2)
|
|
1270
1477
|
}).refine((value) => value.state === "creating" === (value.createClassJobId !== void 0), {
|
|
1271
1478
|
message: "A create_cpp_class response must carry createClassJobId exactly when state is 'creating'.",
|
|
1272
1479
|
path: ["createClassJobId"]
|
|
@@ -1283,7 +1490,7 @@ const bridgeGetCreateClassStatusSuccessResponseSchema = z.object({
|
|
|
1283
1490
|
sourcePath: sourceFilePathSchema.optional(),
|
|
1284
1491
|
state: createClassStatusStateSchema,
|
|
1285
1492
|
type: z.literal(BRIDGE_GET_CREATE_CLASS_STATUS_REQUEST_TYPE),
|
|
1286
|
-
version: z.literal(
|
|
1493
|
+
version: z.literal(2)
|
|
1287
1494
|
}).superRefine((value, ctx) => {
|
|
1288
1495
|
if (value.state !== "succeeded" && value.reloaded !== void 0) ctx.addIssue({
|
|
1289
1496
|
code: z.ZodIssueCode.custom,
|
|
@@ -1318,7 +1525,194 @@ const bridgeFindAssetsSuccessResponseSchema = z.object({
|
|
|
1318
1525
|
totalCount: z.number().int().min(0),
|
|
1319
1526
|
truncated: z.boolean(),
|
|
1320
1527
|
type: z.literal(BRIDGE_FIND_ASSETS_REQUEST_TYPE),
|
|
1321
|
-
version: z.literal(
|
|
1528
|
+
version: z.literal(2)
|
|
1529
|
+
});
|
|
1530
|
+
const bridgeActorSummarySchema = z.object({
|
|
1531
|
+
actorPath: z.string(),
|
|
1532
|
+
className: z.string(),
|
|
1533
|
+
folderPath: z.string(),
|
|
1534
|
+
label: z.string(),
|
|
1535
|
+
levelName: z.string()
|
|
1536
|
+
});
|
|
1537
|
+
const bridgeListActorsSuccessResponseSchema = z.object({
|
|
1538
|
+
actors: z.array(bridgeActorSummarySchema).max(100),
|
|
1539
|
+
message: z.string().trim().min(1).optional(),
|
|
1540
|
+
nextCursor: levelCursorSchema.optional(),
|
|
1541
|
+
ok: z.literal(true),
|
|
1542
|
+
requestId: requestIdSchema,
|
|
1543
|
+
totalCount: z.number().int().min(0),
|
|
1544
|
+
truncated: z.boolean(),
|
|
1545
|
+
type: z.literal(BRIDGE_LIST_ACTORS_REQUEST_TYPE),
|
|
1546
|
+
version: z.literal(2)
|
|
1547
|
+
});
|
|
1548
|
+
const bridgeVectorSchema = z.object({
|
|
1549
|
+
x: z.number(),
|
|
1550
|
+
y: z.number(),
|
|
1551
|
+
z: z.number()
|
|
1552
|
+
});
|
|
1553
|
+
const bridgeRotatorSchema = z.object({
|
|
1554
|
+
pitch: z.number(),
|
|
1555
|
+
roll: z.number(),
|
|
1556
|
+
yaw: z.number()
|
|
1557
|
+
});
|
|
1558
|
+
const bridgeTransformSchema = z.object({
|
|
1559
|
+
location: bridgeVectorSchema,
|
|
1560
|
+
rotation: bridgeRotatorSchema,
|
|
1561
|
+
scale: bridgeVectorSchema
|
|
1562
|
+
});
|
|
1563
|
+
const bridgeActorComponentSchema = z.object({
|
|
1564
|
+
className: z.string(),
|
|
1565
|
+
name: z.string(),
|
|
1566
|
+
parentName: z.string().optional(),
|
|
1567
|
+
relativeTransform: bridgeTransformSchema.optional()
|
|
1568
|
+
});
|
|
1569
|
+
const bridgeActorPropertySchema = z.object({
|
|
1570
|
+
isEditable: z.boolean(),
|
|
1571
|
+
name: z.string(),
|
|
1572
|
+
type: z.string(),
|
|
1573
|
+
value: z.string(),
|
|
1574
|
+
valueTruncated: z.boolean()
|
|
1575
|
+
});
|
|
1576
|
+
const bridgeGetActorDetailsSuccessResponseSchema = z.object({
|
|
1577
|
+
actorPath: z.string(),
|
|
1578
|
+
className: z.string(),
|
|
1579
|
+
componentCount: z.number().int().min(0),
|
|
1580
|
+
components: z.array(bridgeActorComponentSchema).max(200),
|
|
1581
|
+
componentTruncated: z.boolean(),
|
|
1582
|
+
folderPath: z.string(),
|
|
1583
|
+
label: z.string(),
|
|
1584
|
+
levelName: z.string(),
|
|
1585
|
+
nextComponentCursor: levelCursorSchema.optional(),
|
|
1586
|
+
nextPropertyCursor: levelCursorSchema.optional(),
|
|
1587
|
+
ok: z.literal(true),
|
|
1588
|
+
properties: z.array(bridgeActorPropertySchema).max(200),
|
|
1589
|
+
propertyCount: z.number().int().min(0),
|
|
1590
|
+
propertyTruncated: z.boolean(),
|
|
1591
|
+
requestId: requestIdSchema,
|
|
1592
|
+
transform: bridgeTransformSchema,
|
|
1593
|
+
type: z.literal(BRIDGE_GET_ACTOR_DETAILS_REQUEST_TYPE),
|
|
1594
|
+
version: z.literal(2)
|
|
1595
|
+
});
|
|
1596
|
+
const bridgeStreamingLevelSchema = z.object({
|
|
1597
|
+
isLoaded: z.boolean(),
|
|
1598
|
+
isVisible: z.boolean(),
|
|
1599
|
+
packageName: z.string()
|
|
1600
|
+
});
|
|
1601
|
+
const bridgeGetCurrentLevelSuccessResponseSchema = z.object({
|
|
1602
|
+
levelName: z.string().trim().min(1).optional(),
|
|
1603
|
+
levelPath: z.string().trim().min(1).optional(),
|
|
1604
|
+
message: z.string().trim().min(1).optional(),
|
|
1605
|
+
ok: z.literal(true),
|
|
1606
|
+
requestId: requestIdSchema,
|
|
1607
|
+
streamingLevelCount: z.number().int().min(0),
|
|
1608
|
+
streamingLevels: z.array(bridgeStreamingLevelSchema).max(100),
|
|
1609
|
+
truncated: z.boolean(),
|
|
1610
|
+
type: z.literal(BRIDGE_GET_CURRENT_LEVEL_REQUEST_TYPE),
|
|
1611
|
+
version: z.literal(2),
|
|
1612
|
+
worldPartition: z.boolean()
|
|
1613
|
+
});
|
|
1614
|
+
const bridgeLevelEditResultSchema = z.object({
|
|
1615
|
+
actorPath: z.string().optional(),
|
|
1616
|
+
error: z.string().optional(),
|
|
1617
|
+
index: z.number().int().min(0),
|
|
1618
|
+
ok: z.boolean()
|
|
1619
|
+
});
|
|
1620
|
+
const levelEditResponseFields = {
|
|
1621
|
+
dryRun: z.boolean(),
|
|
1622
|
+
failureCount: z.number().int().min(0),
|
|
1623
|
+
message: z.string().trim().min(1).optional(),
|
|
1624
|
+
ok: z.literal(true),
|
|
1625
|
+
requestId: requestIdSchema,
|
|
1626
|
+
results: z.array(bridgeLevelEditResultSchema).max(64),
|
|
1627
|
+
state: levelEditStateSchema,
|
|
1628
|
+
successCount: z.number().int().min(0),
|
|
1629
|
+
transactionTitle: z.string().trim().min(1).optional(),
|
|
1630
|
+
version: z.literal(2)
|
|
1631
|
+
};
|
|
1632
|
+
function isLevelEditStateConsistent(value) {
|
|
1633
|
+
if (value.state === "applied") return !value.dryRun;
|
|
1634
|
+
if (value.state === "validated") return value.dryRun;
|
|
1635
|
+
return true;
|
|
1636
|
+
}
|
|
1637
|
+
const levelEditStateRefinement = {
|
|
1638
|
+
message: "A mutating response must report state 'applied' only for a real run and 'validated' only for a dryRun.",
|
|
1639
|
+
path: ["state"]
|
|
1640
|
+
};
|
|
1641
|
+
const bridgeSpawnActorSuccessResponseSchema = z.object({
|
|
1642
|
+
...levelEditResponseFields,
|
|
1643
|
+
type: z.literal(BRIDGE_SPAWN_ACTOR_REQUEST_TYPE)
|
|
1644
|
+
}).refine(isLevelEditStateConsistent, levelEditStateRefinement);
|
|
1645
|
+
const bridgeDestroyActorSuccessResponseSchema = z.object({
|
|
1646
|
+
...levelEditResponseFields,
|
|
1647
|
+
type: z.literal(BRIDGE_DESTROY_ACTOR_REQUEST_TYPE)
|
|
1648
|
+
}).refine(isLevelEditStateConsistent, levelEditStateRefinement);
|
|
1649
|
+
const bridgeSetActorTransformSuccessResponseSchema = z.object({
|
|
1650
|
+
...levelEditResponseFields,
|
|
1651
|
+
type: z.literal(BRIDGE_SET_ACTOR_TRANSFORM_REQUEST_TYPE)
|
|
1652
|
+
}).refine(isLevelEditStateConsistent, levelEditStateRefinement);
|
|
1653
|
+
const bridgeSetActorPropertySuccessResponseSchema = z.object({
|
|
1654
|
+
...levelEditResponseFields,
|
|
1655
|
+
type: z.literal(BRIDGE_SET_ACTOR_PROPERTY_REQUEST_TYPE)
|
|
1656
|
+
}).refine(isLevelEditStateConsistent, levelEditStateRefinement);
|
|
1657
|
+
const bridgeSelectActorsSuccessResponseSchema = z.object({
|
|
1658
|
+
...levelEditResponseFields,
|
|
1659
|
+
selectedActorCount: z.number().int().min(0),
|
|
1660
|
+
type: z.literal(BRIDGE_SELECT_ACTORS_REQUEST_TYPE)
|
|
1661
|
+
}).refine(isLevelEditStateConsistent, levelEditStateRefinement);
|
|
1662
|
+
const bridgeUndoSuccessResponseSchema = z.object({
|
|
1663
|
+
message: z.string().trim().min(1).optional(),
|
|
1664
|
+
ok: z.literal(true),
|
|
1665
|
+
requestId: requestIdSchema,
|
|
1666
|
+
state: undoStateSchema,
|
|
1667
|
+
transactionTitle: z.string().trim().min(1).optional(),
|
|
1668
|
+
type: z.literal(BRIDGE_UNDO_REQUEST_TYPE),
|
|
1669
|
+
version: z.literal(2)
|
|
1670
|
+
});
|
|
1671
|
+
const bridgeRedoSuccessResponseSchema = z.object({
|
|
1672
|
+
message: z.string().trim().min(1).optional(),
|
|
1673
|
+
ok: z.literal(true),
|
|
1674
|
+
requestId: requestIdSchema,
|
|
1675
|
+
state: redoStateSchema,
|
|
1676
|
+
transactionTitle: z.string().trim().min(1).optional(),
|
|
1677
|
+
type: z.literal(BRIDGE_REDO_REQUEST_TYPE),
|
|
1678
|
+
version: z.literal(2)
|
|
1679
|
+
});
|
|
1680
|
+
const bridgeOpenLevelSuccessResponseSchema = z.object({
|
|
1681
|
+
levelPath: levelPathSchema.optional(),
|
|
1682
|
+
message: nonEmptyStringSchema.optional(),
|
|
1683
|
+
ok: z.literal(true),
|
|
1684
|
+
openLevelJobId: openLevelJobIdSchema.optional(),
|
|
1685
|
+
requestId: requestIdSchema,
|
|
1686
|
+
state: openLevelStateSchema,
|
|
1687
|
+
type: z.literal(BRIDGE_OPEN_LEVEL_REQUEST_TYPE),
|
|
1688
|
+
version: z.literal(2)
|
|
1689
|
+
}).refine((value) => value.state === "opening" === (value.openLevelJobId !== void 0), {
|
|
1690
|
+
message: "An open_level response must carry openLevelJobId exactly when state is 'opening'.",
|
|
1691
|
+
path: ["openLevelJobId"]
|
|
1692
|
+
});
|
|
1693
|
+
const bridgeGetOpenLevelStatusSuccessResponseSchema = z.object({
|
|
1694
|
+
durationMs: z.number().int().min(0).optional(),
|
|
1695
|
+
finishedAt: nonEmptyStringSchema.optional(),
|
|
1696
|
+
levelPath: levelPathSchema.optional(),
|
|
1697
|
+
message: nonEmptyStringSchema.optional(),
|
|
1698
|
+
ok: z.literal(true),
|
|
1699
|
+
openLevelJobId: openLevelJobIdSchema,
|
|
1700
|
+
requestId: requestIdSchema,
|
|
1701
|
+
state: openLevelStatusStateSchema,
|
|
1702
|
+
type: z.literal(BRIDGE_GET_OPEN_LEVEL_STATUS_REQUEST_TYPE),
|
|
1703
|
+
version: z.literal(2)
|
|
1704
|
+
}).superRefine((value, ctx) => {
|
|
1705
|
+
if (value.state === "succeeded" || value.state === "failed") return;
|
|
1706
|
+
if (value.durationMs !== void 0) ctx.addIssue({
|
|
1707
|
+
code: z.ZodIssueCode.custom,
|
|
1708
|
+
message: "durationMs must be absent until the load finishes",
|
|
1709
|
+
path: ["durationMs"]
|
|
1710
|
+
});
|
|
1711
|
+
if (value.finishedAt !== void 0) ctx.addIssue({
|
|
1712
|
+
code: z.ZodIssueCode.custom,
|
|
1713
|
+
message: "finishedAt must be absent until the load finishes",
|
|
1714
|
+
path: ["finishedAt"]
|
|
1715
|
+
});
|
|
1322
1716
|
});
|
|
1323
1717
|
const bridgeAssetDependencySchema = z.object({
|
|
1324
1718
|
category: assetDependencyCategorySchema,
|
|
@@ -1339,7 +1733,7 @@ const bridgeGetAssetDependenciesSuccessResponseSchema = z.object({
|
|
|
1339
1733
|
requestId: requestIdSchema,
|
|
1340
1734
|
scanning: z.boolean(),
|
|
1341
1735
|
type: z.literal(BRIDGE_GET_ASSET_DEPENDENCIES_REQUEST_TYPE),
|
|
1342
|
-
version: z.literal(
|
|
1736
|
+
version: z.literal(2)
|
|
1343
1737
|
});
|
|
1344
1738
|
const bridgeBlueprintReferenceSchema = z.object({
|
|
1345
1739
|
assetName: z.string(),
|
|
@@ -1358,7 +1752,7 @@ const bridgeFindBlueprintReferencesSuccessResponseSchema = z.object({
|
|
|
1358
1752
|
totalCount: z.number().int().min(0),
|
|
1359
1753
|
truncated: z.boolean(),
|
|
1360
1754
|
type: z.literal(BRIDGE_FIND_BLUEPRINT_REFERENCES_REQUEST_TYPE),
|
|
1361
|
-
version: z.literal(
|
|
1755
|
+
version: z.literal(2)
|
|
1362
1756
|
});
|
|
1363
1757
|
const bridgeBlueprintComponentSchema = z.object({
|
|
1364
1758
|
className: z.string(),
|
|
@@ -1411,7 +1805,7 @@ const bridgeGetBlueprintSummarySuccessResponseSchema = z.object({
|
|
|
1411
1805
|
type: z.literal(BRIDGE_GET_BLUEPRINT_SUMMARY_REQUEST_TYPE),
|
|
1412
1806
|
variableCount: z.number().int().min(0),
|
|
1413
1807
|
variables: z.array(bridgeBlueprintVariableSchema),
|
|
1414
|
-
version: z.literal(
|
|
1808
|
+
version: z.literal(2)
|
|
1415
1809
|
});
|
|
1416
1810
|
const bridgeBlueprintPinLinkSchema = z.object({
|
|
1417
1811
|
nodeId: z.string(),
|
|
@@ -1445,7 +1839,7 @@ const bridgeGetBlueprintGraphSuccessResponseSchema = z.object({
|
|
|
1445
1839
|
requestId: requestIdSchema,
|
|
1446
1840
|
truncated: z.boolean(),
|
|
1447
1841
|
type: z.literal(BRIDGE_GET_BLUEPRINT_GRAPH_REQUEST_TYPE),
|
|
1448
|
-
version: z.literal(
|
|
1842
|
+
version: z.literal(2)
|
|
1449
1843
|
});
|
|
1450
1844
|
const bridgeBlueprintCompileDiagnosticSchema = bridgeCompileDiagnosticSchema.extend({
|
|
1451
1845
|
graphName: z.string().optional(),
|
|
@@ -1470,7 +1864,7 @@ const bridgeGetBlueprintCompileErrorsSuccessResponseSchema = z.object({
|
|
|
1470
1864
|
totalCount: z.number().int().min(0),
|
|
1471
1865
|
truncated: z.boolean(),
|
|
1472
1866
|
type: z.literal(BRIDGE_GET_BLUEPRINT_COMPILE_ERRORS_REQUEST_TYPE),
|
|
1473
|
-
version: z.literal(
|
|
1867
|
+
version: z.literal(2)
|
|
1474
1868
|
});
|
|
1475
1869
|
const bridgeCompileBlueprintSuccessResponseSchema = z.object({
|
|
1476
1870
|
compileJobId: blueprintCompileJobIdSchema.optional(),
|
|
@@ -1479,7 +1873,7 @@ const bridgeCompileBlueprintSuccessResponseSchema = z.object({
|
|
|
1479
1873
|
requestId: requestIdSchema,
|
|
1480
1874
|
state: compileBlueprintStateSchema,
|
|
1481
1875
|
type: z.literal(BRIDGE_COMPILE_BLUEPRINT_REQUEST_TYPE),
|
|
1482
|
-
version: z.literal(
|
|
1876
|
+
version: z.literal(2)
|
|
1483
1877
|
}).refine((value) => value.state === "compiling" === (value.compileJobId !== void 0), {
|
|
1484
1878
|
message: "A compile_blueprint response must carry compileJobId exactly when state is 'compiling'.",
|
|
1485
1879
|
path: ["compileJobId"]
|
|
@@ -1496,7 +1890,7 @@ const bridgeGetBlueprintCompileStatusSuccessResponseSchema = z.object({
|
|
|
1496
1890
|
totalCount: z.number().int().min(0),
|
|
1497
1891
|
truncated: z.boolean(),
|
|
1498
1892
|
type: z.literal(BRIDGE_GET_BLUEPRINT_COMPILE_STATUS_REQUEST_TYPE),
|
|
1499
|
-
version: z.literal(
|
|
1893
|
+
version: z.literal(2)
|
|
1500
1894
|
}).superRefine((value, ctx) => {
|
|
1501
1895
|
if (value.state === "succeeded" || value.state === "failed") return;
|
|
1502
1896
|
for (const field of ["durationMs", "finishedAt"]) if (value[field] !== void 0) ctx.addIssue({
|
|
@@ -1522,7 +1916,7 @@ const bridgeGetConfigValueSuccessResponseSchema = z.object({
|
|
|
1522
1916
|
type: z.literal(BRIDGE_GET_CONFIG_VALUE_REQUEST_TYPE),
|
|
1523
1917
|
value: configValueSchema.optional(),
|
|
1524
1918
|
valueTruncated: z.boolean().optional(),
|
|
1525
|
-
version: z.literal(
|
|
1919
|
+
version: z.literal(2)
|
|
1526
1920
|
});
|
|
1527
1921
|
const bridgeSetConfigValueSuccessResponseSchema = z.object({
|
|
1528
1922
|
file: configFileSchema,
|
|
@@ -1537,7 +1931,7 @@ const bridgeSetConfigValueSuccessResponseSchema = z.object({
|
|
|
1537
1931
|
section: configSectionSchema,
|
|
1538
1932
|
type: z.literal(BRIDGE_SET_CONFIG_VALUE_REQUEST_TYPE),
|
|
1539
1933
|
value: configValueSchema,
|
|
1540
|
-
version: z.literal(
|
|
1934
|
+
version: z.literal(2)
|
|
1541
1935
|
});
|
|
1542
1936
|
const bridgeListConfigSectionSuccessResponseSchema = z.object({
|
|
1543
1937
|
entries: z.array(bridgeConfigEntrySchema).max(200),
|
|
@@ -1549,13 +1943,13 @@ const bridgeListConfigSectionSuccessResponseSchema = z.object({
|
|
|
1549
1943
|
totalCount: z.number().int().min(0),
|
|
1550
1944
|
truncated: z.boolean(),
|
|
1551
1945
|
type: z.literal(BRIDGE_LIST_CONFIG_SECTION_REQUEST_TYPE),
|
|
1552
|
-
version: z.literal(
|
|
1946
|
+
version: z.literal(2)
|
|
1553
1947
|
});
|
|
1554
1948
|
const bridgeErrorResponseSchema = z.object({
|
|
1555
1949
|
error: bridgeErrorSchema,
|
|
1556
1950
|
ok: z.literal(false),
|
|
1557
1951
|
requestId: requestIdSchema,
|
|
1558
|
-
version: z.literal(
|
|
1952
|
+
version: z.literal(2)
|
|
1559
1953
|
});
|
|
1560
1954
|
const bridgePingResponseSchema = z.union([bridgePingSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1561
1955
|
const bridgeLogSubscribeResponseSchema = z.union([bridgeLogSubscribeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
@@ -1585,6 +1979,18 @@ const bridgeStartTraceResponseSchema = z.union([bridgeStartTraceSuccessResponseS
|
|
|
1585
1979
|
const bridgeStopTraceResponseSchema = z.union([bridgeStopTraceSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1586
1980
|
const bridgeCreateCppClassResponseSchema = z.union([bridgeCreateCppClassSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1587
1981
|
const bridgeGetCreateClassStatusResponseSchema = z.union([bridgeGetCreateClassStatusSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1982
|
+
const bridgeListActorsResponseSchema = z.union([bridgeListActorsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1983
|
+
const bridgeGetActorDetailsResponseSchema = z.union([bridgeGetActorDetailsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1984
|
+
const bridgeGetCurrentLevelResponseSchema = z.union([bridgeGetCurrentLevelSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1985
|
+
const bridgeSpawnActorResponseSchema = z.union([bridgeSpawnActorSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1986
|
+
const bridgeDestroyActorResponseSchema = z.union([bridgeDestroyActorSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1987
|
+
const bridgeSetActorTransformResponseSchema = z.union([bridgeSetActorTransformSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1988
|
+
const bridgeSetActorPropertyResponseSchema = z.union([bridgeSetActorPropertySuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1989
|
+
const bridgeSelectActorsResponseSchema = z.union([bridgeSelectActorsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1990
|
+
const bridgeUndoResponseSchema = z.union([bridgeUndoSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1991
|
+
const bridgeRedoResponseSchema = z.union([bridgeRedoSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1992
|
+
const bridgeOpenLevelResponseSchema = z.union([bridgeOpenLevelSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1993
|
+
const bridgeGetOpenLevelStatusResponseSchema = z.union([bridgeGetOpenLevelStatusSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1588
1994
|
const bridgeFindAssetsResponseSchema = z.union([bridgeFindAssetsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1589
1995
|
const bridgeGetAssetDependenciesResponseSchema = z.union([bridgeGetAssetDependenciesSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1590
1996
|
const bridgeFindBlueprintReferencesResponseSchema = z.union([bridgeFindBlueprintReferencesSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
@@ -1607,7 +2013,117 @@ function createBridgeFindAssetsRequest(options = {}, requestId = randomUUID()) {
|
|
|
1607
2013
|
recursivePaths: options.recursivePaths,
|
|
1608
2014
|
requestId,
|
|
1609
2015
|
type: BRIDGE_FIND_ASSETS_REQUEST_TYPE,
|
|
1610
|
-
version:
|
|
2016
|
+
version: 2
|
|
2017
|
+
});
|
|
2018
|
+
}
|
|
2019
|
+
function createBridgeListActorsRequest(options = {}, requestId = randomUUID()) {
|
|
2020
|
+
return bridgeListActorsRequestSchema.parse({
|
|
2021
|
+
classNames: options.classNames,
|
|
2022
|
+
cursor: options.cursor,
|
|
2023
|
+
levelName: options.levelName,
|
|
2024
|
+
maxResults: options.maxResults ?? 50,
|
|
2025
|
+
nameFilter: options.nameFilter,
|
|
2026
|
+
requestId,
|
|
2027
|
+
tag: options.tag,
|
|
2028
|
+
type: BRIDGE_LIST_ACTORS_REQUEST_TYPE,
|
|
2029
|
+
version: 2
|
|
2030
|
+
});
|
|
2031
|
+
}
|
|
2032
|
+
function createBridgeGetActorDetailsRequest(actorPath, options = {}, requestId = randomUUID()) {
|
|
2033
|
+
return bridgeGetActorDetailsRequestSchema.parse({
|
|
2034
|
+
actorPath,
|
|
2035
|
+
componentCursor: options.componentCursor,
|
|
2036
|
+
includeInherited: options.includeInherited,
|
|
2037
|
+
maxResults: options.maxResults ?? 25,
|
|
2038
|
+
propertyCursor: options.propertyCursor,
|
|
2039
|
+
requestId,
|
|
2040
|
+
type: BRIDGE_GET_ACTOR_DETAILS_REQUEST_TYPE,
|
|
2041
|
+
version: 2
|
|
2042
|
+
});
|
|
2043
|
+
}
|
|
2044
|
+
function createBridgeGetCurrentLevelRequest(requestId = randomUUID()) {
|
|
2045
|
+
return bridgeGetCurrentLevelRequestSchema.parse({
|
|
2046
|
+
requestId,
|
|
2047
|
+
type: BRIDGE_GET_CURRENT_LEVEL_REQUEST_TYPE,
|
|
2048
|
+
version: 2
|
|
2049
|
+
});
|
|
2050
|
+
}
|
|
2051
|
+
function createBridgeSpawnActorRequest(spawns, options = {}, requestId = randomUUID()) {
|
|
2052
|
+
return bridgeSpawnActorRequestSchema.parse({
|
|
2053
|
+
dryRun: options.dryRun,
|
|
2054
|
+
requestId,
|
|
2055
|
+
spawns,
|
|
2056
|
+
type: BRIDGE_SPAWN_ACTOR_REQUEST_TYPE,
|
|
2057
|
+
version: 2
|
|
2058
|
+
});
|
|
2059
|
+
}
|
|
2060
|
+
function createBridgeDestroyActorRequest(actorPaths, options = {}, requestId = randomUUID()) {
|
|
2061
|
+
return bridgeDestroyActorRequestSchema.parse({
|
|
2062
|
+
actorPaths,
|
|
2063
|
+
dryRun: options.dryRun,
|
|
2064
|
+
requestId,
|
|
2065
|
+
type: BRIDGE_DESTROY_ACTOR_REQUEST_TYPE,
|
|
2066
|
+
version: 2
|
|
2067
|
+
});
|
|
2068
|
+
}
|
|
2069
|
+
function createBridgeSetActorTransformRequest(transforms, options = {}, requestId = randomUUID()) {
|
|
2070
|
+
return bridgeSetActorTransformRequestSchema.parse({
|
|
2071
|
+
dryRun: options.dryRun,
|
|
2072
|
+
requestId,
|
|
2073
|
+
transforms,
|
|
2074
|
+
type: BRIDGE_SET_ACTOR_TRANSFORM_REQUEST_TYPE,
|
|
2075
|
+
version: 2
|
|
2076
|
+
});
|
|
2077
|
+
}
|
|
2078
|
+
function createBridgeSetActorPropertyRequest(properties, options = {}, requestId = randomUUID()) {
|
|
2079
|
+
return bridgeSetActorPropertyRequestSchema.parse({
|
|
2080
|
+
dryRun: options.dryRun,
|
|
2081
|
+
properties,
|
|
2082
|
+
requestId,
|
|
2083
|
+
type: BRIDGE_SET_ACTOR_PROPERTY_REQUEST_TYPE,
|
|
2084
|
+
version: 2
|
|
2085
|
+
});
|
|
2086
|
+
}
|
|
2087
|
+
function createBridgeSelectActorsRequest(actorPaths, options = {}, requestId = randomUUID()) {
|
|
2088
|
+
return bridgeSelectActorsRequestSchema.parse({
|
|
2089
|
+
actorPaths,
|
|
2090
|
+
addToSelection: options.addToSelection,
|
|
2091
|
+
dryRun: options.dryRun,
|
|
2092
|
+
requestId,
|
|
2093
|
+
type: BRIDGE_SELECT_ACTORS_REQUEST_TYPE,
|
|
2094
|
+
version: 2
|
|
2095
|
+
});
|
|
2096
|
+
}
|
|
2097
|
+
function createBridgeUndoRequest(requestId = randomUUID()) {
|
|
2098
|
+
return bridgeUndoRequestSchema.parse({
|
|
2099
|
+
requestId,
|
|
2100
|
+
type: BRIDGE_UNDO_REQUEST_TYPE,
|
|
2101
|
+
version: 2
|
|
2102
|
+
});
|
|
2103
|
+
}
|
|
2104
|
+
function createBridgeRedoRequest(requestId = randomUUID()) {
|
|
2105
|
+
return bridgeRedoRequestSchema.parse({
|
|
2106
|
+
requestId,
|
|
2107
|
+
type: BRIDGE_REDO_REQUEST_TYPE,
|
|
2108
|
+
version: 2
|
|
2109
|
+
});
|
|
2110
|
+
}
|
|
2111
|
+
function createBridgeOpenLevelRequest(levelPath, options = {}, requestId = randomUUID()) {
|
|
2112
|
+
return bridgeOpenLevelRequestSchema.parse({
|
|
2113
|
+
dryRun: options.dryRun,
|
|
2114
|
+
levelPath,
|
|
2115
|
+
requestId,
|
|
2116
|
+
saveDirtyPackages: options.saveDirtyPackages,
|
|
2117
|
+
type: BRIDGE_OPEN_LEVEL_REQUEST_TYPE,
|
|
2118
|
+
version: 2
|
|
2119
|
+
});
|
|
2120
|
+
}
|
|
2121
|
+
function createBridgeGetOpenLevelStatusRequest(openLevelJobId, requestId = randomUUID()) {
|
|
2122
|
+
return bridgeGetOpenLevelStatusRequestSchema.parse({
|
|
2123
|
+
openLevelJobId,
|
|
2124
|
+
requestId,
|
|
2125
|
+
type: BRIDGE_GET_OPEN_LEVEL_STATUS_REQUEST_TYPE,
|
|
2126
|
+
version: 2
|
|
1611
2127
|
});
|
|
1612
2128
|
}
|
|
1613
2129
|
function createBridgeGetAssetDependenciesRequest(assetPath, options = {}, requestId = randomUUID()) {
|
|
@@ -1620,7 +2136,7 @@ function createBridgeGetAssetDependenciesRequest(assetPath, options = {}, reques
|
|
|
1620
2136
|
referencerCursor: options.referencerCursor,
|
|
1621
2137
|
requestId,
|
|
1622
2138
|
type: BRIDGE_GET_ASSET_DEPENDENCIES_REQUEST_TYPE,
|
|
1623
|
-
version:
|
|
2139
|
+
version: 2
|
|
1624
2140
|
});
|
|
1625
2141
|
}
|
|
1626
2142
|
function createBridgeFindBlueprintReferencesRequest(className, options = {}, requestId = randomUUID()) {
|
|
@@ -1631,7 +2147,7 @@ function createBridgeFindBlueprintReferencesRequest(className, options = {}, req
|
|
|
1631
2147
|
referenceKinds: options.referenceKinds,
|
|
1632
2148
|
requestId,
|
|
1633
2149
|
type: BRIDGE_FIND_BLUEPRINT_REFERENCES_REQUEST_TYPE,
|
|
1634
|
-
version:
|
|
2150
|
+
version: 2
|
|
1635
2151
|
});
|
|
1636
2152
|
}
|
|
1637
2153
|
function createBridgeGetBlueprintSummaryRequest(blueprintPath, options = {}, requestId = randomUUID()) {
|
|
@@ -1645,7 +2161,7 @@ function createBridgeGetBlueprintSummaryRequest(blueprintPath, options = {}, req
|
|
|
1645
2161
|
requestId,
|
|
1646
2162
|
type: BRIDGE_GET_BLUEPRINT_SUMMARY_REQUEST_TYPE,
|
|
1647
2163
|
variableCursor: options.variableCursor,
|
|
1648
|
-
version:
|
|
2164
|
+
version: 2
|
|
1649
2165
|
});
|
|
1650
2166
|
}
|
|
1651
2167
|
function createBridgeGetBlueprintGraphRequest(blueprintPath, graphName, options = {}, requestId = randomUUID()) {
|
|
@@ -1657,7 +2173,7 @@ function createBridgeGetBlueprintGraphRequest(blueprintPath, graphName, options
|
|
|
1657
2173
|
nodeCursor: options.nodeCursor,
|
|
1658
2174
|
requestId,
|
|
1659
2175
|
type: BRIDGE_GET_BLUEPRINT_GRAPH_REQUEST_TYPE,
|
|
1660
|
-
version:
|
|
2176
|
+
version: 2
|
|
1661
2177
|
});
|
|
1662
2178
|
}
|
|
1663
2179
|
function createBridgeGetBlueprintCompileErrorsRequest(blueprintPaths, options = {}, requestId = randomUUID()) {
|
|
@@ -1667,7 +2183,7 @@ function createBridgeGetBlueprintCompileErrorsRequest(blueprintPaths, options =
|
|
|
1667
2183
|
maxResults: options.maxResults ?? 50,
|
|
1668
2184
|
requestId,
|
|
1669
2185
|
type: BRIDGE_GET_BLUEPRINT_COMPILE_ERRORS_REQUEST_TYPE,
|
|
1670
|
-
version:
|
|
2186
|
+
version: 2
|
|
1671
2187
|
});
|
|
1672
2188
|
}
|
|
1673
2189
|
function createBridgeCompileBlueprintRequest(blueprintPaths, requestId = randomUUID()) {
|
|
@@ -1675,7 +2191,7 @@ function createBridgeCompileBlueprintRequest(blueprintPaths, requestId = randomU
|
|
|
1675
2191
|
blueprintPaths,
|
|
1676
2192
|
requestId,
|
|
1677
2193
|
type: BRIDGE_COMPILE_BLUEPRINT_REQUEST_TYPE,
|
|
1678
|
-
version:
|
|
2194
|
+
version: 2
|
|
1679
2195
|
});
|
|
1680
2196
|
}
|
|
1681
2197
|
function createBridgeGetBlueprintCompileStatusRequest(compileJobId, options = {}, requestId = randomUUID()) {
|
|
@@ -1685,7 +2201,7 @@ function createBridgeGetBlueprintCompileStatusRequest(compileJobId, options = {}
|
|
|
1685
2201
|
maxResults: options.maxResults ?? 50,
|
|
1686
2202
|
requestId,
|
|
1687
2203
|
type: BRIDGE_GET_BLUEPRINT_COMPILE_STATUS_REQUEST_TYPE,
|
|
1688
|
-
version:
|
|
2204
|
+
version: 2
|
|
1689
2205
|
});
|
|
1690
2206
|
}
|
|
1691
2207
|
function createBridgeGetConfigValueRequest(input, requestId = randomUUID()) {
|
|
@@ -1695,7 +2211,7 @@ function createBridgeGetConfigValueRequest(input, requestId = randomUUID()) {
|
|
|
1695
2211
|
requestId,
|
|
1696
2212
|
section: input.section,
|
|
1697
2213
|
type: BRIDGE_GET_CONFIG_VALUE_REQUEST_TYPE,
|
|
1698
|
-
version:
|
|
2214
|
+
version: 2
|
|
1699
2215
|
});
|
|
1700
2216
|
}
|
|
1701
2217
|
function createBridgeSetConfigValueRequest(input, requestId = randomUUID()) {
|
|
@@ -1707,7 +2223,7 @@ function createBridgeSetConfigValueRequest(input, requestId = randomUUID()) {
|
|
|
1707
2223
|
section: input.section,
|
|
1708
2224
|
type: BRIDGE_SET_CONFIG_VALUE_REQUEST_TYPE,
|
|
1709
2225
|
value: input.value,
|
|
1710
|
-
version:
|
|
2226
|
+
version: 2
|
|
1711
2227
|
});
|
|
1712
2228
|
}
|
|
1713
2229
|
function createBridgeListConfigSectionRequest(input, requestId = randomUUID()) {
|
|
@@ -1718,28 +2234,28 @@ function createBridgeListConfigSectionRequest(input, requestId = randomUUID()) {
|
|
|
1718
2234
|
requestId,
|
|
1719
2235
|
section: input.section,
|
|
1720
2236
|
type: BRIDGE_LIST_CONFIG_SECTION_REQUEST_TYPE,
|
|
1721
|
-
version:
|
|
2237
|
+
version: 2
|
|
1722
2238
|
});
|
|
1723
2239
|
}
|
|
1724
2240
|
function createBridgePingRequest(requestId = randomUUID()) {
|
|
1725
2241
|
return {
|
|
1726
2242
|
requestId,
|
|
1727
2243
|
type: BRIDGE_PING_REQUEST_TYPE,
|
|
1728
|
-
version:
|
|
2244
|
+
version: 2
|
|
1729
2245
|
};
|
|
1730
2246
|
}
|
|
1731
2247
|
function createBridgeStartLiveCompileRequest(requestId = randomUUID()) {
|
|
1732
2248
|
return {
|
|
1733
2249
|
requestId,
|
|
1734
2250
|
type: BRIDGE_START_LIVE_COMPILE_REQUEST_TYPE,
|
|
1735
|
-
version:
|
|
2251
|
+
version: 2
|
|
1736
2252
|
};
|
|
1737
2253
|
}
|
|
1738
2254
|
function createBridgeStartHotReloadRequest(requestId = randomUUID()) {
|
|
1739
2255
|
return {
|
|
1740
2256
|
requestId,
|
|
1741
2257
|
type: BRIDGE_START_HOT_RELOAD_REQUEST_TYPE,
|
|
1742
|
-
version:
|
|
2258
|
+
version: 2
|
|
1743
2259
|
};
|
|
1744
2260
|
}
|
|
1745
2261
|
function createBridgeGetCompileStatusRequest(compileJobId, requestId = randomUUID()) {
|
|
@@ -1747,7 +2263,7 @@ function createBridgeGetCompileStatusRequest(compileJobId, requestId = randomUUI
|
|
|
1747
2263
|
compileJobId,
|
|
1748
2264
|
requestId,
|
|
1749
2265
|
type: BRIDGE_GET_COMPILE_STATUS_REQUEST_TYPE,
|
|
1750
|
-
version:
|
|
2266
|
+
version: 2
|
|
1751
2267
|
});
|
|
1752
2268
|
}
|
|
1753
2269
|
function createBridgeLogSubscribeRequest(source, filters, requestId = randomUUID()) {
|
|
@@ -1756,7 +2272,7 @@ function createBridgeLogSubscribeRequest(source, filters, requestId = randomUUID
|
|
|
1756
2272
|
requestId,
|
|
1757
2273
|
source,
|
|
1758
2274
|
type: BRIDGE_SUBSCRIBE_LOGS_REQUEST_TYPE,
|
|
1759
|
-
version:
|
|
2275
|
+
version: 2
|
|
1760
2276
|
});
|
|
1761
2277
|
}
|
|
1762
2278
|
function createBridgeLogDrainRequest(subscriptionId, cursor, maxEvents, requestId = randomUUID()) {
|
|
@@ -1766,7 +2282,7 @@ function createBridgeLogDrainRequest(subscriptionId, cursor, maxEvents, requestI
|
|
|
1766
2282
|
requestId,
|
|
1767
2283
|
subscriptionId,
|
|
1768
2284
|
type: BRIDGE_DRAIN_LOGS_REQUEST_TYPE,
|
|
1769
|
-
version:
|
|
2285
|
+
version: 2
|
|
1770
2286
|
});
|
|
1771
2287
|
}
|
|
1772
2288
|
function createBridgeStartPieRequest(mode = "new_window", map, options = {}, requestId = randomUUID()) {
|
|
@@ -1778,7 +2294,7 @@ function createBridgeStartPieRequest(mode = "new_window", map, options = {}, req
|
|
|
1778
2294
|
requestId,
|
|
1779
2295
|
runUnderOneProcess: options.runUnderOneProcess,
|
|
1780
2296
|
type: BRIDGE_START_PIE_REQUEST_TYPE,
|
|
1781
|
-
version:
|
|
2297
|
+
version: 2
|
|
1782
2298
|
});
|
|
1783
2299
|
}
|
|
1784
2300
|
function createBridgeGetPieStatusRequest(pieSessionId, requestId = randomUUID()) {
|
|
@@ -1786,7 +2302,7 @@ function createBridgeGetPieStatusRequest(pieSessionId, requestId = randomUUID())
|
|
|
1786
2302
|
pieSessionId,
|
|
1787
2303
|
requestId,
|
|
1788
2304
|
type: BRIDGE_GET_PIE_STATUS_REQUEST_TYPE,
|
|
1789
|
-
version:
|
|
2305
|
+
version: 2
|
|
1790
2306
|
});
|
|
1791
2307
|
}
|
|
1792
2308
|
function createBridgeStopPieRequest(pieSessionId, requestId = randomUUID()) {
|
|
@@ -1794,14 +2310,14 @@ function createBridgeStopPieRequest(pieSessionId, requestId = randomUUID()) {
|
|
|
1794
2310
|
pieSessionId,
|
|
1795
2311
|
requestId,
|
|
1796
2312
|
type: BRIDGE_STOP_PIE_REQUEST_TYPE,
|
|
1797
|
-
version:
|
|
2313
|
+
version: 2
|
|
1798
2314
|
});
|
|
1799
2315
|
}
|
|
1800
2316
|
function createBridgeListLaunchDevicesRequest(requestId = randomUUID()) {
|
|
1801
2317
|
return {
|
|
1802
2318
|
requestId,
|
|
1803
2319
|
type: BRIDGE_LIST_LAUNCH_DEVICES_REQUEST_TYPE,
|
|
1804
|
-
version:
|
|
2320
|
+
version: 2
|
|
1805
2321
|
};
|
|
1806
2322
|
}
|
|
1807
2323
|
function createBridgeLaunchOnDeviceRequest(deviceId, map, requestId = randomUUID()) {
|
|
@@ -1810,7 +2326,7 @@ function createBridgeLaunchOnDeviceRequest(deviceId, map, requestId = randomUUID
|
|
|
1810
2326
|
map,
|
|
1811
2327
|
requestId,
|
|
1812
2328
|
type: BRIDGE_LAUNCH_ON_DEVICE_REQUEST_TYPE,
|
|
1813
|
-
version:
|
|
2329
|
+
version: 2
|
|
1814
2330
|
});
|
|
1815
2331
|
}
|
|
1816
2332
|
function createBridgeListAutomationTestsRequest(options = {}, requestId = randomUUID()) {
|
|
@@ -1821,7 +2337,7 @@ function createBridgeListAutomationTestsRequest(options = {}, requestId = random
|
|
|
1821
2337
|
nameFilter: options.nameFilter,
|
|
1822
2338
|
requestId,
|
|
1823
2339
|
type: BRIDGE_LIST_AUTOMATION_TESTS_REQUEST_TYPE,
|
|
1824
|
-
version:
|
|
2340
|
+
version: 2
|
|
1825
2341
|
});
|
|
1826
2342
|
}
|
|
1827
2343
|
function createBridgeStartAutomationRunRequest(selectors, requestId = randomUUID()) {
|
|
@@ -1831,7 +2347,7 @@ function createBridgeStartAutomationRunRequest(selectors, requestId = randomUUID
|
|
|
1831
2347
|
requestId,
|
|
1832
2348
|
testNames: selectors.testNames ?? [],
|
|
1833
2349
|
type: BRIDGE_START_AUTOMATION_RUN_REQUEST_TYPE,
|
|
1834
|
-
version:
|
|
2350
|
+
version: 2
|
|
1835
2351
|
});
|
|
1836
2352
|
}
|
|
1837
2353
|
function createBridgeGetAutomationRunStatusRequest(testRunId, options = {}, requestId = randomUUID()) {
|
|
@@ -1841,7 +2357,7 @@ function createBridgeGetAutomationRunStatusRequest(testRunId, options = {}, requ
|
|
|
1841
2357
|
requestId,
|
|
1842
2358
|
testRunId,
|
|
1843
2359
|
type: BRIDGE_GET_AUTOMATION_RUN_STATUS_REQUEST_TYPE,
|
|
1844
|
-
version:
|
|
2360
|
+
version: 2
|
|
1845
2361
|
});
|
|
1846
2362
|
}
|
|
1847
2363
|
function createBridgeCancelAutomationRunRequest(testRunId, requestId = randomUUID()) {
|
|
@@ -1849,14 +2365,14 @@ function createBridgeCancelAutomationRunRequest(testRunId, requestId = randomUUI
|
|
|
1849
2365
|
requestId,
|
|
1850
2366
|
testRunId,
|
|
1851
2367
|
type: BRIDGE_CANCEL_AUTOMATION_RUN_REQUEST_TYPE,
|
|
1852
|
-
version:
|
|
2368
|
+
version: 2
|
|
1853
2369
|
});
|
|
1854
2370
|
}
|
|
1855
2371
|
function createBridgeGetEditorStateRequest(requestId = randomUUID()) {
|
|
1856
2372
|
return {
|
|
1857
2373
|
requestId,
|
|
1858
2374
|
type: BRIDGE_GET_EDITOR_STATE_REQUEST_TYPE,
|
|
1859
|
-
version:
|
|
2375
|
+
version: 2
|
|
1860
2376
|
};
|
|
1861
2377
|
}
|
|
1862
2378
|
function createBridgeExecConsoleCommandRequest(command, requestId = randomUUID()) {
|
|
@@ -1864,14 +2380,14 @@ function createBridgeExecConsoleCommandRequest(command, requestId = randomUUID()
|
|
|
1864
2380
|
command,
|
|
1865
2381
|
requestId,
|
|
1866
2382
|
type: BRIDGE_EXEC_CONSOLE_COMMAND_REQUEST_TYPE,
|
|
1867
|
-
version:
|
|
2383
|
+
version: 2
|
|
1868
2384
|
});
|
|
1869
2385
|
}
|
|
1870
2386
|
function createBridgeStatSnapshotRequest(requestId = randomUUID()) {
|
|
1871
2387
|
return bridgeStatSnapshotRequestSchema.parse({
|
|
1872
2388
|
requestId,
|
|
1873
2389
|
type: BRIDGE_STAT_SNAPSHOT_REQUEST_TYPE,
|
|
1874
|
-
version:
|
|
2390
|
+
version: 2
|
|
1875
2391
|
});
|
|
1876
2392
|
}
|
|
1877
2393
|
function createBridgeSaveDirtyPackagesRequest(options = {}, requestId = randomUUID()) {
|
|
@@ -1880,7 +2396,7 @@ function createBridgeSaveDirtyPackagesRequest(options = {}, requestId = randomUU
|
|
|
1880
2396
|
saveContentPackages: options.saveContentPackages,
|
|
1881
2397
|
saveMapPackages: options.saveMapPackages,
|
|
1882
2398
|
type: BRIDGE_SAVE_DIRTY_PACKAGES_REQUEST_TYPE,
|
|
1883
|
-
version:
|
|
2399
|
+
version: 2
|
|
1884
2400
|
});
|
|
1885
2401
|
}
|
|
1886
2402
|
function createBridgeStartTraceRequest(options = {}, requestId = randomUUID()) {
|
|
@@ -1889,7 +2405,7 @@ function createBridgeStartTraceRequest(options = {}, requestId = randomUUID()) {
|
|
|
1889
2405
|
fileName: options.fileName,
|
|
1890
2406
|
requestId,
|
|
1891
2407
|
type: BRIDGE_START_TRACE_REQUEST_TYPE,
|
|
1892
|
-
version:
|
|
2408
|
+
version: 2
|
|
1893
2409
|
});
|
|
1894
2410
|
}
|
|
1895
2411
|
function createBridgeGetClassReflectionRequest(className, options = {}, requestId = randomUUID()) {
|
|
@@ -1902,14 +2418,14 @@ function createBridgeGetClassReflectionRequest(className, options = {}, requestI
|
|
|
1902
2418
|
propertyCursor: options.propertyCursor,
|
|
1903
2419
|
requestId,
|
|
1904
2420
|
type: BRIDGE_GET_CLASS_REFLECTION_REQUEST_TYPE,
|
|
1905
|
-
version:
|
|
2421
|
+
version: 2
|
|
1906
2422
|
});
|
|
1907
2423
|
}
|
|
1908
2424
|
function createBridgeCaptureViewportRequest(requestId = randomUUID()) {
|
|
1909
2425
|
return {
|
|
1910
2426
|
requestId,
|
|
1911
2427
|
type: BRIDGE_CAPTURE_VIEWPORT_REQUEST_TYPE,
|
|
1912
|
-
version:
|
|
2428
|
+
version: 2
|
|
1913
2429
|
};
|
|
1914
2430
|
}
|
|
1915
2431
|
function createBridgeGetCdoDefaultsRequest(className, options = {}, requestId = randomUUID()) {
|
|
@@ -1921,7 +2437,7 @@ function createBridgeGetCdoDefaultsRequest(className, options = {}, requestId =
|
|
|
1921
2437
|
nameFilter: options.nameFilter,
|
|
1922
2438
|
requestId,
|
|
1923
2439
|
type: BRIDGE_GET_CDO_DEFAULTS_REQUEST_TYPE,
|
|
1924
|
-
version:
|
|
2440
|
+
version: 2
|
|
1925
2441
|
});
|
|
1926
2442
|
}
|
|
1927
2443
|
function createBridgeGetCrashCallstackRequest(maxRecords = 1, maxFrames = 32, requestId = randomUUID()) {
|
|
@@ -1930,14 +2446,14 @@ function createBridgeGetCrashCallstackRequest(maxRecords = 1, maxFrames = 32, re
|
|
|
1930
2446
|
maxRecords,
|
|
1931
2447
|
requestId,
|
|
1932
2448
|
type: BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE,
|
|
1933
|
-
version:
|
|
2449
|
+
version: 2
|
|
1934
2450
|
});
|
|
1935
2451
|
}
|
|
1936
2452
|
function createBridgeStopTraceRequest(requestId = randomUUID()) {
|
|
1937
2453
|
return bridgeStopTraceRequestSchema.parse({
|
|
1938
2454
|
requestId,
|
|
1939
2455
|
type: BRIDGE_STOP_TRACE_REQUEST_TYPE,
|
|
1940
|
-
version:
|
|
2456
|
+
version: 2
|
|
1941
2457
|
});
|
|
1942
2458
|
}
|
|
1943
2459
|
function createBridgeCreateCppClassRequest(className, parentClass, options = {}, requestId = randomUUID()) {
|
|
@@ -1948,7 +2464,7 @@ function createBridgeCreateCppClassRequest(className, parentClass, options = {},
|
|
|
1948
2464
|
parentClass,
|
|
1949
2465
|
requestId,
|
|
1950
2466
|
type: BRIDGE_CREATE_CPP_CLASS_REQUEST_TYPE,
|
|
1951
|
-
version:
|
|
2467
|
+
version: 2
|
|
1952
2468
|
});
|
|
1953
2469
|
}
|
|
1954
2470
|
function createBridgeGetCreateClassStatusRequest(createClassJobId, requestId = randomUUID()) {
|
|
@@ -1956,7 +2472,7 @@ function createBridgeGetCreateClassStatusRequest(createClassJobId, requestId = r
|
|
|
1956
2472
|
createClassJobId,
|
|
1957
2473
|
requestId,
|
|
1958
2474
|
type: BRIDGE_GET_CREATE_CLASS_STATUS_REQUEST_TYPE,
|
|
1959
|
-
version:
|
|
2475
|
+
version: 2
|
|
1960
2476
|
});
|
|
1961
2477
|
}
|
|
1962
2478
|
//#endregion
|
|
@@ -2056,6 +2572,42 @@ async function sendBridgeStopTraceRequest(request, options) {
|
|
|
2056
2572
|
async function sendBridgeFindAssetsRequest(request, options) {
|
|
2057
2573
|
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeFindAssetsResponseSchema, request.requestId);
|
|
2058
2574
|
}
|
|
2575
|
+
async function sendBridgeListActorsRequest(request, options) {
|
|
2576
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeListActorsResponseSchema, request.requestId);
|
|
2577
|
+
}
|
|
2578
|
+
async function sendBridgeGetActorDetailsRequest(request, options) {
|
|
2579
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetActorDetailsResponseSchema, request.requestId);
|
|
2580
|
+
}
|
|
2581
|
+
async function sendBridgeGetCurrentLevelRequest(request, options) {
|
|
2582
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetCurrentLevelResponseSchema, request.requestId);
|
|
2583
|
+
}
|
|
2584
|
+
async function sendBridgeSpawnActorRequest(request, options) {
|
|
2585
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSpawnActorResponseSchema, request.requestId);
|
|
2586
|
+
}
|
|
2587
|
+
async function sendBridgeDestroyActorRequest(request, options) {
|
|
2588
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeDestroyActorResponseSchema, request.requestId);
|
|
2589
|
+
}
|
|
2590
|
+
async function sendBridgeSetActorTransformRequest(request, options) {
|
|
2591
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetActorTransformResponseSchema, request.requestId);
|
|
2592
|
+
}
|
|
2593
|
+
async function sendBridgeSetActorPropertyRequest(request, options) {
|
|
2594
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetActorPropertyResponseSchema, request.requestId);
|
|
2595
|
+
}
|
|
2596
|
+
async function sendBridgeSelectActorsRequest(request, options) {
|
|
2597
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSelectActorsResponseSchema, request.requestId);
|
|
2598
|
+
}
|
|
2599
|
+
async function sendBridgeUndoRequest(request, options) {
|
|
2600
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeUndoResponseSchema, request.requestId);
|
|
2601
|
+
}
|
|
2602
|
+
async function sendBridgeRedoRequest(request, options) {
|
|
2603
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeRedoResponseSchema, request.requestId);
|
|
2604
|
+
}
|
|
2605
|
+
async function sendBridgeOpenLevelRequest(request, options) {
|
|
2606
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeOpenLevelResponseSchema, request.requestId);
|
|
2607
|
+
}
|
|
2608
|
+
async function sendBridgeGetOpenLevelStatusRequest(request, options) {
|
|
2609
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetOpenLevelStatusResponseSchema, request.requestId);
|
|
2610
|
+
}
|
|
2059
2611
|
async function sendBridgeGetAssetDependenciesRequest(request, options) {
|
|
2060
2612
|
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetAssetDependenciesResponseSchema, request.requestId);
|
|
2061
2613
|
}
|
|
@@ -2429,6 +2981,13 @@ var RegistryWriteQueue = class {
|
|
|
2429
2981
|
function createHttpApi(options) {
|
|
2430
2982
|
const app = Fastify({ logger: false });
|
|
2431
2983
|
const registryWriteQueue = options.registryWriteQueue ?? new RegistryWriteQueue();
|
|
2984
|
+
const notifyRegistryChanged = () => {
|
|
2985
|
+
try {
|
|
2986
|
+
options.onRegistryChanged?.();
|
|
2987
|
+
} catch (error) {
|
|
2988
|
+
options.logger.warn({ error }, "Failed to notify listeners that the registry changed");
|
|
2989
|
+
}
|
|
2990
|
+
};
|
|
2432
2991
|
app.setErrorHandler((error, _request, reply) => {
|
|
2433
2992
|
if (error instanceof HttpError) {
|
|
2434
2993
|
reply.code(error.statusCode).send({
|
|
@@ -2513,6 +3072,7 @@ function createHttpApi(options) {
|
|
|
2513
3072
|
projectName: entry.projectName,
|
|
2514
3073
|
projectPath: entry.projectPath
|
|
2515
3074
|
}, "Upserted Unreal Editor project registration");
|
|
3075
|
+
notifyRegistryChanged();
|
|
2516
3076
|
return {
|
|
2517
3077
|
projectId: entry.projectId,
|
|
2518
3078
|
stored: true
|
|
@@ -2543,6 +3103,7 @@ function createHttpApi(options) {
|
|
|
2543
3103
|
existed,
|
|
2544
3104
|
projectId
|
|
2545
3105
|
}, "Removed Unreal Editor project registration");
|
|
3106
|
+
if (existed) notifyRegistryChanged();
|
|
2546
3107
|
return {
|
|
2547
3108
|
projectId,
|
|
2548
3109
|
removed: true
|
|
@@ -2972,144 +3533,6 @@ function isLogLevel(value) {
|
|
|
2972
3533
|
return value === "fatal" || value === "error" || value === "warn" || value === "info" || value === "debug" || value === "trace" || value === "silent";
|
|
2973
3534
|
}
|
|
2974
3535
|
//#endregion
|
|
2975
|
-
//#region src/buildDiagnostics.ts
|
|
2976
|
-
const CLANG_DIAGNOSTIC_PATTERN = /^(?<file>.+?):(?<line>\d+):(?:(?<column>\d+):)?\s+(?<severity>fatal error|error|warning):\s+(?<message>.*)$/u;
|
|
2977
|
-
const MSVC_DIAGNOSTIC_PATTERN = /^(?<file>.+?)\((?<line>\d+)(?:,\d+)?\):\s+(?<severity>fatal error|error|warning)\s+(?<code>[A-Z]+\d+):\s+(?<message>.*)$/u;
|
|
2978
|
-
const CLANG_TIDY_PATTERN = /^(?<file>.+?):(?<line>\d+):(?<column>\d+):\s+(?<severity>error|warning):\s+(?<message>.*?)(?:\s+\[(?<check>[^\]]+)\])?$/u;
|
|
2979
|
-
const COOK_LINE_PREFIX_PATTERN = /^(?:\[[^\]]*\]\s*)*(?:[A-Za-z]+Helper:\s*[^:]*:\s*)?/u;
|
|
2980
|
-
const COOK_DIAGNOSTIC_PATTERN = /^(?<category>[A-Za-z_][A-Za-z0-9_]*):\s+(?<severity>Error|Warning)(?::)?\s+(?<message>.+)$/u;
|
|
2981
|
-
const UAT_DIAGNOSTIC_PATTERN = /^(?<severity>ERROR|WARNING):\s+(?<message>.+)$/u;
|
|
2982
|
-
function diagnosticKey(diagnostic) {
|
|
2983
|
-
return `${diagnostic.file ?? ""}|${diagnostic.line ?? ""}|${diagnostic.message}`;
|
|
2984
|
-
}
|
|
2985
|
-
function matchCookDiagnostic(rawLine) {
|
|
2986
|
-
const line = rawLine.trim().replace(COOK_LINE_PREFIX_PATTERN, "").trim();
|
|
2987
|
-
if (line.length === 0) return null;
|
|
2988
|
-
const categoryMatch = COOK_DIAGNOSTIC_PATTERN.exec(line);
|
|
2989
|
-
if (categoryMatch?.groups) {
|
|
2990
|
-
const { category, message, severity } = categoryMatch.groups;
|
|
2991
|
-
if (category === void 0 || message === void 0 || severity === void 0) return null;
|
|
2992
|
-
return {
|
|
2993
|
-
isError: severity === "Error",
|
|
2994
|
-
message: `${category}: ${message.trim()}`
|
|
2995
|
-
};
|
|
2996
|
-
}
|
|
2997
|
-
const uatMatch = UAT_DIAGNOSTIC_PATTERN.exec(line);
|
|
2998
|
-
if (!uatMatch?.groups) return null;
|
|
2999
|
-
const { message, severity } = uatMatch.groups;
|
|
3000
|
-
if (message === void 0 || severity === void 0) return null;
|
|
3001
|
-
return {
|
|
3002
|
-
isError: severity === "ERROR",
|
|
3003
|
-
message: message.trim()
|
|
3004
|
-
};
|
|
3005
|
-
}
|
|
3006
|
-
var CookDiagnosticCollector = class {
|
|
3007
|
-
maxEntriesPerSeverity;
|
|
3008
|
-
errors = [];
|
|
3009
|
-
warnings = [];
|
|
3010
|
-
seenErrors = /* @__PURE__ */ new Set();
|
|
3011
|
-
seenWarnings = /* @__PURE__ */ new Set();
|
|
3012
|
-
pending = "";
|
|
3013
|
-
truncatedFlag = false;
|
|
3014
|
-
constructor(maxEntriesPerSeverity) {
|
|
3015
|
-
this.maxEntriesPerSeverity = maxEntriesPerSeverity;
|
|
3016
|
-
}
|
|
3017
|
-
push(chunk) {
|
|
3018
|
-
const lines = (this.pending + chunk).split(/\r?\n/u);
|
|
3019
|
-
this.pending = lines.pop() ?? "";
|
|
3020
|
-
for (const line of lines) this.pushLine(line);
|
|
3021
|
-
}
|
|
3022
|
-
flush() {
|
|
3023
|
-
if (this.pending.length === 0) return;
|
|
3024
|
-
const remaining = this.pending;
|
|
3025
|
-
this.pending = "";
|
|
3026
|
-
this.pushLine(remaining);
|
|
3027
|
-
}
|
|
3028
|
-
snapshot() {
|
|
3029
|
-
return {
|
|
3030
|
-
errorCount: this.errors.length,
|
|
3031
|
-
errors: [...this.errors],
|
|
3032
|
-
truncated: this.truncatedFlag,
|
|
3033
|
-
warningCount: this.warnings.length,
|
|
3034
|
-
warnings: [...this.warnings]
|
|
3035
|
-
};
|
|
3036
|
-
}
|
|
3037
|
-
pushLine(rawLine) {
|
|
3038
|
-
const matched = matchCookDiagnostic(rawLine);
|
|
3039
|
-
if (!matched) return;
|
|
3040
|
-
const diagnostic = { message: matched.message };
|
|
3041
|
-
const target = matched.isError ? this.errors : this.warnings;
|
|
3042
|
-
const seen = matched.isError ? this.seenErrors : this.seenWarnings;
|
|
3043
|
-
const key = diagnosticKey(diagnostic);
|
|
3044
|
-
if (seen.has(key)) return;
|
|
3045
|
-
seen.add(key);
|
|
3046
|
-
if (target.length >= this.maxEntriesPerSeverity) {
|
|
3047
|
-
this.truncatedFlag = true;
|
|
3048
|
-
return;
|
|
3049
|
-
}
|
|
3050
|
-
target.push(diagnostic);
|
|
3051
|
-
}
|
|
3052
|
-
};
|
|
3053
|
-
function parseBuildDiagnostics(output) {
|
|
3054
|
-
const errors = [];
|
|
3055
|
-
const warnings = [];
|
|
3056
|
-
const seenErrors = /* @__PURE__ */ new Set();
|
|
3057
|
-
const seenWarnings = /* @__PURE__ */ new Set();
|
|
3058
|
-
for (const rawLine of output.split(/\r?\n/u)) {
|
|
3059
|
-
const line = rawLine.trim();
|
|
3060
|
-
if (line.length === 0) continue;
|
|
3061
|
-
const match = CLANG_DIAGNOSTIC_PATTERN.exec(line) ?? MSVC_DIAGNOSTIC_PATTERN.exec(line);
|
|
3062
|
-
if (!match?.groups) continue;
|
|
3063
|
-
const groups = match.groups;
|
|
3064
|
-
const { file, line: lineText, message, severity } = groups;
|
|
3065
|
-
if (file === void 0 || lineText === void 0 || message === void 0 || severity === void 0) continue;
|
|
3066
|
-
const code = typeof groups.code === "string" ? `${groups.code}: ` : "";
|
|
3067
|
-
const diagnostic = {
|
|
3068
|
-
file,
|
|
3069
|
-
line: Number.parseInt(lineText, 10),
|
|
3070
|
-
message: `${code}${message}`.trim()
|
|
3071
|
-
};
|
|
3072
|
-
const isError = severity === "error" || severity === "fatal error";
|
|
3073
|
-
const target = isError ? errors : warnings;
|
|
3074
|
-
const seen = isError ? seenErrors : seenWarnings;
|
|
3075
|
-
const key = diagnosticKey(diagnostic);
|
|
3076
|
-
if (seen.has(key)) continue;
|
|
3077
|
-
seen.add(key);
|
|
3078
|
-
target.push(diagnostic);
|
|
3079
|
-
}
|
|
3080
|
-
return {
|
|
3081
|
-
errorCount: errors.length,
|
|
3082
|
-
errors,
|
|
3083
|
-
warningCount: warnings.length,
|
|
3084
|
-
warnings
|
|
3085
|
-
};
|
|
3086
|
-
}
|
|
3087
|
-
function parseClangTidyFindings(output) {
|
|
3088
|
-
const findings = [];
|
|
3089
|
-
const seen = /* @__PURE__ */ new Set();
|
|
3090
|
-
for (const rawLine of output.split(/\r?\n/u)) {
|
|
3091
|
-
const match = CLANG_TIDY_PATTERN.exec(rawLine.trim());
|
|
3092
|
-
if (!match?.groups) continue;
|
|
3093
|
-
const groups = match.groups;
|
|
3094
|
-
const { file, line, message } = groups;
|
|
3095
|
-
if (file === void 0 || line === void 0 || message === void 0) continue;
|
|
3096
|
-
const severity = groups.severity === "error" ? "error" : "warning";
|
|
3097
|
-
const finding = {
|
|
3098
|
-
check: groups.check ?? "unknown",
|
|
3099
|
-
file,
|
|
3100
|
-
line: Number.parseInt(line, 10),
|
|
3101
|
-
message: message.trim(),
|
|
3102
|
-
severity
|
|
3103
|
-
};
|
|
3104
|
-
if (typeof groups.column === "string") finding.column = Number.parseInt(groups.column, 10);
|
|
3105
|
-
const key = `${finding.file}|${finding.line}|${finding.column ?? ""}|${finding.check}|${finding.message}`;
|
|
3106
|
-
if (seen.has(key)) continue;
|
|
3107
|
-
seen.add(key);
|
|
3108
|
-
findings.push(finding);
|
|
3109
|
-
}
|
|
3110
|
-
return findings;
|
|
3111
|
-
}
|
|
3112
|
-
//#endregion
|
|
3113
3536
|
//#region src/engineToolchain.ts
|
|
3114
3537
|
const UNREAL_BUILD_CONFIGURATIONS = [
|
|
3115
3538
|
"Debug",
|
|
@@ -3140,6 +3563,7 @@ function cookCommandletTargetPlatform(platform) {
|
|
|
3140
3563
|
const DEFAULT_PROCESS_TIMEOUT_MS = 18e5;
|
|
3141
3564
|
const MAX_PROCESS_TIMEOUT_MS = 72e5;
|
|
3142
3565
|
const DEFAULT_PACKAGE_TIMEOUT_MS = 54e5;
|
|
3566
|
+
const ENGINE_INSTALL_DIRECTORY_PATTERN = /^UE_(\d+(?:\.\d+)*)$/u;
|
|
3143
3567
|
async function defaultFileExists(filePath) {
|
|
3144
3568
|
try {
|
|
3145
3569
|
await access(filePath);
|
|
@@ -3357,6 +3781,47 @@ async function resolveEngine(options) {
|
|
|
3357
3781
|
unrealBuildTool
|
|
3358
3782
|
};
|
|
3359
3783
|
}
|
|
3784
|
+
async function listEngineInstalls(context) {
|
|
3785
|
+
const ueInstallsDir = context.env.UE_INSTALLS_DIR?.trim();
|
|
3786
|
+
if (!ueInstallsDir) throw new EngineToolchainError("UE_INSTALLS_DIR is not set; define it in .env (see .env.example).");
|
|
3787
|
+
let entries;
|
|
3788
|
+
try {
|
|
3789
|
+
entries = await context.listDirectory(ueInstallsDir);
|
|
3790
|
+
} catch (error) {
|
|
3791
|
+
throw new EngineToolchainError(`Failed to read UE_INSTALLS_DIR ${ueInstallsDir}: ${error instanceof Error ? error.message : String(error)}`, { cause: error instanceof Error ? error : void 0 });
|
|
3792
|
+
}
|
|
3793
|
+
const installs = [];
|
|
3794
|
+
for (const entry of entries) {
|
|
3795
|
+
const engineVersion = ENGINE_INSTALL_DIRECTORY_PATTERN.exec(entry)?.[1];
|
|
3796
|
+
if (engineVersion === void 0) continue;
|
|
3797
|
+
const engineRoot = path.join(ueInstallsDir, entry);
|
|
3798
|
+
installs.push({
|
|
3799
|
+
engineRoot,
|
|
3800
|
+
engineVersion,
|
|
3801
|
+
unrealBuildToolResolved: await isUnrealBuildToolResolvable(engineRoot, context)
|
|
3802
|
+
});
|
|
3803
|
+
}
|
|
3804
|
+
return installs.sort((left, right) => compareEngineVersions(left.engineVersion, right.engineVersion));
|
|
3805
|
+
}
|
|
3806
|
+
async function isUnrealBuildToolResolvable(engineRoot, context) {
|
|
3807
|
+
try {
|
|
3808
|
+
await resolveUnrealBuildTool(engineRoot, context);
|
|
3809
|
+
return true;
|
|
3810
|
+
} catch (error) {
|
|
3811
|
+
if (error instanceof EngineToolchainError) return false;
|
|
3812
|
+
throw error;
|
|
3813
|
+
}
|
|
3814
|
+
}
|
|
3815
|
+
function compareEngineVersions(left, right) {
|
|
3816
|
+
const leftSegments = left.split(".");
|
|
3817
|
+
const rightSegments = right.split(".");
|
|
3818
|
+
const segmentCount = Math.max(leftSegments.length, rightSegments.length);
|
|
3819
|
+
for (let index = 0; index < segmentCount; index += 1) {
|
|
3820
|
+
const difference = Number(leftSegments[index] ?? 0) - Number(rightSegments[index] ?? 0);
|
|
3821
|
+
if (difference !== 0) return difference;
|
|
3822
|
+
}
|
|
3823
|
+
return 0;
|
|
3824
|
+
}
|
|
3360
3825
|
async function resolveUnrealBuildTool(engineRoot, context) {
|
|
3361
3826
|
if (context.platform === "win32") {
|
|
3362
3827
|
const ubtExe = path.join(engineRoot, "Engine", "Binaries", "DotNET", "UnrealBuildTool", "UnrealBuildTool.exe");
|
|
@@ -3460,12 +3925,431 @@ async function resolveBundledDotnet(engineRoot, context) {
|
|
|
3460
3925
|
const candidate = path.join(dotnetRoot, versionDir, platformDir, executableName);
|
|
3461
3926
|
if (await context.fileExists(candidate)) return candidate;
|
|
3462
3927
|
}
|
|
3463
|
-
}
|
|
3464
|
-
function buildUnrealBuildToolInvocation(engine, extraArgs) {
|
|
3465
|
-
return {
|
|
3466
|
-
args: [...engine.unrealBuildTool.args, ...extraArgs],
|
|
3467
|
-
command: engine.unrealBuildTool.command
|
|
3468
|
-
};
|
|
3928
|
+
}
|
|
3929
|
+
function buildUnrealBuildToolInvocation(engine, extraArgs) {
|
|
3930
|
+
return {
|
|
3931
|
+
args: [...engine.unrealBuildTool.args, ...extraArgs],
|
|
3932
|
+
command: engine.unrealBuildTool.command
|
|
3933
|
+
};
|
|
3934
|
+
}
|
|
3935
|
+
const RESOURCE_MIME_TYPE = "application/json";
|
|
3936
|
+
const REGISTRY_RESOURCE_URI = "uemcp://registry";
|
|
3937
|
+
const REGISTRY_PROJECT_RESOURCE_URI_TEMPLATE = "uemcp://registry/{projectId}";
|
|
3938
|
+
const ENGINES_RESOURCE_URI = "uemcp://engines";
|
|
3939
|
+
const WORKSPACE_PROJECT_RESOURCE_URI = "uemcp://workspace/project";
|
|
3940
|
+
function readRegistryResource(dependencies) {
|
|
3941
|
+
const entries = dependencies.registry.snapshot();
|
|
3942
|
+
return clampResourceList(entries, (visibleEntries, truncated) => ({
|
|
3943
|
+
entries: visibleEntries,
|
|
3944
|
+
totalCount: entries.length,
|
|
3945
|
+
truncated
|
|
3946
|
+
}));
|
|
3947
|
+
}
|
|
3948
|
+
function readRegistryProjectResource(projectId, dependencies) {
|
|
3949
|
+
const parsedProjectId = projectIdSchema.safeParse(projectId);
|
|
3950
|
+
if (!parsedProjectId.success) return {
|
|
3951
|
+
entry: null,
|
|
3952
|
+
found: false,
|
|
3953
|
+
projectId,
|
|
3954
|
+
reason: "The requested projectId is not a canonical 32-character Unreal ProjectID.",
|
|
3955
|
+
truncated: false
|
|
3956
|
+
};
|
|
3957
|
+
const entry = dependencies.registry.getProject(parsedProjectId.data);
|
|
3958
|
+
if (!entry) return {
|
|
3959
|
+
entry: null,
|
|
3960
|
+
found: false,
|
|
3961
|
+
projectId: parsedProjectId.data,
|
|
3962
|
+
reason: "No Unreal Editor is registered with this server for that projectId.",
|
|
3963
|
+
truncated: false
|
|
3964
|
+
};
|
|
3965
|
+
return clampResourcePayload({
|
|
3966
|
+
entry,
|
|
3967
|
+
found: true,
|
|
3968
|
+
projectId: entry.projectId,
|
|
3969
|
+
truncated: false
|
|
3970
|
+
}, () => ({
|
|
3971
|
+
entry: null,
|
|
3972
|
+
found: true,
|
|
3973
|
+
projectId: parsedProjectId.data,
|
|
3974
|
+
reason: "The registry entry exceeded the resource payload budget.",
|
|
3975
|
+
truncated: true
|
|
3976
|
+
}));
|
|
3977
|
+
}
|
|
3978
|
+
async function readEnginesResource(dependencies) {
|
|
3979
|
+
const context = dependencies.engineToolchainContext ?? createEngineToolchainContext();
|
|
3980
|
+
const installsDirectory = context.env.UE_INSTALLS_DIR?.trim() ?? null;
|
|
3981
|
+
let engineInstalls;
|
|
3982
|
+
try {
|
|
3983
|
+
engineInstalls = await listEngineInstalls(context);
|
|
3984
|
+
} catch (error) {
|
|
3985
|
+
if (!(error instanceof EngineToolchainError)) throw error;
|
|
3986
|
+
dependencies.logger.warn({ error }, "Failed to enumerate installed Unreal engines for the engines resource");
|
|
3987
|
+
return {
|
|
3988
|
+
engineInstalls: [],
|
|
3989
|
+
installsDirectory: installsDirectory && installsDirectory.length > 0 ? installsDirectory : null,
|
|
3990
|
+
reason: error.message,
|
|
3991
|
+
totalCount: 0,
|
|
3992
|
+
truncated: false
|
|
3993
|
+
};
|
|
3994
|
+
}
|
|
3995
|
+
return clampResourceList(engineInstalls, (visibleInstalls, truncated) => ({
|
|
3996
|
+
engineInstalls: visibleInstalls,
|
|
3997
|
+
installsDirectory: installsDirectory && installsDirectory.length > 0 ? installsDirectory : null,
|
|
3998
|
+
totalCount: engineInstalls.length,
|
|
3999
|
+
truncated
|
|
4000
|
+
}));
|
|
4001
|
+
}
|
|
4002
|
+
async function readWorkspaceProjectResource(dependencies) {
|
|
4003
|
+
const workingDirectory = dependencies.workingDirectory ?? process.cwd();
|
|
4004
|
+
try {
|
|
4005
|
+
const resolved = await dependencies.projectIdResolver.resolveProjectIdFromProjectPath(workingDirectory);
|
|
4006
|
+
return clampResourcePayload({
|
|
4007
|
+
configPath: resolved.configPath,
|
|
4008
|
+
projectId: resolved.projectId,
|
|
4009
|
+
projectPath: resolved.projectPath,
|
|
4010
|
+
resolved: true,
|
|
4011
|
+
truncated: false,
|
|
4012
|
+
workingDirectory
|
|
4013
|
+
}, () => ({
|
|
4014
|
+
reason: "The resolved workspace project exceeded the resource payload budget.",
|
|
4015
|
+
resolved: false,
|
|
4016
|
+
truncated: true,
|
|
4017
|
+
workingDirectory
|
|
4018
|
+
}));
|
|
4019
|
+
} catch (error) {
|
|
4020
|
+
if (!(error instanceof ProjectIdResolutionError)) throw error;
|
|
4021
|
+
return {
|
|
4022
|
+
configPath: error.filePath,
|
|
4023
|
+
reason: error.reason,
|
|
4024
|
+
resolved: false,
|
|
4025
|
+
truncated: false,
|
|
4026
|
+
workingDirectory
|
|
4027
|
+
};
|
|
4028
|
+
}
|
|
4029
|
+
}
|
|
4030
|
+
function registerMcpResources(server, dependencies) {
|
|
4031
|
+
server.registerResource("registry", REGISTRY_RESOURCE_URI, {
|
|
4032
|
+
description: "Every Unreal Editor currently registered with this server, straight from the in-memory registry. Attach this instead of calling list_registered_projects when you only need to know which editors are live and which projectId to pass to the tools. Reads no files and never contacts an editor.",
|
|
4033
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
4034
|
+
title: "Registered Unreal Editors"
|
|
4035
|
+
}, (uri) => buildResourceContents(uri, readRegistryResource(dependencies)));
|
|
4036
|
+
server.registerResource("registry-project", new ResourceTemplate(REGISTRY_PROJECT_RESOURCE_URI_TEMPLATE, {
|
|
4037
|
+
complete: { projectId: (value) => completeRegisteredProjectId(value, dependencies) },
|
|
4038
|
+
list: () => listRegistryProjectResources(dependencies)
|
|
4039
|
+
}), {
|
|
4040
|
+
description: "The registration for a single Unreal Editor, addressed by canonical 32-character ProjectID. Reports found: false with a reason rather than failing when the projectId is unknown or malformed.",
|
|
4041
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
4042
|
+
title: "Registered Unreal Editor"
|
|
4043
|
+
}, (uri, variables) => buildResourceContents(uri, readRegistryProjectResource(readTemplateVariable(variables.projectId), dependencies)));
|
|
4044
|
+
server.registerResource("engines", ENGINES_RESOURCE_URI, {
|
|
4045
|
+
description: "Unreal Engine installs discovered under UE_INSTALLS_DIR, each with its version, engine root, and whether UnrealBuildTool resolved inside it. Source builds and GUID engine associations are excluded because the build tools cannot resolve them either.",
|
|
4046
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
4047
|
+
title: "Installed Unreal Engines"
|
|
4048
|
+
}, async (uri) => buildResourceContents(uri, await readEnginesResource(dependencies)));
|
|
4049
|
+
server.registerResource("workspace-project", WORKSPACE_PROJECT_RESOURCE_URI, {
|
|
4050
|
+
description: "The Unreal project identity of the server's working directory, resolved from Config/DefaultGame.ini. Reports resolved: false with a reason when the working directory is not an Unreal project.",
|
|
4051
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
4052
|
+
title: "Workspace Unreal Project"
|
|
4053
|
+
}, async (uri) => buildResourceContents(uri, await readWorkspaceProjectResource(dependencies)));
|
|
4054
|
+
}
|
|
4055
|
+
function listRegistryProjectResources(dependencies) {
|
|
4056
|
+
return { resources: dependencies.registry.snapshot().map((entry) => ({
|
|
4057
|
+
description: `Registration for ${entry.projectName} at ${entry.projectPath}`,
|
|
4058
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
4059
|
+
name: entry.projectId,
|
|
4060
|
+
title: entry.projectName,
|
|
4061
|
+
uri: buildRegistryProjectUri(entry.projectId)
|
|
4062
|
+
})) };
|
|
4063
|
+
}
|
|
4064
|
+
function completeRegisteredProjectId(value, dependencies) {
|
|
4065
|
+
const prefix = value.trim().toLowerCase();
|
|
4066
|
+
return dependencies.registry.snapshot().map((entry) => entry.projectId).filter((projectId) => projectId.startsWith(prefix));
|
|
4067
|
+
}
|
|
4068
|
+
function buildRegistryProjectUri(projectId) {
|
|
4069
|
+
return `${REGISTRY_RESOURCE_URI}/${projectId}`;
|
|
4070
|
+
}
|
|
4071
|
+
function buildResourceContents(uri, payload) {
|
|
4072
|
+
return { contents: [{
|
|
4073
|
+
mimeType: RESOURCE_MIME_TYPE,
|
|
4074
|
+
text: serializeResourcePayload(payload),
|
|
4075
|
+
uri: uri.href
|
|
4076
|
+
}] };
|
|
4077
|
+
}
|
|
4078
|
+
function readTemplateVariable(value) {
|
|
4079
|
+
if (Array.isArray(value)) return value[0] ?? "";
|
|
4080
|
+
return value ?? "";
|
|
4081
|
+
}
|
|
4082
|
+
function clampResourceList(items, build) {
|
|
4083
|
+
const fullPayload = build(items, false);
|
|
4084
|
+
if (measureResourcePayloadBytes(fullPayload) <= 65536) return fullPayload;
|
|
4085
|
+
let smallestRejected = items.length;
|
|
4086
|
+
let largestAccepted = 0;
|
|
4087
|
+
while (largestAccepted + 1 < smallestRejected) {
|
|
4088
|
+
const candidateCount = Math.floor((largestAccepted + smallestRejected) / 2);
|
|
4089
|
+
if (measureResourcePayloadBytes(build(items.slice(0, candidateCount), true)) <= 65536) {
|
|
4090
|
+
largestAccepted = candidateCount;
|
|
4091
|
+
continue;
|
|
4092
|
+
}
|
|
4093
|
+
smallestRejected = candidateCount;
|
|
4094
|
+
}
|
|
4095
|
+
return build(items.slice(0, largestAccepted), true);
|
|
4096
|
+
}
|
|
4097
|
+
function clampResourcePayload(payload, buildMinimal) {
|
|
4098
|
+
if (measureResourcePayloadBytes(payload) <= 65536) return payload;
|
|
4099
|
+
return buildMinimal();
|
|
4100
|
+
}
|
|
4101
|
+
function measureResourcePayloadBytes(payload) {
|
|
4102
|
+
return Buffer$1.byteLength(serializeResourcePayload(payload), "utf8");
|
|
4103
|
+
}
|
|
4104
|
+
function serializeResourcePayload(payload) {
|
|
4105
|
+
return JSON.stringify(payload, null, 2);
|
|
4106
|
+
}
|
|
4107
|
+
//#endregion
|
|
4108
|
+
//#region src/mcpPrompts.ts
|
|
4109
|
+
const projectIdPromptArgument = projectIdSchema.describe("Canonical 32-character Unreal ProjectID of the target editor. Read uemcp://registry to find one.");
|
|
4110
|
+
const diagnoseCrashPromptArgs = { projectId: projectIdPromptArgument };
|
|
4111
|
+
const diagnoseBridgeDisconnectPromptArgs = { projectPath: z.string().trim().min(1).optional().describe("Filesystem path of the Unreal project directory or .uproject, when it is known.") };
|
|
4112
|
+
const smokeTestBridgePromptArgs = { projectId: projectIdPromptArgument };
|
|
4113
|
+
const addGameplayFeaturePromptArgs = {
|
|
4114
|
+
className: bridgeCreateCppClassRequestSchema.shape.className.describe("Name of the C++ class to create, without the type prefix (for example PatrolComponent)."),
|
|
4115
|
+
moduleName: bridgeCreateCppClassRequestSchema.shape.moduleName.describe("Target module for the new class. Omitted means the project’s primary game module."),
|
|
4116
|
+
parentClass: bridgeCreateCppClassRequestSchema.shape.parentClass.describe("Parent class to derive from (for example Actor, ActorComponent, or a project class)."),
|
|
4117
|
+
projectId: projectIdPromptArgument
|
|
4118
|
+
};
|
|
4119
|
+
function buildDiagnoseCrashPrompt(args) {
|
|
4120
|
+
return buildPromptResult("Investigate the most recent Unreal Editor crash for a registered project.", [
|
|
4121
|
+
`Investigate the most recent crash for Unreal project ${args.projectId}.`,
|
|
4122
|
+
"",
|
|
4123
|
+
"Work in this order and stop as soon as the cause is established:",
|
|
4124
|
+
`1. Read ${buildRegistryProjectUri(args.projectId)}, then call ping_project. A registration that is present but unreachable is the signature of a crash: deregistration only runs on a clean shutdown, so a killed process leaves its entry behind. An absent entry proves nothing on its own — the editor may never have registered, or a prior health check may already have evicted it.`,
|
|
4125
|
+
"2. Call get_crash_callstack for the project. Read the newest record first. Note the crash type, the assert or exception text, and the topmost project frames — engine frames below them are usually the victim, not the cause.",
|
|
4126
|
+
"3. Call get_editor_state to see what the editor was doing (PIE state, loaded level, current selection). A crash during PIE and a crash while idle have different suspects.",
|
|
4127
|
+
"4. Call stream_output_log with maxEvents around 50 and minVerbosity of warning. The first call establishes the subscription and returns no events; call it again with the returned cursor to drain. Look for the warnings immediately preceding the crash.",
|
|
4128
|
+
"5. If the callstack names a Blueprint, call get_blueprint_compile_errors for it; if it names a C++ symbol, call get_compile_status to check whether the running binary matches the current source.",
|
|
4129
|
+
"",
|
|
4130
|
+
"Report the crash type, the failing frame, the evidence that supports it, and the smallest change that would address it. Say so plainly if the callstack is inconclusive rather than guessing."
|
|
4131
|
+
].join("\n"));
|
|
4132
|
+
}
|
|
4133
|
+
function buildDiagnoseBridgeDisconnectPrompt(args) {
|
|
4134
|
+
const projectPathStep = args.projectPath ? `2. Call get_project_id with projectPath ${args.projectPath} to get the canonical ProjectID, then compare it to the registry entries from step 1. A mismatch means the editor and this server are reading different Config/DefaultGame.ini files.` : "2. Ask for the project path if you need one, then call get_project_id with it and compare the result to the registry entries from step 1. A mismatch means the editor and this server are reading different Config/DefaultGame.ini files.";
|
|
4135
|
+
return buildPromptResult("Diagnose why this server cannot reach a running Unreal Editor over the MCPBridge.", [
|
|
4136
|
+
"The MCP server cannot reach a running Unreal Editor. Find which leg of the connection is broken before changing anything.",
|
|
4137
|
+
"",
|
|
4138
|
+
"The two processes meet in two places: the editor registers itself over this server’s HTTP API, and this server opens a TCP bridge socket to the port the editor recorded in that registration.",
|
|
4139
|
+
"",
|
|
4140
|
+
`1. Read ${REGISTRY_RESOURCE_URI}. No entry at all means registration never landed or was evicted. An entry with a stale lastSeenAt means registration landed but health checks are failing.`,
|
|
4141
|
+
projectPathStep,
|
|
4142
|
+
"3. Call ping_project with the registered projectId. reachable: false with registrationRemoved: true means the editor’s TCP listener is gone — the editor died, or the plugin lost its port. Note that this call evicts a stale registration, so read the registry resource before calling it, not after.",
|
|
4143
|
+
"4. If the registration looks healthy but one specific tool fails, call stream_output_log and drain with the returned cursor. Plugin-side faults are logged under the LogMCPBridgeRuntime category: failures resolving the ProjectID, failures binding the bridge socket, and rejected registrations all name themselves there.",
|
|
4144
|
+
"",
|
|
4145
|
+
"Common causes, in rough order of likelihood: the editor was closed or crashed and the registration is stale; the editor is open on a different project than the one being asked about; the project directory was copied, so two directories share one ProjectID and fight over one registration; the plugin is pointed at a different server address.",
|
|
4146
|
+
"",
|
|
4147
|
+
"Report which leg is broken and the single smallest action that fixes it. Do not propose code changes until the diagnosis is complete — this failure is usually configuration, not a bug."
|
|
4148
|
+
].join("\n"));
|
|
4149
|
+
}
|
|
4150
|
+
function buildSmokeTestBridgePrompt(args) {
|
|
4151
|
+
return buildPromptResult("Prove the MCPBridge works end to end for a registered project.", [
|
|
4152
|
+
`Verify the MCPBridge is healthy for Unreal project ${args.projectId}. This is green-path verification, not fault diagnosis.`,
|
|
4153
|
+
"",
|
|
4154
|
+
`1. Read ${buildRegistryProjectUri(args.projectId)}. Expect a registration whose lastSeenAt is recent and whose port is in the 7000-7100 range.`,
|
|
4155
|
+
"2. Call ping_project. Expect reachable: true, registrationRemoved: false, and attemptsUsed: 1.",
|
|
4156
|
+
"3. Call get_editor_state. Expect the loaded level and PIE state of the editor actually open in front of the user.",
|
|
4157
|
+
"4. Exercise log streaming, which is the one path that covers subscribe, emit, drain, and unsubscribe together:",
|
|
4158
|
+
" a. Call stream_output_log with categoryAllow of [\"LogTemp\"], textContains of \"smoke-bridge-output\", and maxEvents of 10. The first call returns an empty events array and a cursor. That is correct — the subscription has nothing buffered yet.",
|
|
4159
|
+
" b. Call exec_console_command with the command: log LogTemp Warning smoke-bridge-output ping",
|
|
4160
|
+
" c. Call stream_output_log again with the same arguments plus the cursor from step 4a. Expect at least one event whose message contains smoke-bridge-output, and a nextCursor that has advanced.",
|
|
4161
|
+
"",
|
|
4162
|
+
"Report each step as pass or fail with the value that proves it. If any step fails, stop and say which one — the diagnose_bridge_disconnect prompt takes it from there. Treat an empty first drain as expected, never as a failure."
|
|
4163
|
+
].join("\n"));
|
|
4164
|
+
}
|
|
4165
|
+
function buildAddGameplayFeaturePrompt(args) {
|
|
4166
|
+
const moduleClause = args.moduleName ? ` in module ${args.moduleName}` : "";
|
|
4167
|
+
return buildPromptResult("Add a C++ gameplay class to a live Unreal project and take it through compile and test.", [
|
|
4168
|
+
`Add a C++ class ${args.className} deriving from ${args.parentClass}${moduleClause} to Unreal project ${args.projectId}, then get it compiling and tested.`,
|
|
4169
|
+
"",
|
|
4170
|
+
"Every step here is asynchronous. Each start returns a job id; do not assume success from the start call alone.",
|
|
4171
|
+
"",
|
|
4172
|
+
`1. Call create_cpp_class with className ${args.className}, parentClass ${args.parentClass}${args.moduleName ? `, moduleName ${args.moduleName}` : ""}. It returns a createClassJobId immediately.`,
|
|
4173
|
+
"2. Wait for it with wait_for_job using kind create_class, or poll get_create_class_status. Do not edit the generated files until it reports completion — the editor is still writing them.",
|
|
4174
|
+
"3. Read the generated header and source, then write the actual implementation. A generated class compiles but does nothing.",
|
|
4175
|
+
"4. Call trigger_live_compile, then wait_for_job with kind compile. On failure, read the diagnostics from get_compile_status, fix the source, and compile again. Do not proceed past a failing compile.",
|
|
4176
|
+
"5. Call list_automation_tests to find the tests covering this area, then run_automation_tests, then wait_for_job with kind test_run. Report which tests ran and which failed.",
|
|
4177
|
+
"6. Call save_dirty_packages once the work is done so nothing is left unsaved in the editor.",
|
|
4178
|
+
"",
|
|
4179
|
+
"If the project has no automation tests covering the new class, say so rather than reporting the step as passed."
|
|
4180
|
+
].join("\n"));
|
|
4181
|
+
}
|
|
4182
|
+
function registerMcpPrompts(server) {
|
|
4183
|
+
server.registerPrompt("diagnose_crash", {
|
|
4184
|
+
argsSchema: diagnoseCrashPromptArgs,
|
|
4185
|
+
description: "Walk the most recent Unreal Editor crash for a project back to its cause using the crash callstack, editor state, and output log.",
|
|
4186
|
+
title: "Diagnose Unreal Crash"
|
|
4187
|
+
}, (args) => buildDiagnoseCrashPrompt(args));
|
|
4188
|
+
server.registerPrompt("diagnose_bridge_disconnect", {
|
|
4189
|
+
argsSchema: diagnoseBridgeDisconnectPromptArgs,
|
|
4190
|
+
description: "Find which leg of the MCPBridge is broken when this server cannot reach a running Unreal Editor — missing registration, ProjectID mismatch, dead listener, or a plugin-side failure.",
|
|
4191
|
+
title: "Diagnose Bridge Disconnect"
|
|
4192
|
+
}, (args) => buildDiagnoseBridgeDisconnectPrompt(args));
|
|
4193
|
+
server.registerPrompt("smoke_test_bridge", {
|
|
4194
|
+
argsSchema: smokeTestBridgePromptArgs,
|
|
4195
|
+
description: "Prove the MCPBridge round-trips end to end for a project: registration, ping, editor state, and a full log subscribe-emit-drain cycle.",
|
|
4196
|
+
title: "Smoke-Test the Bridge"
|
|
4197
|
+
}, (args) => buildSmokeTestBridgePrompt(args));
|
|
4198
|
+
server.registerPrompt("add_gameplay_feature", {
|
|
4199
|
+
argsSchema: addGameplayFeaturePromptArgs,
|
|
4200
|
+
description: "Add a C++ gameplay class to a live Unreal project and drive it through class creation, implementation, live compile, and automation tests.",
|
|
4201
|
+
title: "Add Gameplay Feature"
|
|
4202
|
+
}, (args) => buildAddGameplayFeaturePrompt(args));
|
|
4203
|
+
}
|
|
4204
|
+
function buildPromptResult(description, text) {
|
|
4205
|
+
return {
|
|
4206
|
+
description,
|
|
4207
|
+
messages: [{
|
|
4208
|
+
content: {
|
|
4209
|
+
text,
|
|
4210
|
+
type: "text"
|
|
4211
|
+
},
|
|
4212
|
+
role: "user"
|
|
4213
|
+
}]
|
|
4214
|
+
};
|
|
4215
|
+
}
|
|
4216
|
+
//#endregion
|
|
4217
|
+
//#region src/buildDiagnostics.ts
|
|
4218
|
+
const CLANG_DIAGNOSTIC_PATTERN = /^(?<file>.+?):(?<line>\d+):(?:(?<column>\d+):)?\s+(?<severity>fatal error|error|warning):\s+(?<message>.*)$/u;
|
|
4219
|
+
const MSVC_DIAGNOSTIC_PATTERN = /^(?<file>.+?)\((?<line>\d+)(?:,\d+)?\):\s+(?<severity>fatal error|error|warning)\s+(?<code>[A-Z]+\d+):\s+(?<message>.*)$/u;
|
|
4220
|
+
const CLANG_TIDY_PATTERN = /^(?<file>.+?):(?<line>\d+):(?<column>\d+):\s+(?<severity>error|warning):\s+(?<message>.*?)(?:\s+\[(?<check>[^\]]+)\])?$/u;
|
|
4221
|
+
const COOK_LINE_PREFIX_PATTERN = /^(?:\[[^\]]*\]\s*)*(?:[A-Za-z]+Helper:\s*[^:]*:\s*)?/u;
|
|
4222
|
+
const COOK_DIAGNOSTIC_PATTERN = /^(?<category>[A-Za-z_][A-Za-z0-9_]*):\s+(?<severity>Error|Warning)(?::)?\s+(?<message>.+)$/u;
|
|
4223
|
+
const UAT_DIAGNOSTIC_PATTERN = /^(?<severity>ERROR|WARNING):\s+(?<message>.+)$/u;
|
|
4224
|
+
function diagnosticKey(diagnostic) {
|
|
4225
|
+
return `${diagnostic.file ?? ""}|${diagnostic.line ?? ""}|${diagnostic.message}`;
|
|
4226
|
+
}
|
|
4227
|
+
function matchCookDiagnostic(rawLine) {
|
|
4228
|
+
const line = rawLine.trim().replace(COOK_LINE_PREFIX_PATTERN, "").trim();
|
|
4229
|
+
if (line.length === 0) return null;
|
|
4230
|
+
const categoryMatch = COOK_DIAGNOSTIC_PATTERN.exec(line);
|
|
4231
|
+
if (categoryMatch?.groups) {
|
|
4232
|
+
const { category, message, severity } = categoryMatch.groups;
|
|
4233
|
+
if (category === void 0 || message === void 0 || severity === void 0) return null;
|
|
4234
|
+
return {
|
|
4235
|
+
isError: severity === "Error",
|
|
4236
|
+
message: `${category}: ${message.trim()}`
|
|
4237
|
+
};
|
|
4238
|
+
}
|
|
4239
|
+
const uatMatch = UAT_DIAGNOSTIC_PATTERN.exec(line);
|
|
4240
|
+
if (!uatMatch?.groups) return null;
|
|
4241
|
+
const { message, severity } = uatMatch.groups;
|
|
4242
|
+
if (message === void 0 || severity === void 0) return null;
|
|
4243
|
+
return {
|
|
4244
|
+
isError: severity === "ERROR",
|
|
4245
|
+
message: message.trim()
|
|
4246
|
+
};
|
|
4247
|
+
}
|
|
4248
|
+
var CookDiagnosticCollector = class {
|
|
4249
|
+
maxEntriesPerSeverity;
|
|
4250
|
+
errors = [];
|
|
4251
|
+
warnings = [];
|
|
4252
|
+
seenErrors = /* @__PURE__ */ new Set();
|
|
4253
|
+
seenWarnings = /* @__PURE__ */ new Set();
|
|
4254
|
+
pending = "";
|
|
4255
|
+
truncatedFlag = false;
|
|
4256
|
+
constructor(maxEntriesPerSeverity) {
|
|
4257
|
+
this.maxEntriesPerSeverity = maxEntriesPerSeverity;
|
|
4258
|
+
}
|
|
4259
|
+
push(chunk) {
|
|
4260
|
+
const lines = (this.pending + chunk).split(/\r?\n/u);
|
|
4261
|
+
this.pending = lines.pop() ?? "";
|
|
4262
|
+
for (const line of lines) this.pushLine(line);
|
|
4263
|
+
}
|
|
4264
|
+
flush() {
|
|
4265
|
+
if (this.pending.length === 0) return;
|
|
4266
|
+
const remaining = this.pending;
|
|
4267
|
+
this.pending = "";
|
|
4268
|
+
this.pushLine(remaining);
|
|
4269
|
+
}
|
|
4270
|
+
snapshot() {
|
|
4271
|
+
return {
|
|
4272
|
+
errorCount: this.errors.length,
|
|
4273
|
+
errors: [...this.errors],
|
|
4274
|
+
truncated: this.truncatedFlag,
|
|
4275
|
+
warningCount: this.warnings.length,
|
|
4276
|
+
warnings: [...this.warnings]
|
|
4277
|
+
};
|
|
4278
|
+
}
|
|
4279
|
+
pushLine(rawLine) {
|
|
4280
|
+
const matched = matchCookDiagnostic(rawLine);
|
|
4281
|
+
if (!matched) return;
|
|
4282
|
+
const diagnostic = { message: matched.message };
|
|
4283
|
+
const target = matched.isError ? this.errors : this.warnings;
|
|
4284
|
+
const seen = matched.isError ? this.seenErrors : this.seenWarnings;
|
|
4285
|
+
const key = diagnosticKey(diagnostic);
|
|
4286
|
+
if (seen.has(key)) return;
|
|
4287
|
+
seen.add(key);
|
|
4288
|
+
if (target.length >= this.maxEntriesPerSeverity) {
|
|
4289
|
+
this.truncatedFlag = true;
|
|
4290
|
+
return;
|
|
4291
|
+
}
|
|
4292
|
+
target.push(diagnostic);
|
|
4293
|
+
}
|
|
4294
|
+
};
|
|
4295
|
+
function parseBuildDiagnostics(output) {
|
|
4296
|
+
const errors = [];
|
|
4297
|
+
const warnings = [];
|
|
4298
|
+
const seenErrors = /* @__PURE__ */ new Set();
|
|
4299
|
+
const seenWarnings = /* @__PURE__ */ new Set();
|
|
4300
|
+
for (const rawLine of output.split(/\r?\n/u)) {
|
|
4301
|
+
const line = rawLine.trim();
|
|
4302
|
+
if (line.length === 0) continue;
|
|
4303
|
+
const match = CLANG_DIAGNOSTIC_PATTERN.exec(line) ?? MSVC_DIAGNOSTIC_PATTERN.exec(line);
|
|
4304
|
+
if (!match?.groups) continue;
|
|
4305
|
+
const groups = match.groups;
|
|
4306
|
+
const { file, line: lineText, message, severity } = groups;
|
|
4307
|
+
if (file === void 0 || lineText === void 0 || message === void 0 || severity === void 0) continue;
|
|
4308
|
+
const code = typeof groups.code === "string" ? `${groups.code}: ` : "";
|
|
4309
|
+
const diagnostic = {
|
|
4310
|
+
file,
|
|
4311
|
+
line: Number.parseInt(lineText, 10),
|
|
4312
|
+
message: `${code}${message}`.trim()
|
|
4313
|
+
};
|
|
4314
|
+
const isError = severity === "error" || severity === "fatal error";
|
|
4315
|
+
const target = isError ? errors : warnings;
|
|
4316
|
+
const seen = isError ? seenErrors : seenWarnings;
|
|
4317
|
+
const key = diagnosticKey(diagnostic);
|
|
4318
|
+
if (seen.has(key)) continue;
|
|
4319
|
+
seen.add(key);
|
|
4320
|
+
target.push(diagnostic);
|
|
4321
|
+
}
|
|
4322
|
+
return {
|
|
4323
|
+
errorCount: errors.length,
|
|
4324
|
+
errors,
|
|
4325
|
+
warningCount: warnings.length,
|
|
4326
|
+
warnings
|
|
4327
|
+
};
|
|
4328
|
+
}
|
|
4329
|
+
function parseClangTidyFindings(output) {
|
|
4330
|
+
const findings = [];
|
|
4331
|
+
const seen = /* @__PURE__ */ new Set();
|
|
4332
|
+
for (const rawLine of output.split(/\r?\n/u)) {
|
|
4333
|
+
const match = CLANG_TIDY_PATTERN.exec(rawLine.trim());
|
|
4334
|
+
if (!match?.groups) continue;
|
|
4335
|
+
const groups = match.groups;
|
|
4336
|
+
const { file, line, message } = groups;
|
|
4337
|
+
if (file === void 0 || line === void 0 || message === void 0) continue;
|
|
4338
|
+
const severity = groups.severity === "error" ? "error" : "warning";
|
|
4339
|
+
const finding = {
|
|
4340
|
+
check: groups.check ?? "unknown",
|
|
4341
|
+
file,
|
|
4342
|
+
line: Number.parseInt(line, 10),
|
|
4343
|
+
message: message.trim(),
|
|
4344
|
+
severity
|
|
4345
|
+
};
|
|
4346
|
+
if (typeof groups.column === "string") finding.column = Number.parseInt(groups.column, 10);
|
|
4347
|
+
const key = `${finding.file}|${finding.line}|${finding.column ?? ""}|${finding.check}|${finding.message}`;
|
|
4348
|
+
if (seen.has(key)) continue;
|
|
4349
|
+
seen.add(key);
|
|
4350
|
+
findings.push(finding);
|
|
4351
|
+
}
|
|
4352
|
+
return findings;
|
|
3469
4353
|
}
|
|
3470
4354
|
//#endregion
|
|
3471
4355
|
//#region src/moduleScaffold.ts
|
|
@@ -4863,6 +5747,62 @@ const findAssetsInputSchema = {
|
|
|
4863
5747
|
recursiveClasses: bridgeFindAssetsRequestSchema.shape.recursiveClasses.describe("Whether classNames also match subclasses (default true)."),
|
|
4864
5748
|
recursivePaths: bridgeFindAssetsRequestSchema.shape.recursivePaths.describe("Whether packagePaths also match sub-folders (default true).")
|
|
4865
5749
|
};
|
|
5750
|
+
const listActorsInputSchema = {
|
|
5751
|
+
classNames: bridgeListActorsRequestSchema.shape.classNames.describe("Actor class names to match, either short (StaticMeshActor, PointLight) or full class paths (/Script/Engine.StaticMeshActor, /Game/BP/BP_Foo.BP_Foo_C). Subclasses match too. Empty means every class."),
|
|
5752
|
+
cursor: bridgeListActorsRequestSchema.shape.cursor.describe("Offset into the stable-ordered matched list (default 0). Pass the previous response nextCursor to fetch the next page."),
|
|
5753
|
+
levelName: bridgeListActorsRequestSchema.shape.levelName.describe("Restrict the walk to a single level, by package name (/Game/Maps/MyLevel) or short name (MyLevel). Omitted means every level loaded in the editor world."),
|
|
5754
|
+
maxResults: bridgeListActorsRequestSchema.shape.maxResults.default(50).describe("Maximum number of actors to return per page (1-100, default 50). totalCount still reports the unbounded match count."),
|
|
5755
|
+
nameFilter: bridgeListActorsRequestSchema.shape.nameFilter.describe("Optional case-insensitive substring matched against each actor label and path."),
|
|
5756
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should list its actors."),
|
|
5757
|
+
tag: bridgeListActorsRequestSchema.shape.tag.describe("Optional exact-match actor tag (AActor::Tags) to filter by.")
|
|
5758
|
+
};
|
|
5759
|
+
const getActorDetailsInputSchema = {
|
|
5760
|
+
actorPath: bridgeGetActorDetailsRequestSchema.shape.actorPath.describe("Full path name of the actor, as returned by list_actors or get_editor_state (e.g. /Game/Maps/Test.Test:PersistentLevel.StaticMeshActor_3)."),
|
|
5761
|
+
componentCursor: bridgeGetActorDetailsRequestSchema.shape.componentCursor.describe("Offset into the component list (default 0). Pass the previous response nextComponentCursor to fetch the next page."),
|
|
5762
|
+
includeInherited: bridgeGetActorDetailsRequestSchema.shape.includeInherited.describe("Whether to include properties inherited from parent classes (default false). Inherited properties are the bulk of any AActor subclass."),
|
|
5763
|
+
maxResults: bridgeGetActorDetailsRequestSchema.shape.maxResults.default(25).describe("Maximum entries returned per page for each list (1-200, default 25)."),
|
|
5764
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actor."),
|
|
5765
|
+
propertyCursor: bridgeGetActorDetailsRequestSchema.shape.propertyCursor.describe("Offset into the property list (default 0). Pass the previous response nextPropertyCursor to fetch the next page.")
|
|
5766
|
+
};
|
|
5767
|
+
const getCurrentLevelInputSchema = { projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should report its loaded level.") };
|
|
5768
|
+
const spawnActorInputSchema = {
|
|
5769
|
+
dryRun: bridgeSpawnActorRequestSchema.shape.dryRun.describe("When true, validate every entry and report what would be spawned without opening a transaction or touching the world (default false)."),
|
|
5770
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should spawn the actors."),
|
|
5771
|
+
spawns: bridgeSpawnActorRequestSchema.shape.spawns.describe("Actors to spawn (1-64). Each entry needs a classPath — a native class path (/Script/Engine.StaticMeshActor) or a Blueprint generated class (/Game/BP/BP_Foo.BP_Foo_C) — plus an optional transform, label, outliner folderPath, and tags. The whole batch spawns inside one transaction, so Ctrl+Z removes all of it as a single step.")
|
|
5772
|
+
};
|
|
5773
|
+
const destroyActorInputSchema = {
|
|
5774
|
+
actorPaths: bridgeDestroyActorRequestSchema.shape.actorPaths.describe("Full path names of the actors to destroy (1-64), as returned by list_actors. The whole batch is destroyed inside one transaction, so Ctrl+Z restores all of it as a single step."),
|
|
5775
|
+
dryRun: bridgeDestroyActorRequestSchema.shape.dryRun.describe("When true, check that every actorPath resolves and report what would be destroyed without opening a transaction or touching the world (default false)."),
|
|
5776
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actors.")
|
|
5777
|
+
};
|
|
5778
|
+
const setActorTransformInputSchema = {
|
|
5779
|
+
dryRun: bridgeSetActorTransformRequestSchema.shape.dryRun.describe("When true, check that every actorPath resolves and report what would move without opening a transaction (default false)."),
|
|
5780
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actors."),
|
|
5781
|
+
transforms: bridgeSetActorTransformRequestSchema.shape.transforms.describe("Transform edits to apply (1-64). Each entry needs an actorPath plus any of location, rotation, and scale — an omitted component keeps its current value, so you can move an actor without restating its rotation. The whole batch runs in one transaction.")
|
|
5782
|
+
};
|
|
5783
|
+
const setActorPropertyInputSchema = {
|
|
5784
|
+
dryRun: bridgeSetActorPropertyRequestSchema.shape.dryRun.describe("When true, resolve every property path and check the value coerces, without opening a transaction or writing anything (default false)."),
|
|
5785
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actors."),
|
|
5786
|
+
properties: bridgeSetActorPropertyRequestSchema.shape.properties.describe("Property writes to apply (1-64). Each entry needs an actorPath, a propertyPath — 'bHidden' for an actor property or 'StaticMeshComponent.RelativeScale3D' for a component's — and a value in the same ExportText format get_actor_details and get_cdo_defaults emit. Non-editable (EditConst) properties are rejected with an error rather than silently ignored.")
|
|
5787
|
+
};
|
|
5788
|
+
const selectActorsInputSchema = {
|
|
5789
|
+
actorPaths: bridgeSelectActorsRequestSchema.shape.actorPaths.describe("Actor paths to select (up to 64). An empty list clears the selection. These are the same actorPath values list_actors and get_editor_state report."),
|
|
5790
|
+
addToSelection: bridgeSelectActorsRequestSchema.shape.addToSelection.describe("When true, add the listed actors to the current selection instead of replacing it (default false)."),
|
|
5791
|
+
dryRun: bridgeSelectActorsRequestSchema.shape.dryRun.describe("When true, check that every actorPath resolves and report what would be selected without changing the selection (default false)."),
|
|
5792
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actors.")
|
|
5793
|
+
};
|
|
5794
|
+
const undoInputSchema = { projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should undo its last transaction.") };
|
|
5795
|
+
const redoInputSchema = { projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should redo its last undone transaction.") };
|
|
5796
|
+
const openLevelInputSchema = {
|
|
5797
|
+
dryRun: bridgeOpenLevelRequestSchema.shape.dryRun.describe("When true, check that the level package exists and report what would be opened without loading it (default false)."),
|
|
5798
|
+
levelPath: bridgeOpenLevelRequestSchema.shape.levelPath.describe("Package name of the level to open (e.g. /Game/Maps/MyLevel), as get_current_level and find_assets report it."),
|
|
5799
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should open the level."),
|
|
5800
|
+
saveDirtyPackages: bridgeOpenLevelRequestSchema.shape.saveDirtyPackages.describe("When true, save dirty packages before tearing down the current world; otherwise unsaved changes are discarded (default false).")
|
|
5801
|
+
};
|
|
5802
|
+
const getOpenLevelStatusInputSchema = {
|
|
5803
|
+
openLevelJobId: bridgeGetOpenLevelStatusRequestSchema.shape.openLevelJobId.describe("openLevelJobId returned by open_level identifying the load job to poll."),
|
|
5804
|
+
projectId: projectIdSchema
|
|
5805
|
+
};
|
|
4866
5806
|
const getAssetDependenciesInputSchema = {
|
|
4867
5807
|
assetPath: bridgeGetAssetDependenciesRequestSchema.shape.assetPath.describe("Package name or object path of the asset to inspect (e.g. /Game/BP/BP_Player or /Game/BP/BP_Player.BP_Player)."),
|
|
4868
5808
|
categories: bridgeGetAssetDependenciesRequestSchema.shape.categories.describe("Dependency categories to include: 'package' (default), 'searchable_name', 'manage'."),
|
|
@@ -5253,7 +6193,7 @@ function registerMcpTools(server, dependencies) {
|
|
|
5253
6193
|
}, dependencies));
|
|
5254
6194
|
});
|
|
5255
6195
|
server.registerTool("get_editor_state", {
|
|
5256
|
-
description: "Report the registered Unreal Editor's current state for a project: the open map name and package path, the
|
|
6196
|
+
description: "Report the registered Unreal Editor's current state for a project: the open map name and package path, the selected actors as { actorPath, label } objects whose actorPath the level tools accept directly, the active editor modes, and whether Play-in-Editor is running. Selected actors are capped per response; selectedActorCount reports the full selection size. activeModes is empty until the level editor has finished initializing, so an empty list right after the editor starts means 'not ready yet', not 'no mode'.",
|
|
5257
6197
|
inputSchema: getEditorStateInputSchema,
|
|
5258
6198
|
title: "Get Editor State"
|
|
5259
6199
|
}, async ({ projectId }) => {
|
|
@@ -5380,6 +6320,134 @@ function registerMcpTools(server, dependencies) {
|
|
|
5380
6320
|
projectId
|
|
5381
6321
|
}, dependencies));
|
|
5382
6322
|
});
|
|
6323
|
+
server.registerTool("list_actors", {
|
|
6324
|
+
description: "Enumerate actors in the editor's currently loaded level(s), optionally filtered by class, name substring, tag, or level. Returns each actor's canonical actorPath (the identifier every other level tool takes), display label, class, level, and World Outliner folder. Results are paged: pass the previous response nextCursor to fetch the next page, and totalCount reports the full match count even when a page truncates. Use this to find an actor before calling get_actor_details.",
|
|
6325
|
+
inputSchema: listActorsInputSchema,
|
|
6326
|
+
title: "List Actors"
|
|
6327
|
+
}, async ({ classNames, cursor, levelName, maxResults, nameFilter, projectId, tag }) => {
|
|
6328
|
+
return toToolSuccess(await listActors({
|
|
6329
|
+
classNames,
|
|
6330
|
+
cursor,
|
|
6331
|
+
levelName,
|
|
6332
|
+
maxResults,
|
|
6333
|
+
nameFilter,
|
|
6334
|
+
projectId,
|
|
6335
|
+
tag
|
|
6336
|
+
}, dependencies));
|
|
6337
|
+
});
|
|
6338
|
+
server.registerTool("get_actor_details", {
|
|
6339
|
+
description: "Inspect one actor in the loaded level by its actorPath: world transform, attached component hierarchy (each component's name, class, attachment parent, and relative transform), and reflected UPROPERTY values. Property values use the same ExportText format get_cdo_defaults emits, so a value read here can be written back verbatim. Components and properties page independently — pass nextComponentCursor / nextPropertyCursor to continue each list. Inherited properties are excluded unless includeInherited is true.",
|
|
6340
|
+
inputSchema: getActorDetailsInputSchema,
|
|
6341
|
+
title: "Get Actor Details"
|
|
6342
|
+
}, async ({ actorPath, componentCursor, includeInherited, maxResults, projectId, propertyCursor }) => {
|
|
6343
|
+
return toToolSuccess(await getActorDetails({
|
|
6344
|
+
actorPath,
|
|
6345
|
+
componentCursor,
|
|
6346
|
+
includeInherited,
|
|
6347
|
+
maxResults,
|
|
6348
|
+
projectId,
|
|
6349
|
+
propertyCursor
|
|
6350
|
+
}, dependencies));
|
|
6351
|
+
});
|
|
6352
|
+
server.registerTool("get_current_level", {
|
|
6353
|
+
description: "Report the level the editor currently has open — its short name and package path — plus every streaming level registered on that world with its loaded and visible state. worldPartition=true means the map streams cells through World Partition rather than through the listed ULevelStreaming entries, so the streamingLevels list will usually be empty for such a map. Returns no level fields when the editor has no world loaded.",
|
|
6354
|
+
inputSchema: getCurrentLevelInputSchema,
|
|
6355
|
+
title: "Get Current Level"
|
|
6356
|
+
}, async ({ projectId }) => {
|
|
6357
|
+
return toToolSuccess(await getCurrentLevel({ projectId }, dependencies));
|
|
6358
|
+
});
|
|
6359
|
+
server.registerTool("spawn_actor", {
|
|
6360
|
+
description: "Spawn one or more actors into the editor's loaded level. Each entry takes a classPath (native or Blueprint generated class) and an optional transform, label, outliner folder, and tags. The whole batch runs inside a single editor transaction, so a human pressing Ctrl+Z removes every actor the call spawned as one step, and save_dirty_packages will report the level afterwards. Returns a per-entry result carrying the new actorPath or the reason that entry failed; a failed entry does not abort the rest of the batch. Pass dryRun: true to validate the batch and see what would be spawned without changing anything.",
|
|
6361
|
+
inputSchema: spawnActorInputSchema,
|
|
6362
|
+
title: "Spawn Actor"
|
|
6363
|
+
}, async ({ dryRun, projectId, spawns }) => {
|
|
6364
|
+
return toToolSuccess(await spawnActor({
|
|
6365
|
+
dryRun,
|
|
6366
|
+
projectId,
|
|
6367
|
+
spawns
|
|
6368
|
+
}, dependencies));
|
|
6369
|
+
});
|
|
6370
|
+
server.registerTool("destroy_actor", {
|
|
6371
|
+
description: "Destroy one or more actors in the loaded level, addressed by the actorPath list_actors returns. The whole batch runs inside a single editor transaction, so Ctrl+Z restores every actor the call destroyed as one step. Returns a per-entry result; an actorPath that no longer resolves fails only its own entry. Pass dryRun: true to check the paths and see what would be destroyed without changing anything.",
|
|
6372
|
+
inputSchema: destroyActorInputSchema,
|
|
6373
|
+
title: "Destroy Actor"
|
|
6374
|
+
}, async ({ actorPaths, dryRun, projectId }) => {
|
|
6375
|
+
return toToolSuccess(await destroyActor({
|
|
6376
|
+
actorPaths,
|
|
6377
|
+
dryRun,
|
|
6378
|
+
projectId
|
|
6379
|
+
}, dependencies));
|
|
6380
|
+
});
|
|
6381
|
+
server.registerTool("set_actor_transform", {
|
|
6382
|
+
description: "Move, rotate, and/or scale one or more actors in the loaded level. Each entry addresses an actor by actorPath and supplies any of location, rotation, and scale — an omitted component keeps its current value. The whole batch runs inside a single editor transaction, so Ctrl+Z restores every original transform as one step. Returns a per-entry result; pass dryRun: true to check the paths without moving anything.",
|
|
6383
|
+
inputSchema: setActorTransformInputSchema,
|
|
6384
|
+
title: "Set Actor Transform"
|
|
6385
|
+
}, async ({ dryRun, projectId, transforms }) => {
|
|
6386
|
+
return toToolSuccess(await setActorTransform({
|
|
6387
|
+
dryRun,
|
|
6388
|
+
projectId,
|
|
6389
|
+
transforms
|
|
6390
|
+
}, dependencies));
|
|
6391
|
+
});
|
|
6392
|
+
server.registerTool("set_actor_property", {
|
|
6393
|
+
description: "Write reflected UPROPERTY values on actors or their components in the loaded level. Each entry takes an actorPath, a propertyPath ('bHidden' on the actor, 'StaticMeshComponent.RelativeScale3D' on a component), and a value in the same ExportText format get_actor_details and get_cdo_defaults emit — so you can read a value, edit it, and write it back without translating. Properties marked EditConst or not exposed for editing are rejected with an explicit error rather than silently ignored. The whole batch runs in one transaction; pass dryRun: true to resolve paths and check coercion without writing.",
|
|
6394
|
+
inputSchema: setActorPropertyInputSchema,
|
|
6395
|
+
title: "Set Actor Property"
|
|
6396
|
+
}, async ({ dryRun, projectId, properties }) => {
|
|
6397
|
+
return toToolSuccess(await setActorProperty({
|
|
6398
|
+
dryRun,
|
|
6399
|
+
projectId,
|
|
6400
|
+
properties
|
|
6401
|
+
}, dependencies));
|
|
6402
|
+
});
|
|
6403
|
+
server.registerTool("select_actors", {
|
|
6404
|
+
description: "Set the editor's actor selection — the write-side counterpart to get_editor_state, using the same actorPath identifiers list_actors returns. An empty actorPaths list clears the selection; addToSelection adds to it instead of replacing it. Runs inside a transaction, so Ctrl+Z restores the previous selection. Returns the resulting selectedActorCount plus a per-entry result for any path that no longer resolves.",
|
|
6405
|
+
inputSchema: selectActorsInputSchema,
|
|
6406
|
+
title: "Select Actors"
|
|
6407
|
+
}, async ({ actorPaths, addToSelection, dryRun, projectId }) => {
|
|
6408
|
+
return toToolSuccess(await selectActors({
|
|
6409
|
+
actorPaths,
|
|
6410
|
+
addToSelection,
|
|
6411
|
+
dryRun,
|
|
6412
|
+
projectId
|
|
6413
|
+
}, dependencies));
|
|
6414
|
+
});
|
|
6415
|
+
server.registerTool("undo", {
|
|
6416
|
+
description: "Undo the editor's most recent transaction — the same action as pressing Ctrl+Z in the editor — and report the title of the transaction that was undone. Use this to roll back your own level edits without a human in the loop. Returns state 'nothing_to_undo' when the transaction buffer is empty. Note this undoes whatever is at the head of the buffer, which may be a human's edit rather than yours, so check the returned transactionTitle.",
|
|
6417
|
+
inputSchema: undoInputSchema,
|
|
6418
|
+
title: "Undo"
|
|
6419
|
+
}, async ({ projectId }) => {
|
|
6420
|
+
return toToolSuccess(await undo({ projectId }, dependencies));
|
|
6421
|
+
});
|
|
6422
|
+
server.registerTool("redo", {
|
|
6423
|
+
description: "Redo the editor's most recently undone transaction — the same action as pressing Ctrl+Y in the editor — and report the title of the transaction that was redone. Returns state 'nothing_to_redo' when there is nothing to reapply.",
|
|
6424
|
+
inputSchema: redoInputSchema,
|
|
6425
|
+
title: "Redo"
|
|
6426
|
+
}, async ({ projectId }) => {
|
|
6427
|
+
return toToolSuccess(await redo({ projectId }, dependencies));
|
|
6428
|
+
});
|
|
6429
|
+
server.registerTool("open_level", {
|
|
6430
|
+
description: "Open a level in the editor by package name. Loading a map tears down and rebuilds the world, which takes far longer than a bridge request can wait, so this only accepts the job: it returns state 'opening' with an openLevelJobId to poll with get_open_level_status. Unsaved changes in the current world are discarded unless saveDirtyPackages is true. This is NOT undoable — loading a map clears the editor's transaction buffer, so undo cannot bring the previous level back.",
|
|
6431
|
+
inputSchema: openLevelInputSchema,
|
|
6432
|
+
title: "Open Level"
|
|
6433
|
+
}, async ({ dryRun, levelPath, projectId, saveDirtyPackages }) => {
|
|
6434
|
+
return toToolSuccess(await openLevel({
|
|
6435
|
+
dryRun,
|
|
6436
|
+
levelPath,
|
|
6437
|
+
projectId,
|
|
6438
|
+
saveDirtyPackages
|
|
6439
|
+
}, dependencies));
|
|
6440
|
+
});
|
|
6441
|
+
server.registerTool("get_open_level_status", {
|
|
6442
|
+
description: "Poll a level load started by open_level for a projectId; returns state (opening, succeeded, failed, unknown_job), the loaded levelPath, and timing once finished. Poll until the state leaves 'opening' before issuing further level tools — actor paths from the previous world do not survive the load.",
|
|
6443
|
+
inputSchema: getOpenLevelStatusInputSchema,
|
|
6444
|
+
title: "Get Open Level Status"
|
|
6445
|
+
}, async ({ openLevelJobId, projectId }) => {
|
|
6446
|
+
return toToolSuccess(await getOpenLevelStatus({
|
|
6447
|
+
openLevelJobId,
|
|
6448
|
+
projectId
|
|
6449
|
+
}, dependencies));
|
|
6450
|
+
});
|
|
5383
6451
|
server.registerTool("find_assets", {
|
|
5384
6452
|
description: "Query a project's Unreal Asset Registry for assets by class and/or content path, without loading them; returns each match's name, class, package name, package path, and object path. Requires at least one of classNames or packagePaths — an unfiltered query would stall the editor enumerating every asset. Results are paged: pass the previous response nextCursor to fetch the next page (totalCount reports the full match count). scanning=true means the registry is still indexing, so an empty result does not prove the asset is absent.",
|
|
5385
6453
|
inputSchema: findAssetsInputSchema,
|
|
@@ -5489,6 +6557,285 @@ function registerMcpTools(server, dependencies) {
|
|
|
5489
6557
|
}, dependencies));
|
|
5490
6558
|
});
|
|
5491
6559
|
}
|
|
6560
|
+
async function listActors(input, dependencies) {
|
|
6561
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6562
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6563
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6564
|
+
const response = await sendBridgeListActorsRequest(createBridgeListActorsRequest({
|
|
6565
|
+
classNames: input.classNames,
|
|
6566
|
+
cursor: input.cursor,
|
|
6567
|
+
levelName: input.levelName,
|
|
6568
|
+
maxResults: input.maxResults,
|
|
6569
|
+
nameFilter: input.nameFilter,
|
|
6570
|
+
tag: input.tag
|
|
6571
|
+
}), {
|
|
6572
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6573
|
+
host: "127.0.0.1",
|
|
6574
|
+
port: entry.port,
|
|
6575
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6576
|
+
});
|
|
6577
|
+
if (!response.ok) throw new Error(`Bridge list_actors failed (${response.error.code}): ${response.error.message}`);
|
|
6578
|
+
return {
|
|
6579
|
+
actors: response.actors,
|
|
6580
|
+
message: response.message,
|
|
6581
|
+
nextCursor: response.nextCursor,
|
|
6582
|
+
projectId: entry.projectId,
|
|
6583
|
+
totalCount: response.totalCount,
|
|
6584
|
+
truncated: response.truncated
|
|
6585
|
+
};
|
|
6586
|
+
}
|
|
6587
|
+
async function getActorDetails(input, dependencies) {
|
|
6588
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6589
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6590
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6591
|
+
const response = await sendBridgeGetActorDetailsRequest(createBridgeGetActorDetailsRequest(input.actorPath, {
|
|
6592
|
+
componentCursor: input.componentCursor,
|
|
6593
|
+
includeInherited: input.includeInherited,
|
|
6594
|
+
maxResults: input.maxResults,
|
|
6595
|
+
propertyCursor: input.propertyCursor
|
|
6596
|
+
}), {
|
|
6597
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6598
|
+
host: "127.0.0.1",
|
|
6599
|
+
port: entry.port,
|
|
6600
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6601
|
+
});
|
|
6602
|
+
if (!response.ok) throw new Error(`Bridge get_actor_details failed (${response.error.code}): ${response.error.message}`);
|
|
6603
|
+
return {
|
|
6604
|
+
actorPath: response.actorPath,
|
|
6605
|
+
className: response.className,
|
|
6606
|
+
componentCount: response.componentCount,
|
|
6607
|
+
components: response.components,
|
|
6608
|
+
componentTruncated: response.componentTruncated,
|
|
6609
|
+
folderPath: response.folderPath,
|
|
6610
|
+
label: response.label,
|
|
6611
|
+
levelName: response.levelName,
|
|
6612
|
+
nextComponentCursor: response.nextComponentCursor,
|
|
6613
|
+
nextPropertyCursor: response.nextPropertyCursor,
|
|
6614
|
+
projectId: entry.projectId,
|
|
6615
|
+
properties: response.properties,
|
|
6616
|
+
propertyCount: response.propertyCount,
|
|
6617
|
+
propertyTruncated: response.propertyTruncated,
|
|
6618
|
+
transform: response.transform
|
|
6619
|
+
};
|
|
6620
|
+
}
|
|
6621
|
+
async function getCurrentLevel(input, dependencies) {
|
|
6622
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6623
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6624
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6625
|
+
const response = await sendBridgeGetCurrentLevelRequest(createBridgeGetCurrentLevelRequest(), {
|
|
6626
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6627
|
+
host: "127.0.0.1",
|
|
6628
|
+
port: entry.port,
|
|
6629
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6630
|
+
});
|
|
6631
|
+
if (!response.ok) throw new Error(`Bridge get_current_level failed (${response.error.code}): ${response.error.message}`);
|
|
6632
|
+
return {
|
|
6633
|
+
levelName: response.levelName,
|
|
6634
|
+
levelPath: response.levelPath,
|
|
6635
|
+
message: response.message,
|
|
6636
|
+
projectId: entry.projectId,
|
|
6637
|
+
streamingLevelCount: response.streamingLevelCount,
|
|
6638
|
+
streamingLevels: response.streamingLevels,
|
|
6639
|
+
truncated: response.truncated,
|
|
6640
|
+
worldPartition: response.worldPartition
|
|
6641
|
+
};
|
|
6642
|
+
}
|
|
6643
|
+
async function spawnActor(input, dependencies) {
|
|
6644
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6645
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6646
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6647
|
+
const response = await sendBridgeSpawnActorRequest(createBridgeSpawnActorRequest(input.spawns, { dryRun: input.dryRun }), {
|
|
6648
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6649
|
+
host: "127.0.0.1",
|
|
6650
|
+
port: entry.port,
|
|
6651
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6652
|
+
});
|
|
6653
|
+
if (!response.ok) throw new Error(`Bridge spawn_actor failed (${response.error.code}): ${response.error.message}`);
|
|
6654
|
+
return {
|
|
6655
|
+
dryRun: response.dryRun,
|
|
6656
|
+
failureCount: response.failureCount,
|
|
6657
|
+
message: response.message,
|
|
6658
|
+
projectId: entry.projectId,
|
|
6659
|
+
results: response.results,
|
|
6660
|
+
state: response.state,
|
|
6661
|
+
successCount: response.successCount,
|
|
6662
|
+
transactionTitle: response.transactionTitle
|
|
6663
|
+
};
|
|
6664
|
+
}
|
|
6665
|
+
async function destroyActor(input, dependencies) {
|
|
6666
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6667
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6668
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6669
|
+
const response = await sendBridgeDestroyActorRequest(createBridgeDestroyActorRequest(input.actorPaths, { dryRun: input.dryRun }), {
|
|
6670
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6671
|
+
host: "127.0.0.1",
|
|
6672
|
+
port: entry.port,
|
|
6673
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6674
|
+
});
|
|
6675
|
+
if (!response.ok) throw new Error(`Bridge destroy_actor failed (${response.error.code}): ${response.error.message}`);
|
|
6676
|
+
return {
|
|
6677
|
+
dryRun: response.dryRun,
|
|
6678
|
+
failureCount: response.failureCount,
|
|
6679
|
+
message: response.message,
|
|
6680
|
+
projectId: entry.projectId,
|
|
6681
|
+
results: response.results,
|
|
6682
|
+
state: response.state,
|
|
6683
|
+
successCount: response.successCount,
|
|
6684
|
+
transactionTitle: response.transactionTitle
|
|
6685
|
+
};
|
|
6686
|
+
}
|
|
6687
|
+
async function setActorTransform(input, dependencies) {
|
|
6688
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6689
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6690
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6691
|
+
const response = await sendBridgeSetActorTransformRequest(createBridgeSetActorTransformRequest(input.transforms, { dryRun: input.dryRun }), {
|
|
6692
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6693
|
+
host: "127.0.0.1",
|
|
6694
|
+
port: entry.port,
|
|
6695
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6696
|
+
});
|
|
6697
|
+
if (!response.ok) throw new Error(`Bridge set_actor_transform failed (${response.error.code}): ${response.error.message}`);
|
|
6698
|
+
return {
|
|
6699
|
+
dryRun: response.dryRun,
|
|
6700
|
+
failureCount: response.failureCount,
|
|
6701
|
+
message: response.message,
|
|
6702
|
+
projectId: entry.projectId,
|
|
6703
|
+
results: response.results,
|
|
6704
|
+
state: response.state,
|
|
6705
|
+
successCount: response.successCount,
|
|
6706
|
+
transactionTitle: response.transactionTitle
|
|
6707
|
+
};
|
|
6708
|
+
}
|
|
6709
|
+
async function setActorProperty(input, dependencies) {
|
|
6710
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6711
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6712
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6713
|
+
const response = await sendBridgeSetActorPropertyRequest(createBridgeSetActorPropertyRequest(input.properties, { dryRun: input.dryRun }), {
|
|
6714
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6715
|
+
host: "127.0.0.1",
|
|
6716
|
+
port: entry.port,
|
|
6717
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6718
|
+
});
|
|
6719
|
+
if (!response.ok) throw new Error(`Bridge set_actor_property failed (${response.error.code}): ${response.error.message}`);
|
|
6720
|
+
return {
|
|
6721
|
+
dryRun: response.dryRun,
|
|
6722
|
+
failureCount: response.failureCount,
|
|
6723
|
+
message: response.message,
|
|
6724
|
+
projectId: entry.projectId,
|
|
6725
|
+
results: response.results,
|
|
6726
|
+
state: response.state,
|
|
6727
|
+
successCount: response.successCount,
|
|
6728
|
+
transactionTitle: response.transactionTitle
|
|
6729
|
+
};
|
|
6730
|
+
}
|
|
6731
|
+
async function selectActors(input, dependencies) {
|
|
6732
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6733
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6734
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6735
|
+
const response = await sendBridgeSelectActorsRequest(createBridgeSelectActorsRequest(input.actorPaths, {
|
|
6736
|
+
addToSelection: input.addToSelection,
|
|
6737
|
+
dryRun: input.dryRun
|
|
6738
|
+
}), {
|
|
6739
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6740
|
+
host: "127.0.0.1",
|
|
6741
|
+
port: entry.port,
|
|
6742
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6743
|
+
});
|
|
6744
|
+
if (!response.ok) throw new Error(`Bridge select_actors failed (${response.error.code}): ${response.error.message}`);
|
|
6745
|
+
return {
|
|
6746
|
+
dryRun: response.dryRun,
|
|
6747
|
+
failureCount: response.failureCount,
|
|
6748
|
+
message: response.message,
|
|
6749
|
+
projectId: entry.projectId,
|
|
6750
|
+
results: response.results,
|
|
6751
|
+
selectedActorCount: response.selectedActorCount,
|
|
6752
|
+
state: response.state,
|
|
6753
|
+
successCount: response.successCount,
|
|
6754
|
+
transactionTitle: response.transactionTitle
|
|
6755
|
+
};
|
|
6756
|
+
}
|
|
6757
|
+
async function undo(input, dependencies) {
|
|
6758
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6759
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6760
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6761
|
+
const response = await sendBridgeUndoRequest(createBridgeUndoRequest(), {
|
|
6762
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6763
|
+
host: "127.0.0.1",
|
|
6764
|
+
port: entry.port,
|
|
6765
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6766
|
+
});
|
|
6767
|
+
if (!response.ok) throw new Error(`Bridge undo failed (${response.error.code}): ${response.error.message}`);
|
|
6768
|
+
return {
|
|
6769
|
+
message: response.message,
|
|
6770
|
+
projectId: entry.projectId,
|
|
6771
|
+
state: response.state,
|
|
6772
|
+
transactionTitle: response.transactionTitle
|
|
6773
|
+
};
|
|
6774
|
+
}
|
|
6775
|
+
async function redo(input, dependencies) {
|
|
6776
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6777
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6778
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6779
|
+
const response = await sendBridgeRedoRequest(createBridgeRedoRequest(), {
|
|
6780
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6781
|
+
host: "127.0.0.1",
|
|
6782
|
+
port: entry.port,
|
|
6783
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6784
|
+
});
|
|
6785
|
+
if (!response.ok) throw new Error(`Bridge redo failed (${response.error.code}): ${response.error.message}`);
|
|
6786
|
+
return {
|
|
6787
|
+
message: response.message,
|
|
6788
|
+
projectId: entry.projectId,
|
|
6789
|
+
state: response.state,
|
|
6790
|
+
transactionTitle: response.transactionTitle
|
|
6791
|
+
};
|
|
6792
|
+
}
|
|
6793
|
+
async function openLevel(input, dependencies) {
|
|
6794
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6795
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6796
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6797
|
+
const request = createBridgeOpenLevelRequest(input.levelPath, {
|
|
6798
|
+
dryRun: input.dryRun,
|
|
6799
|
+
saveDirtyPackages: input.saveDirtyPackages
|
|
6800
|
+
});
|
|
6801
|
+
const response = await sendBridgeOpenLevelRequest(request, {
|
|
6802
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6803
|
+
host: "127.0.0.1",
|
|
6804
|
+
port: entry.port,
|
|
6805
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6806
|
+
});
|
|
6807
|
+
if (!response.ok) throw new Error(`Bridge open_level failed (${response.error.code}): ${response.error.message}`);
|
|
6808
|
+
const result = {
|
|
6809
|
+
levelPath: response.levelPath ?? request.levelPath,
|
|
6810
|
+
projectId: entry.projectId,
|
|
6811
|
+
state: response.state
|
|
6812
|
+
};
|
|
6813
|
+
if (response.openLevelJobId !== void 0) result.openLevelJobId = response.openLevelJobId;
|
|
6814
|
+
if (response.message !== void 0) result.message = response.message;
|
|
6815
|
+
return result;
|
|
6816
|
+
}
|
|
6817
|
+
async function getOpenLevelStatus(input, dependencies) {
|
|
6818
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
6819
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
6820
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
6821
|
+
const response = await sendBridgeGetOpenLevelStatusRequest(createBridgeGetOpenLevelStatusRequest(input.openLevelJobId), {
|
|
6822
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
6823
|
+
host: "127.0.0.1",
|
|
6824
|
+
port: entry.port,
|
|
6825
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
6826
|
+
});
|
|
6827
|
+
if (!response.ok) throw new Error(`Bridge get_open_level_status failed (${response.error.code}): ${response.error.message}`);
|
|
6828
|
+
const result = {
|
|
6829
|
+
openLevelJobId: response.openLevelJobId,
|
|
6830
|
+
projectId: normalizedProjectId,
|
|
6831
|
+
state: response.state
|
|
6832
|
+
};
|
|
6833
|
+
if (response.levelPath !== void 0) result.levelPath = response.levelPath;
|
|
6834
|
+
if (response.message !== void 0) result.message = response.message;
|
|
6835
|
+
if (response.finishedAt !== void 0) result.finishedAt = response.finishedAt;
|
|
6836
|
+
if (response.durationMs !== void 0) result.durationMs = response.durationMs;
|
|
6837
|
+
return result;
|
|
6838
|
+
}
|
|
5492
6839
|
async function findAssets(input, dependencies) {
|
|
5493
6840
|
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
5494
6841
|
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
@@ -6882,7 +8229,7 @@ function isMissingFileError(error) {
|
|
|
6882
8229
|
//#endregion
|
|
6883
8230
|
//#region src/server.ts
|
|
6884
8231
|
const SERVER_NAME = "ue-mcp-server";
|
|
6885
|
-
const SERVER_VERSION = "0.
|
|
8232
|
+
const SERVER_VERSION = "1.0.0";
|
|
6886
8233
|
const logger = createModuleLogger("bootstrap");
|
|
6887
8234
|
const enginePingLogger = createModuleLogger("engine-ping");
|
|
6888
8235
|
const httpApiLogger = createModuleLogger("http-api");
|
|
@@ -6901,8 +8248,12 @@ async function startServer(options) {
|
|
|
6901
8248
|
readTimeoutMs: options.config.startupPingTimeoutMs
|
|
6902
8249
|
});
|
|
6903
8250
|
await pruneRegistryEntries(registry, store, options.config);
|
|
8251
|
+
let notifyRegistryChanged = () => {};
|
|
6904
8252
|
const httpApi = createHttpApi({
|
|
6905
8253
|
logger: httpApiLogger,
|
|
8254
|
+
onRegistryChanged: () => {
|
|
8255
|
+
notifyRegistryChanged();
|
|
8256
|
+
},
|
|
6906
8257
|
projectIdResolver,
|
|
6907
8258
|
registry,
|
|
6908
8259
|
registryWriteQueue,
|
|
@@ -6915,7 +8266,7 @@ async function startServer(options) {
|
|
|
6915
8266
|
const listeningHttpPort = getListeningHttpPort(httpApi, options.config.httpPort);
|
|
6916
8267
|
let mcpServer;
|
|
6917
8268
|
try {
|
|
6918
|
-
|
|
8269
|
+
const createdMcpServer = createMcpServer({
|
|
6919
8270
|
logger: mcpToolLogger,
|
|
6920
8271
|
logSessionManager,
|
|
6921
8272
|
pingTimeoutMs: options.config.startupPingTimeoutMs,
|
|
@@ -6924,6 +8275,10 @@ async function startServer(options) {
|
|
|
6924
8275
|
registryWriteQueue,
|
|
6925
8276
|
store
|
|
6926
8277
|
});
|
|
8278
|
+
mcpServer = createdMcpServer;
|
|
8279
|
+
notifyRegistryChanged = () => {
|
|
8280
|
+
createdMcpServer.sendResourceListChanged();
|
|
8281
|
+
};
|
|
6927
8282
|
if (options.connectMcpTransport !== false) await mcpServer.connect(new StdioServerTransport());
|
|
6928
8283
|
} catch (error) {
|
|
6929
8284
|
try {
|
|
@@ -6977,8 +8332,14 @@ function createMcpServer(dependencies) {
|
|
|
6977
8332
|
const server = new McpServer({
|
|
6978
8333
|
name: SERVER_NAME,
|
|
6979
8334
|
version: SERVER_VERSION
|
|
6980
|
-
}, { capabilities: {
|
|
8335
|
+
}, { capabilities: {
|
|
8336
|
+
prompts: {},
|
|
8337
|
+
resources: {},
|
|
8338
|
+
tools: {}
|
|
8339
|
+
} });
|
|
6981
8340
|
registerMcpTools(server, dependencies);
|
|
8341
|
+
registerMcpResources(server, dependencies);
|
|
8342
|
+
registerMcpPrompts(server);
|
|
6982
8343
|
return server;
|
|
6983
8344
|
}
|
|
6984
8345
|
async function pruneRegistryEntries(registry, store, config) {
|