@uemcp/server 1.8.0 → 1.9.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.mjs +1688 -651
- package/package.json +2 -1
package/dist/index.mjs
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import os, { tmpdir } from "node:os";
|
|
3
|
-
import path from "node:path";
|
|
2
|
+
import os, { homedir, tmpdir } from "node:os";
|
|
3
|
+
import path, { join } from "node:path";
|
|
4
4
|
import { z } from "zod";
|
|
5
5
|
import { McpServer, ResourceTemplate } from "@modelcontextprotocol/sdk/server/mcp.js";
|
|
6
6
|
import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
|
|
@@ -10,9 +10,10 @@ import Fastify from "fastify";
|
|
|
10
10
|
import { Buffer as Buffer$1 } from "node:buffer";
|
|
11
11
|
import pino from "pino";
|
|
12
12
|
import { spawn } from "node:child_process";
|
|
13
|
-
import { createReadStream } from "node:fs";
|
|
14
|
-
import { access, mkdir, mkdtemp, open, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
13
|
+
import { createReadStream, existsSync } from "node:fs";
|
|
14
|
+
import { access, copyFile, mkdir, mkdtemp, open, readFile, readdir, rename, rm, stat, writeFile } from "node:fs/promises";
|
|
15
15
|
import { createInterface } from "node:readline";
|
|
16
|
+
import { PNG } from "pngjs";
|
|
16
17
|
//#region src/errors.ts
|
|
17
18
|
var McpServerError = class extends Error {
|
|
18
19
|
constructor(message, options) {
|
|
@@ -397,14 +398,30 @@ const TOOL_METADATA = {
|
|
|
397
398
|
]),
|
|
398
399
|
build_texture_streaming: mutates("level", "start_editor_build"),
|
|
399
400
|
build_virtual_textures: mutates("level", "start_editor_build"),
|
|
401
|
+
call_actor_function: mutates("test", "call_actor_function", [
|
|
402
|
+
"call function",
|
|
403
|
+
"invoke",
|
|
404
|
+
"runtime"
|
|
405
|
+
]),
|
|
400
406
|
call_tool: mutates("core", void 0, ["dispatch", "invoke"]),
|
|
401
407
|
cancel_package_job: idempotentMutates("build"),
|
|
402
408
|
cancel_test_run: idempotentMutates("test", "cancel_automation_run"),
|
|
403
409
|
capture_viewport: readOnly("core", "capture_viewport", ["screenshot", "image"]),
|
|
404
410
|
checkout_assets: mutates("asset", "checkout_assets"),
|
|
405
411
|
clean_build: destroys("build", void 0, ["intermediate", "binaries"]),
|
|
412
|
+
compare_viewport_baseline: reachesOutside("core", false, "capture_viewport", [
|
|
413
|
+
"baseline",
|
|
414
|
+
"visual regression",
|
|
415
|
+
"diff",
|
|
416
|
+
"screenshot"
|
|
417
|
+
]),
|
|
406
418
|
compile_blueprint: idempotentMutates("blueprint", "compile_blueprint"),
|
|
407
419
|
connect_pins: mutates("blueprint", "connect_pins"),
|
|
420
|
+
control_blueprint_debugger: mutates("blueprint", "control_blueprint_debugger", [
|
|
421
|
+
"step",
|
|
422
|
+
"resume",
|
|
423
|
+
"debugger"
|
|
424
|
+
]),
|
|
408
425
|
convert_to_nanite: idempotentMutates("asset", "convert_to_nanite"),
|
|
409
426
|
cook_content: mutates("build", void 0, ["cook", "platform"]),
|
|
410
427
|
create_anim_blueprint: mutates("anim", "create_anim_blueprint"),
|
|
@@ -507,6 +524,11 @@ const TOOL_METADATA = {
|
|
|
507
524
|
"fix"
|
|
508
525
|
]),
|
|
509
526
|
get_blueprint_compile_status: readOnly("blueprint", "get_blueprint_compile_status"),
|
|
527
|
+
get_blueprint_debugger_state: readOnly("blueprint", "get_blueprint_debugger_state", [
|
|
528
|
+
"paused",
|
|
529
|
+
"call stack",
|
|
530
|
+
"watch"
|
|
531
|
+
]),
|
|
510
532
|
get_blueprint_graph: readOnly("blueprint", "get_blueprint_graph"),
|
|
511
533
|
get_blueprint_summary: readOnly("blueprint", "get_blueprint_summary"),
|
|
512
534
|
get_build_job_status: readOnly("level", "get_build_job_status"),
|
|
@@ -533,6 +555,12 @@ const TOOL_METADATA = {
|
|
|
533
555
|
get_current_level: readOnly("core", "get_current_level"),
|
|
534
556
|
get_editor_state: readOnly("core", "get_editor_state"),
|
|
535
557
|
get_import_job_status: readOnly("asset", "get_import_job_status"),
|
|
558
|
+
get_net_stats: readOnly("test", "get_net_stats", [
|
|
559
|
+
"network",
|
|
560
|
+
"multiplayer",
|
|
561
|
+
"replication",
|
|
562
|
+
"ping"
|
|
563
|
+
]),
|
|
536
564
|
get_open_level_status: readOnly("level", "get_open_level_status"),
|
|
537
565
|
get_package_status: readOnly("build"),
|
|
538
566
|
get_pie_status: readOnly("test", "get_pie_status"),
|
|
@@ -554,17 +582,28 @@ const TOOL_METADATA = {
|
|
|
554
582
|
"mesh"
|
|
555
583
|
]),
|
|
556
584
|
import_data_table: reachesOutside("asset", false, "import_data_table", ["csv", "json"]),
|
|
585
|
+
inject_input_action: mutates("input", "inject_input_action", [
|
|
586
|
+
"press",
|
|
587
|
+
"simulate input",
|
|
588
|
+
"enhanced input"
|
|
589
|
+
]),
|
|
557
590
|
launch_on_device: reachesOutside("test", false, "launch_on_device"),
|
|
558
591
|
list_actors: readOnly("core", "list_actors"),
|
|
559
592
|
list_asset_factories: readOnly("asset", "list_asset_factories"),
|
|
560
593
|
list_automation_tests: readOnly("test", "list_automation_tests"),
|
|
561
594
|
list_available_nodes: readOnly("blueprint", "list_available_nodes"),
|
|
595
|
+
list_blueprint_breakpoints: readOnly("blueprint", "list_blueprint_breakpoints", ["breakpoint"]),
|
|
562
596
|
list_config_section: readOnly("core", "list_config_section"),
|
|
563
597
|
list_data_layers: readOnly("level", "list_data_layers"),
|
|
564
598
|
list_gameplay_tags: readOnly("gas", "list_gameplay_tags"),
|
|
565
599
|
list_graph_nodes: readOnly("blueprint", "list_graph_nodes"),
|
|
566
600
|
list_launch_devices: reachesOutside("test", true, "list_launch_devices"),
|
|
567
601
|
list_material_params: readOnly("fx", "list_material_params"),
|
|
602
|
+
list_pie_worlds: readOnly("test", "list_pie_worlds", [
|
|
603
|
+
"client",
|
|
604
|
+
"server",
|
|
605
|
+
"instance"
|
|
606
|
+
]),
|
|
568
607
|
list_registered_projects: readOnly("core", void 0, [
|
|
569
608
|
"registry",
|
|
570
609
|
"editors",
|
|
@@ -625,6 +664,7 @@ const TOOL_METADATA = {
|
|
|
625
664
|
set_asset_property: idempotentMutates("asset", "set_asset_property"),
|
|
626
665
|
set_blackboard_keys: idempotentMutates("ai", "set_blackboard_keys"),
|
|
627
666
|
set_blend_space_samples: idempotentMutates("anim", "set_blend_space_samples"),
|
|
667
|
+
set_blueprint_breakpoint: idempotentMutates("blueprint", "set_blueprint_breakpoint", ["breakpoint", "debug"]),
|
|
628
668
|
set_bp_default: idempotentMutates("blueprint", "set_bp_default"),
|
|
629
669
|
set_config_value: idempotentMutates("core", "set_config_value"),
|
|
630
670
|
set_data_layer_state: idempotentMutates("level", "set_data_layer_state"),
|
|
@@ -671,6 +711,11 @@ const TOOL_METADATA = {
|
|
|
671
711
|
"block",
|
|
672
712
|
"await"
|
|
673
713
|
]),
|
|
714
|
+
watch_blueprint_pin: idempotentMutates("blueprint", "watch_blueprint_pin", [
|
|
715
|
+
"watch",
|
|
716
|
+
"pin",
|
|
717
|
+
"value"
|
|
718
|
+
]),
|
|
674
719
|
write_data_table_row: idempotentMutates("asset", "write_data_table_row")
|
|
675
720
|
};
|
|
676
721
|
function isToolsetName(value) {
|
|
@@ -1711,6 +1756,136 @@ function createBridgeLaunchOnDeviceRequest(deviceId, map, requestId = randomUUID
|
|
|
1711
1756
|
version: 2
|
|
1712
1757
|
});
|
|
1713
1758
|
}
|
|
1759
|
+
const BRIDGE_CALL_ACTOR_FUNCTION_REQUEST_TYPE = "call_actor_function";
|
|
1760
|
+
const BRIDGE_LIST_PIE_WORLDS_REQUEST_TYPE = "list_pie_worlds";
|
|
1761
|
+
const BRIDGE_GET_NET_STATS_REQUEST_TYPE = "get_net_stats";
|
|
1762
|
+
const BRIDGE_WORLD_SELECTORS = ["editor", "pie"];
|
|
1763
|
+
const BRIDGE_NET_ROLES = [
|
|
1764
|
+
"standalone",
|
|
1765
|
+
"server",
|
|
1766
|
+
"client"
|
|
1767
|
+
];
|
|
1768
|
+
const worldSelectorSchema = z.enum(BRIDGE_WORLD_SELECTORS);
|
|
1769
|
+
const pieInstanceIndexSchema = z.number().int().min(0).max(16);
|
|
1770
|
+
const netRoleSchema = z.enum(BRIDGE_NET_ROLES);
|
|
1771
|
+
const bridgeCallActorFunctionArgumentSchema = z.object({
|
|
1772
|
+
name: z.string().trim().min(1).max(512),
|
|
1773
|
+
value: z.string().max(BRIDGE_PROPERTY_VALUE_MAX_CHARS)
|
|
1774
|
+
});
|
|
1775
|
+
const bridgeCallActorFunctionRequestSchema = z.object({
|
|
1776
|
+
actorPath: actorPathSchema,
|
|
1777
|
+
args: z.array(bridgeCallActorFunctionArgumentSchema).max(16).default([]),
|
|
1778
|
+
functionName: z.string().trim().min(1).max(512),
|
|
1779
|
+
pieInstanceIndex: pieInstanceIndexSchema.optional(),
|
|
1780
|
+
requestId: requestIdSchema,
|
|
1781
|
+
type: z.literal(BRIDGE_CALL_ACTOR_FUNCTION_REQUEST_TYPE),
|
|
1782
|
+
version: z.literal(2),
|
|
1783
|
+
world: worldSelectorSchema.optional()
|
|
1784
|
+
});
|
|
1785
|
+
const bridgeCallActorFunctionOutputSchema = z.object({
|
|
1786
|
+
name: z.string(),
|
|
1787
|
+
value: z.string()
|
|
1788
|
+
});
|
|
1789
|
+
const bridgeCallActorFunctionSuccessResponseSchema = z.object({
|
|
1790
|
+
actorPath: z.string(),
|
|
1791
|
+
functionName: z.string(),
|
|
1792
|
+
ok: z.literal(true),
|
|
1793
|
+
outputs: z.array(bridgeCallActorFunctionOutputSchema),
|
|
1794
|
+
requestId: requestIdSchema,
|
|
1795
|
+
returnValue: z.string().optional(),
|
|
1796
|
+
type: z.literal(BRIDGE_CALL_ACTOR_FUNCTION_REQUEST_TYPE),
|
|
1797
|
+
version: z.literal(2),
|
|
1798
|
+
worldName: z.string()
|
|
1799
|
+
});
|
|
1800
|
+
const bridgeListPieWorldsRequestSchema = z.object({
|
|
1801
|
+
requestId: requestIdSchema,
|
|
1802
|
+
type: z.literal(BRIDGE_LIST_PIE_WORLDS_REQUEST_TYPE),
|
|
1803
|
+
version: z.literal(2)
|
|
1804
|
+
});
|
|
1805
|
+
const bridgePieWorldSchema = z.object({
|
|
1806
|
+
actorCount: z.number().int().min(0),
|
|
1807
|
+
index: z.number().int().min(0),
|
|
1808
|
+
isServer: z.boolean(),
|
|
1809
|
+
mapName: z.string(),
|
|
1810
|
+
netMode: pieNetModeSchema,
|
|
1811
|
+
playerCount: z.number().int().min(0),
|
|
1812
|
+
worldName: z.string()
|
|
1813
|
+
});
|
|
1814
|
+
const bridgeListPieWorldsSuccessResponseSchema = z.object({
|
|
1815
|
+
active: z.boolean(),
|
|
1816
|
+
message: z.string().trim().min(1).optional(),
|
|
1817
|
+
ok: z.literal(true),
|
|
1818
|
+
requestId: requestIdSchema,
|
|
1819
|
+
type: z.literal(BRIDGE_LIST_PIE_WORLDS_REQUEST_TYPE),
|
|
1820
|
+
version: z.literal(2),
|
|
1821
|
+
worlds: z.array(bridgePieWorldSchema)
|
|
1822
|
+
});
|
|
1823
|
+
const bridgeGetNetStatsRequestSchema = z.object({
|
|
1824
|
+
pieInstanceIndex: pieInstanceIndexSchema.optional(),
|
|
1825
|
+
requestId: requestIdSchema,
|
|
1826
|
+
type: z.literal(BRIDGE_GET_NET_STATS_REQUEST_TYPE),
|
|
1827
|
+
version: z.literal(2)
|
|
1828
|
+
});
|
|
1829
|
+
const bridgeNetConnectionStatsSchema = z.object({
|
|
1830
|
+
address: z.string(),
|
|
1831
|
+
index: z.number().int().min(0),
|
|
1832
|
+
packetLossIn: z.number().min(0),
|
|
1833
|
+
packetLossOut: z.number().min(0),
|
|
1834
|
+
pingMs: z.number().min(0),
|
|
1835
|
+
playerName: z.string(),
|
|
1836
|
+
state: z.string()
|
|
1837
|
+
});
|
|
1838
|
+
const bridgeNetWorldStatsSchema = z.object({
|
|
1839
|
+
connectionCount: z.number().int().min(0),
|
|
1840
|
+
connections: z.array(bridgeNetConnectionStatsSchema),
|
|
1841
|
+
hasNetDriver: z.boolean(),
|
|
1842
|
+
inBytesPerSecond: z.number().min(0),
|
|
1843
|
+
index: z.number().int().min(0),
|
|
1844
|
+
netMode: pieNetModeSchema,
|
|
1845
|
+
outBytesPerSecond: z.number().min(0),
|
|
1846
|
+
replicatedActorCount: z.number().int().min(0),
|
|
1847
|
+
role: netRoleSchema,
|
|
1848
|
+
worldName: z.string()
|
|
1849
|
+
});
|
|
1850
|
+
const bridgeGetNetStatsSuccessResponseSchema = z.object({
|
|
1851
|
+
active: z.boolean(),
|
|
1852
|
+
message: z.string().trim().min(1).optional(),
|
|
1853
|
+
ok: z.literal(true),
|
|
1854
|
+
requestId: requestIdSchema,
|
|
1855
|
+
type: z.literal(BRIDGE_GET_NET_STATS_REQUEST_TYPE),
|
|
1856
|
+
version: z.literal(2),
|
|
1857
|
+
worlds: z.array(bridgeNetWorldStatsSchema)
|
|
1858
|
+
});
|
|
1859
|
+
const bridgeCallActorFunctionResponseSchema = z.union([bridgeCallActorFunctionSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1860
|
+
const bridgeListPieWorldsResponseSchema = z.union([bridgeListPieWorldsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1861
|
+
const bridgeGetNetStatsResponseSchema = z.union([bridgeGetNetStatsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
1862
|
+
function createBridgeCallActorFunctionRequest(actorPath, functionName, options = {}, requestId = randomUUID()) {
|
|
1863
|
+
return bridgeCallActorFunctionRequestSchema.parse({
|
|
1864
|
+
actorPath,
|
|
1865
|
+
args: options.args,
|
|
1866
|
+
functionName,
|
|
1867
|
+
pieInstanceIndex: options.pieInstanceIndex,
|
|
1868
|
+
requestId,
|
|
1869
|
+
type: BRIDGE_CALL_ACTOR_FUNCTION_REQUEST_TYPE,
|
|
1870
|
+
version: 2,
|
|
1871
|
+
world: options.world
|
|
1872
|
+
});
|
|
1873
|
+
}
|
|
1874
|
+
function createBridgeListPieWorldsRequest(requestId = randomUUID()) {
|
|
1875
|
+
return bridgeListPieWorldsRequestSchema.parse({
|
|
1876
|
+
requestId,
|
|
1877
|
+
type: BRIDGE_LIST_PIE_WORLDS_REQUEST_TYPE,
|
|
1878
|
+
version: 2
|
|
1879
|
+
});
|
|
1880
|
+
}
|
|
1881
|
+
function createBridgeGetNetStatsRequest(options = {}, requestId = randomUUID()) {
|
|
1882
|
+
return bridgeGetNetStatsRequestSchema.parse({
|
|
1883
|
+
pieInstanceIndex: options.pieInstanceIndex,
|
|
1884
|
+
requestId,
|
|
1885
|
+
type: BRIDGE_GET_NET_STATS_REQUEST_TYPE,
|
|
1886
|
+
version: 2
|
|
1887
|
+
});
|
|
1888
|
+
}
|
|
1714
1889
|
//#endregion
|
|
1715
1890
|
//#region src/protocol/compile.ts
|
|
1716
1891
|
const BRIDGE_START_LIVE_COMPILE_REQUEST_TYPE = "start_live_compile";
|
|
@@ -2329,135 +2504,659 @@ function createBridgeGetCdoDefaultsRequest(className, options = {}, requestId =
|
|
|
2329
2504
|
});
|
|
2330
2505
|
}
|
|
2331
2506
|
//#endregion
|
|
2332
|
-
//#region src/protocol/
|
|
2333
|
-
const
|
|
2334
|
-
const
|
|
2335
|
-
const
|
|
2336
|
-
const
|
|
2337
|
-
const
|
|
2338
|
-
const
|
|
2339
|
-
const
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
|
|
2344
|
-
|
|
2345
|
-
|
|
2346
|
-
"
|
|
2347
|
-
"already_tracing",
|
|
2348
|
-
"unsupported"
|
|
2349
|
-
];
|
|
2350
|
-
const BRIDGE_STOP_TRACE_STATES = [
|
|
2351
|
-
"stopped",
|
|
2352
|
-
"not_tracing",
|
|
2353
|
-
"unsupported"
|
|
2507
|
+
//#region src/protocol/graph.ts
|
|
2508
|
+
const BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE = "list_graph_nodes";
|
|
2509
|
+
const BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE = "add_graph_node";
|
|
2510
|
+
const BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE = "remove_graph_node";
|
|
2511
|
+
const BRIDGE_CONNECT_PINS_REQUEST_TYPE = "connect_pins";
|
|
2512
|
+
const BRIDGE_DISCONNECT_PINS_REQUEST_TYPE = "disconnect_pins";
|
|
2513
|
+
const BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE = "set_pin_default";
|
|
2514
|
+
const BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE = "list_available_nodes";
|
|
2515
|
+
const BRIDGE_GRAPH_PIN_VALUE_MAX_CHARS = 4096;
|
|
2516
|
+
const BRIDGE_GRAPH_NODE_POSITION_LIMIT = 1e6;
|
|
2517
|
+
const BRIDGE_GRAPH_NODE_KINDS = [
|
|
2518
|
+
"class",
|
|
2519
|
+
"function",
|
|
2520
|
+
"variable_get",
|
|
2521
|
+
"variable_set"
|
|
2354
2522
|
];
|
|
2355
|
-
const
|
|
2356
|
-
const
|
|
2357
|
-
const
|
|
2358
|
-
const
|
|
2359
|
-
const
|
|
2360
|
-
const
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
const stopTraceStateSchema = z.enum(BRIDGE_STOP_TRACE_STATES);
|
|
2364
|
-
const traceChannelSchema = z.string().trim().min(1).max(64).regex(/^[A-Za-z0-9_]+$/);
|
|
2365
|
-
const traceChannelArraySchema = z.array(traceChannelSchema).max(32);
|
|
2366
|
-
const traceFileNameSchema = z.string().trim().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/);
|
|
2367
|
-
const memoryMegabytesSchema = z.number().min(0);
|
|
2368
|
-
const frameTimingMillisecondsSchema = z.number().min(0);
|
|
2369
|
-
const bridgeGetCrashCallstackRequestSchema = z.object({
|
|
2370
|
-
maxFrames: crashMaxFramesSchema,
|
|
2371
|
-
maxRecords: crashMaxRecordsSchema,
|
|
2372
|
-
requestId: requestIdSchema,
|
|
2373
|
-
type: z.literal(BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE),
|
|
2374
|
-
version: z.literal(2)
|
|
2523
|
+
const graphPinNameSchema = z.string().trim().min(1).max(256);
|
|
2524
|
+
const graphPinValueSchema = z.string().max(BRIDGE_GRAPH_PIN_VALUE_MAX_CHARS);
|
|
2525
|
+
const graphNodeKindSchema = z.enum(BRIDGE_GRAPH_NODE_KINDS);
|
|
2526
|
+
const graphNodeMaxResultsSchema = z.number().int().min(1).max(100);
|
|
2527
|
+
const availableNodeMaxResultsSchema = z.number().int().min(1).max(100);
|
|
2528
|
+
const graphNodePositionSchema = z.object({
|
|
2529
|
+
x: z.number().int().min(-1e6).max(BRIDGE_GRAPH_NODE_POSITION_LIMIT).default(0),
|
|
2530
|
+
y: z.number().int().min(-1e6).max(BRIDGE_GRAPH_NODE_POSITION_LIMIT).default(0)
|
|
2375
2531
|
});
|
|
2376
|
-
const
|
|
2377
|
-
|
|
2532
|
+
const bridgeListGraphNodesRequestSchema = z.object({
|
|
2533
|
+
assetPath: assetPathSchema,
|
|
2534
|
+
cursor: assetCursorSchema.optional(),
|
|
2535
|
+
graphName: graphNameSchema,
|
|
2536
|
+
loadIfNeeded: z.boolean().optional(),
|
|
2537
|
+
maxResults: graphNodeMaxResultsSchema.optional(),
|
|
2378
2538
|
requestId: requestIdSchema,
|
|
2379
|
-
type: z.literal(
|
|
2539
|
+
type: z.literal(BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE),
|
|
2380
2540
|
version: z.literal(2)
|
|
2381
2541
|
});
|
|
2382
|
-
const
|
|
2542
|
+
const bridgeAddGraphNodeRequestFieldsSchema = z.object({
|
|
2543
|
+
assetPath: assetPathSchema,
|
|
2544
|
+
graphName: graphNameSchema,
|
|
2545
|
+
nodeClass: assetPathSchema.optional(),
|
|
2546
|
+
kind: graphNodeKindSchema,
|
|
2547
|
+
memberName: boundedStringSchema.optional(),
|
|
2548
|
+
memberParentClass: assetPathSchema.optional(),
|
|
2549
|
+
pinDefaults: z.record(graphPinNameSchema, graphPinValueSchema).refine((value) => Object.keys(value).length <= 64, { message: `An add_graph_node request carries at most ${String(64)} pin defaults.` }).optional(),
|
|
2550
|
+
position: graphNodePositionSchema.optional(),
|
|
2383
2551
|
requestId: requestIdSchema,
|
|
2384
|
-
type: z.literal(
|
|
2552
|
+
type: z.literal(BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE),
|
|
2385
2553
|
version: z.literal(2)
|
|
2386
2554
|
});
|
|
2387
|
-
const
|
|
2388
|
-
|
|
2389
|
-
|
|
2555
|
+
const bridgeAddGraphNodeRequestSchema = bridgeAddGraphNodeRequestFieldsSchema.refine((value) => value.kind === "class" ? value.nodeClass !== void 0 : value.memberName !== void 0, {
|
|
2556
|
+
message: "kind 'class' requires nodeClass; every other kind requires memberName.",
|
|
2557
|
+
path: ["nodeClass"]
|
|
2558
|
+
});
|
|
2559
|
+
const bridgeRemoveGraphNodeRequestSchema = z.object({
|
|
2560
|
+
assetPath: assetPathSchema,
|
|
2561
|
+
graphName: graphNameSchema,
|
|
2562
|
+
nodeGuid: graphNodeGuidSchema,
|
|
2390
2563
|
requestId: requestIdSchema,
|
|
2391
|
-
type: z.literal(
|
|
2564
|
+
type: z.literal(BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE),
|
|
2392
2565
|
version: z.literal(2)
|
|
2393
2566
|
});
|
|
2394
|
-
const
|
|
2567
|
+
const graphPinPairFields = {
|
|
2568
|
+
assetPath: assetPathSchema,
|
|
2569
|
+
graphName: graphNameSchema,
|
|
2395
2570
|
requestId: requestIdSchema,
|
|
2396
|
-
|
|
2571
|
+
sourceNodeGuid: graphNodeGuidSchema,
|
|
2572
|
+
sourcePinName: graphPinNameSchema,
|
|
2573
|
+
targetNodeGuid: graphNodeGuidSchema,
|
|
2574
|
+
targetPinName: graphPinNameSchema,
|
|
2397
2575
|
version: z.literal(2)
|
|
2576
|
+
};
|
|
2577
|
+
const bridgeConnectPinsRequestSchema = z.object({
|
|
2578
|
+
...graphPinPairFields,
|
|
2579
|
+
type: z.literal(BRIDGE_CONNECT_PINS_REQUEST_TYPE)
|
|
2398
2580
|
});
|
|
2399
|
-
const
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
index: z.number().int().min(0),
|
|
2403
|
-
line: z.number().int().min(1).optional(),
|
|
2404
|
-
module: z.string().trim().min(1).optional(),
|
|
2405
|
-
symbol: z.string().trim().min(1).optional()
|
|
2581
|
+
const bridgeDisconnectPinsRequestSchema = z.object({
|
|
2582
|
+
...graphPinPairFields,
|
|
2583
|
+
type: z.literal(BRIDGE_DISCONNECT_PINS_REQUEST_TYPE)
|
|
2406
2584
|
});
|
|
2407
|
-
const
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2413
|
-
|
|
2414
|
-
|
|
2415
|
-
|
|
2585
|
+
const bridgeSetPinDefaultRequestSchema = z.object({
|
|
2586
|
+
assetPath: assetPathSchema,
|
|
2587
|
+
graphName: graphNameSchema,
|
|
2588
|
+
nodeGuid: graphNodeGuidSchema,
|
|
2589
|
+
pinName: graphPinNameSchema,
|
|
2590
|
+
requestId: requestIdSchema,
|
|
2591
|
+
type: z.literal(BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE),
|
|
2592
|
+
value: graphPinValueSchema,
|
|
2593
|
+
version: z.literal(2)
|
|
2416
2594
|
});
|
|
2417
|
-
const
|
|
2418
|
-
|
|
2419
|
-
|
|
2595
|
+
const bridgeListAvailableNodesRequestSchema = z.object({
|
|
2596
|
+
assetPath: assetPathSchema,
|
|
2597
|
+
cursor: assetCursorSchema.optional(),
|
|
2598
|
+
graphName: graphNameSchema,
|
|
2599
|
+
maxResults: availableNodeMaxResultsSchema.optional(),
|
|
2600
|
+
nameFilter: boundedStringSchema.optional(),
|
|
2420
2601
|
requestId: requestIdSchema,
|
|
2421
|
-
|
|
2422
|
-
truncated: z.boolean(),
|
|
2423
|
-
type: z.literal(BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE),
|
|
2602
|
+
type: z.literal(BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE),
|
|
2424
2603
|
version: z.literal(2)
|
|
2425
2604
|
});
|
|
2426
|
-
const
|
|
2427
|
-
|
|
2605
|
+
const bridgeListGraphNodesSuccessResponseSchema = z.object({
|
|
2606
|
+
assetPath: z.string(),
|
|
2607
|
+
graphName: z.string(),
|
|
2608
|
+
nextCursor: assetCursorSchema.optional(),
|
|
2609
|
+
nodeCount: z.number().int().min(0),
|
|
2610
|
+
nodes: z.array(bridgeBlueprintNodeSchema).max(100),
|
|
2428
2611
|
ok: z.literal(true),
|
|
2429
|
-
output: consoleOutputSchema,
|
|
2430
2612
|
requestId: requestIdSchema,
|
|
2431
|
-
target: execConsoleTargetSchema,
|
|
2432
2613
|
truncated: z.boolean(),
|
|
2433
|
-
type: z.literal(
|
|
2614
|
+
type: z.literal(BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE),
|
|
2434
2615
|
version: z.literal(2)
|
|
2435
2616
|
});
|
|
2436
|
-
const
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
usedVirtualMb: memoryMegabytesSchema
|
|
2442
|
-
});
|
|
2443
|
-
const bridgeStatSnapshotSuccessResponseSchema = z.object({
|
|
2444
|
-
capturedAt: nonEmptyStringSchema,
|
|
2445
|
-
fps: z.number().min(0),
|
|
2446
|
-
frameTimeMs: frameTimingMillisecondsSchema,
|
|
2447
|
-
gameThreadTimeMs: frameTimingMillisecondsSchema.optional(),
|
|
2448
|
-
memory: bridgeMemorySnapshotSchema,
|
|
2617
|
+
const bridgeAddGraphNodeSuccessResponseSchema = z.object({
|
|
2618
|
+
assetPath: z.string(),
|
|
2619
|
+
graphName: z.string(),
|
|
2620
|
+
message: nonEmptyStringSchema.optional(),
|
|
2621
|
+
node: bridgeBlueprintNodeSchema,
|
|
2449
2622
|
ok: z.literal(true),
|
|
2450
|
-
renderThreadTimeMs: frameTimingMillisecondsSchema.optional(),
|
|
2451
2623
|
requestId: requestIdSchema,
|
|
2452
|
-
|
|
2624
|
+
state: creativeEditStateSchema,
|
|
2625
|
+
type: z.literal(BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE),
|
|
2453
2626
|
version: z.literal(2)
|
|
2454
2627
|
});
|
|
2455
|
-
const
|
|
2628
|
+
const bridgeRemoveGraphNodeSuccessResponseSchema = z.object({
|
|
2629
|
+
assetPath: z.string(),
|
|
2630
|
+
graphName: z.string(),
|
|
2456
2631
|
message: nonEmptyStringSchema.optional(),
|
|
2632
|
+
nodeGuid: z.string(),
|
|
2457
2633
|
ok: z.literal(true),
|
|
2634
|
+
removed: z.boolean(),
|
|
2458
2635
|
requestId: requestIdSchema,
|
|
2459
|
-
state:
|
|
2460
|
-
|
|
2636
|
+
state: creativeEditStateSchema,
|
|
2637
|
+
type: z.literal(BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE),
|
|
2638
|
+
version: z.literal(2)
|
|
2639
|
+
});
|
|
2640
|
+
const graphPinPairResponseFields = {
|
|
2641
|
+
assetPath: z.string(),
|
|
2642
|
+
graphName: z.string(),
|
|
2643
|
+
message: nonEmptyStringSchema.optional(),
|
|
2644
|
+
ok: z.literal(true),
|
|
2645
|
+
requestId: requestIdSchema,
|
|
2646
|
+
sourceNodeGuid: z.string(),
|
|
2647
|
+
sourcePinName: z.string(),
|
|
2648
|
+
state: creativeEditStateSchema,
|
|
2649
|
+
targetNodeGuid: z.string(),
|
|
2650
|
+
targetPinName: z.string(),
|
|
2651
|
+
version: z.literal(2)
|
|
2652
|
+
};
|
|
2653
|
+
const bridgeConnectPinsSuccessResponseSchema = z.object({
|
|
2654
|
+
...graphPinPairResponseFields,
|
|
2655
|
+
connected: z.boolean(),
|
|
2656
|
+
type: z.literal(BRIDGE_CONNECT_PINS_REQUEST_TYPE)
|
|
2657
|
+
});
|
|
2658
|
+
const bridgeDisconnectPinsSuccessResponseSchema = z.object({
|
|
2659
|
+
...graphPinPairResponseFields,
|
|
2660
|
+
disconnected: z.boolean(),
|
|
2661
|
+
type: z.literal(BRIDGE_DISCONNECT_PINS_REQUEST_TYPE)
|
|
2662
|
+
});
|
|
2663
|
+
const bridgeSetPinDefaultSuccessResponseSchema = z.object({
|
|
2664
|
+
assetPath: z.string(),
|
|
2665
|
+
graphName: z.string(),
|
|
2666
|
+
message: nonEmptyStringSchema.optional(),
|
|
2667
|
+
nodeGuid: z.string(),
|
|
2668
|
+
ok: z.literal(true),
|
|
2669
|
+
pinName: z.string(),
|
|
2670
|
+
requestId: requestIdSchema,
|
|
2671
|
+
state: creativeEditStateSchema,
|
|
2672
|
+
type: z.literal(BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE),
|
|
2673
|
+
value: z.string(),
|
|
2674
|
+
version: z.literal(2)
|
|
2675
|
+
});
|
|
2676
|
+
const bridgeGraphActionSchema = z.object({
|
|
2677
|
+
category: z.string(),
|
|
2678
|
+
keywords: z.string().optional(),
|
|
2679
|
+
memberName: z.string().optional(),
|
|
2680
|
+
memberParentClass: z.string().optional(),
|
|
2681
|
+
nodeClass: z.string(),
|
|
2682
|
+
nodeKind: graphNodeKindSchema,
|
|
2683
|
+
title: z.string(),
|
|
2684
|
+
tooltip: z.string().optional()
|
|
2685
|
+
});
|
|
2686
|
+
const bridgeListAvailableNodesSuccessResponseSchema = z.object({
|
|
2687
|
+
actions: z.array(bridgeGraphActionSchema).max(100),
|
|
2688
|
+
assetPath: z.string(),
|
|
2689
|
+
graphName: z.string(),
|
|
2690
|
+
nextCursor: assetCursorSchema.optional(),
|
|
2691
|
+
ok: z.literal(true),
|
|
2692
|
+
requestId: requestIdSchema,
|
|
2693
|
+
totalCount: z.number().int().min(0),
|
|
2694
|
+
truncated: z.boolean(),
|
|
2695
|
+
type: z.literal(BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE),
|
|
2696
|
+
version: z.literal(2)
|
|
2697
|
+
});
|
|
2698
|
+
const bridgeListGraphNodesResponseSchema = z.union([bridgeListGraphNodesSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2699
|
+
const bridgeAddGraphNodeResponseSchema = z.union([bridgeAddGraphNodeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2700
|
+
const bridgeRemoveGraphNodeResponseSchema = z.union([bridgeRemoveGraphNodeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2701
|
+
const bridgeConnectPinsResponseSchema = z.union([bridgeConnectPinsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2702
|
+
const bridgeDisconnectPinsResponseSchema = z.union([bridgeDisconnectPinsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2703
|
+
const bridgeSetPinDefaultResponseSchema = z.union([bridgeSetPinDefaultSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2704
|
+
const bridgeListAvailableNodesResponseSchema = z.union([bridgeListAvailableNodesSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2705
|
+
function createBridgeListGraphNodesRequest(assetPath, graphName, options = {}, requestId = randomUUID()) {
|
|
2706
|
+
return bridgeListGraphNodesRequestSchema.parse({
|
|
2707
|
+
assetPath,
|
|
2708
|
+
cursor: options.cursor,
|
|
2709
|
+
graphName,
|
|
2710
|
+
loadIfNeeded: options.loadIfNeeded,
|
|
2711
|
+
maxResults: options.maxResults,
|
|
2712
|
+
requestId,
|
|
2713
|
+
type: BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE,
|
|
2714
|
+
version: 2
|
|
2715
|
+
});
|
|
2716
|
+
}
|
|
2717
|
+
function createBridgeAddGraphNodeRequest(assetPath, graphName, kind, options = {}, requestId = randomUUID()) {
|
|
2718
|
+
return bridgeAddGraphNodeRequestSchema.parse({
|
|
2719
|
+
assetPath,
|
|
2720
|
+
graphName,
|
|
2721
|
+
kind,
|
|
2722
|
+
memberName: options.memberName,
|
|
2723
|
+
memberParentClass: options.memberParentClass,
|
|
2724
|
+
nodeClass: options.nodeClass,
|
|
2725
|
+
pinDefaults: options.pinDefaults,
|
|
2726
|
+
position: options.position,
|
|
2727
|
+
requestId,
|
|
2728
|
+
type: BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE,
|
|
2729
|
+
version: 2
|
|
2730
|
+
});
|
|
2731
|
+
}
|
|
2732
|
+
function createBridgeRemoveGraphNodeRequest(assetPath, graphName, nodeGuid, requestId = randomUUID()) {
|
|
2733
|
+
return bridgeRemoveGraphNodeRequestSchema.parse({
|
|
2734
|
+
assetPath,
|
|
2735
|
+
graphName,
|
|
2736
|
+
nodeGuid,
|
|
2737
|
+
requestId,
|
|
2738
|
+
type: BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE,
|
|
2739
|
+
version: 2
|
|
2740
|
+
});
|
|
2741
|
+
}
|
|
2742
|
+
function createBridgeConnectPinsRequest(assetPath, graphName, source, target, requestId = randomUUID()) {
|
|
2743
|
+
return bridgeConnectPinsRequestSchema.parse({
|
|
2744
|
+
assetPath,
|
|
2745
|
+
graphName,
|
|
2746
|
+
requestId,
|
|
2747
|
+
sourceNodeGuid: source.nodeGuid,
|
|
2748
|
+
sourcePinName: source.pinName,
|
|
2749
|
+
targetNodeGuid: target.nodeGuid,
|
|
2750
|
+
targetPinName: target.pinName,
|
|
2751
|
+
type: BRIDGE_CONNECT_PINS_REQUEST_TYPE,
|
|
2752
|
+
version: 2
|
|
2753
|
+
});
|
|
2754
|
+
}
|
|
2755
|
+
function createBridgeDisconnectPinsRequest(assetPath, graphName, source, target, requestId = randomUUID()) {
|
|
2756
|
+
return bridgeDisconnectPinsRequestSchema.parse({
|
|
2757
|
+
assetPath,
|
|
2758
|
+
graphName,
|
|
2759
|
+
requestId,
|
|
2760
|
+
sourceNodeGuid: source.nodeGuid,
|
|
2761
|
+
sourcePinName: source.pinName,
|
|
2762
|
+
targetNodeGuid: target.nodeGuid,
|
|
2763
|
+
targetPinName: target.pinName,
|
|
2764
|
+
type: BRIDGE_DISCONNECT_PINS_REQUEST_TYPE,
|
|
2765
|
+
version: 2
|
|
2766
|
+
});
|
|
2767
|
+
}
|
|
2768
|
+
function createBridgeSetPinDefaultRequest(assetPath, graphName, nodeGuid, pinName, value, requestId = randomUUID()) {
|
|
2769
|
+
return bridgeSetPinDefaultRequestSchema.parse({
|
|
2770
|
+
assetPath,
|
|
2771
|
+
graphName,
|
|
2772
|
+
nodeGuid,
|
|
2773
|
+
pinName,
|
|
2774
|
+
requestId,
|
|
2775
|
+
type: BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE,
|
|
2776
|
+
value,
|
|
2777
|
+
version: 2
|
|
2778
|
+
});
|
|
2779
|
+
}
|
|
2780
|
+
function createBridgeListAvailableNodesRequest(assetPath, graphName, options = {}, requestId = randomUUID()) {
|
|
2781
|
+
return bridgeListAvailableNodesRequestSchema.parse({
|
|
2782
|
+
assetPath,
|
|
2783
|
+
cursor: options.cursor,
|
|
2784
|
+
graphName,
|
|
2785
|
+
maxResults: options.maxResults,
|
|
2786
|
+
nameFilter: options.nameFilter,
|
|
2787
|
+
requestId,
|
|
2788
|
+
type: BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE,
|
|
2789
|
+
version: 2
|
|
2790
|
+
});
|
|
2791
|
+
}
|
|
2792
|
+
//#endregion
|
|
2793
|
+
//#region src/protocol/debugger.ts
|
|
2794
|
+
const BRIDGE_SET_BLUEPRINT_BREAKPOINT_REQUEST_TYPE = "set_blueprint_breakpoint";
|
|
2795
|
+
const BRIDGE_LIST_BLUEPRINT_BREAKPOINTS_REQUEST_TYPE = "list_blueprint_breakpoints";
|
|
2796
|
+
const BRIDGE_GET_BLUEPRINT_DEBUGGER_STATE_REQUEST_TYPE = "get_blueprint_debugger_state";
|
|
2797
|
+
const BRIDGE_CONTROL_BLUEPRINT_DEBUGGER_REQUEST_TYPE = "control_blueprint_debugger";
|
|
2798
|
+
const BRIDGE_WATCH_BLUEPRINT_PIN_REQUEST_TYPE = "watch_blueprint_pin";
|
|
2799
|
+
const BRIDGE_BREAKPOINT_ACTIONS = [
|
|
2800
|
+
"set",
|
|
2801
|
+
"clear",
|
|
2802
|
+
"enable",
|
|
2803
|
+
"disable"
|
|
2804
|
+
];
|
|
2805
|
+
const BRIDGE_PIN_WATCH_ACTIONS = [
|
|
2806
|
+
"set",
|
|
2807
|
+
"clear",
|
|
2808
|
+
"clear_all"
|
|
2809
|
+
];
|
|
2810
|
+
const BRIDGE_PIN_WATCH_STATES = [
|
|
2811
|
+
"set",
|
|
2812
|
+
"already_set",
|
|
2813
|
+
"cleared",
|
|
2814
|
+
"cleared_all",
|
|
2815
|
+
"not_found",
|
|
2816
|
+
"unsupported"
|
|
2817
|
+
];
|
|
2818
|
+
const BRIDGE_BREAKPOINT_STATES = [
|
|
2819
|
+
"set",
|
|
2820
|
+
"cleared",
|
|
2821
|
+
"enabled",
|
|
2822
|
+
"disabled",
|
|
2823
|
+
"already_set",
|
|
2824
|
+
"not_found",
|
|
2825
|
+
"unsupported"
|
|
2826
|
+
];
|
|
2827
|
+
const BRIDGE_DEBUGGER_ACTIONS = [
|
|
2828
|
+
"resume",
|
|
2829
|
+
"step_over",
|
|
2830
|
+
"step_into",
|
|
2831
|
+
"step_out",
|
|
2832
|
+
"stop"
|
|
2833
|
+
];
|
|
2834
|
+
const BRIDGE_DEBUGGER_CONTROL_STATES = [
|
|
2835
|
+
"resumed",
|
|
2836
|
+
"stepping",
|
|
2837
|
+
"stopped",
|
|
2838
|
+
"not_paused",
|
|
2839
|
+
"unsupported"
|
|
2840
|
+
];
|
|
2841
|
+
const breakpointActionSchema = z.enum(BRIDGE_BREAKPOINT_ACTIONS);
|
|
2842
|
+
const breakpointStateSchema = z.enum(BRIDGE_BREAKPOINT_STATES);
|
|
2843
|
+
const pinWatchActionSchema = z.enum(BRIDGE_PIN_WATCH_ACTIONS);
|
|
2844
|
+
const pinWatchStateSchema = z.enum(BRIDGE_PIN_WATCH_STATES);
|
|
2845
|
+
const debuggerActionSchema = z.enum(BRIDGE_DEBUGGER_ACTIONS);
|
|
2846
|
+
const debuggerControlStateSchema = z.enum(BRIDGE_DEBUGGER_CONTROL_STATES);
|
|
2847
|
+
const nodeGuidSchema = z.string().trim().min(1).max(64);
|
|
2848
|
+
const nodeTitleSchema = z.string().trim().min(1).max(512);
|
|
2849
|
+
const debuggerGraphNameSchema = z.string().trim().min(1).max(512);
|
|
2850
|
+
const pinNameSchema = z.string().trim().min(1).max(256);
|
|
2851
|
+
const bridgeSetBlueprintBreakpointRequestSchema = z.object({
|
|
2852
|
+
action: breakpointActionSchema,
|
|
2853
|
+
blueprintPath: assetPathSchema,
|
|
2854
|
+
graphName: debuggerGraphNameSchema.optional(),
|
|
2855
|
+
nodeGuid: nodeGuidSchema.optional(),
|
|
2856
|
+
nodeTitle: nodeTitleSchema.optional(),
|
|
2857
|
+
requestId: requestIdSchema,
|
|
2858
|
+
type: z.literal(BRIDGE_SET_BLUEPRINT_BREAKPOINT_REQUEST_TYPE),
|
|
2859
|
+
version: z.literal(2)
|
|
2860
|
+
}).refine((value) => value.nodeGuid !== void 0 || value.nodeTitle !== void 0, {
|
|
2861
|
+
message: "A set_blueprint_breakpoint request requires a nodeGuid or a nodeTitle.",
|
|
2862
|
+
path: ["nodeGuid"]
|
|
2863
|
+
});
|
|
2864
|
+
const bridgeSetBlueprintBreakpointSuccessResponseSchema = z.object({
|
|
2865
|
+
blueprintPath: z.string(),
|
|
2866
|
+
breakpointCount: z.number().int().min(0),
|
|
2867
|
+
graphName: z.string(),
|
|
2868
|
+
message: z.string().trim().min(1).optional(),
|
|
2869
|
+
nodeGuid: z.string(),
|
|
2870
|
+
nodeTitle: z.string(),
|
|
2871
|
+
ok: z.literal(true),
|
|
2872
|
+
requestId: requestIdSchema,
|
|
2873
|
+
state: breakpointStateSchema,
|
|
2874
|
+
type: z.literal(BRIDGE_SET_BLUEPRINT_BREAKPOINT_REQUEST_TYPE),
|
|
2875
|
+
version: z.literal(2)
|
|
2876
|
+
});
|
|
2877
|
+
const bridgeListBlueprintBreakpointsRequestSchema = z.object({
|
|
2878
|
+
blueprintPath: assetPathSchema,
|
|
2879
|
+
requestId: requestIdSchema,
|
|
2880
|
+
type: z.literal(BRIDGE_LIST_BLUEPRINT_BREAKPOINTS_REQUEST_TYPE),
|
|
2881
|
+
version: z.literal(2)
|
|
2882
|
+
});
|
|
2883
|
+
const bridgeBlueprintBreakpointSchema = z.object({
|
|
2884
|
+
enabled: z.boolean(),
|
|
2885
|
+
graphName: z.string(),
|
|
2886
|
+
nodeGuid: z.string(),
|
|
2887
|
+
nodeTitle: z.string()
|
|
2888
|
+
});
|
|
2889
|
+
const bridgeListBlueprintBreakpointsSuccessResponseSchema = z.object({
|
|
2890
|
+
blueprintPath: z.string(),
|
|
2891
|
+
breakpoints: z.array(bridgeBlueprintBreakpointSchema),
|
|
2892
|
+
message: z.string().trim().min(1).optional(),
|
|
2893
|
+
ok: z.literal(true),
|
|
2894
|
+
requestId: requestIdSchema,
|
|
2895
|
+
type: z.literal(BRIDGE_LIST_BLUEPRINT_BREAKPOINTS_REQUEST_TYPE),
|
|
2896
|
+
version: z.literal(2)
|
|
2897
|
+
});
|
|
2898
|
+
const bridgeGetBlueprintDebuggerStateRequestSchema = z.object({
|
|
2899
|
+
maxFrames: z.number().int().min(1).max(64).default(32),
|
|
2900
|
+
maxWatches: z.number().int().min(1).max(64).default(32),
|
|
2901
|
+
requestId: requestIdSchema,
|
|
2902
|
+
type: z.literal(BRIDGE_GET_BLUEPRINT_DEBUGGER_STATE_REQUEST_TYPE),
|
|
2903
|
+
version: z.literal(2)
|
|
2904
|
+
});
|
|
2905
|
+
const bridgeDebuggerStackFrameSchema = z.object({
|
|
2906
|
+
blueprintPath: z.string(),
|
|
2907
|
+
functionName: z.string(),
|
|
2908
|
+
graphName: z.string(),
|
|
2909
|
+
index: z.number().int().min(0),
|
|
2910
|
+
nodeTitle: z.string()
|
|
2911
|
+
});
|
|
2912
|
+
const bridgeDebuggerWatchSchema = z.object({
|
|
2913
|
+
nodeTitle: z.string(),
|
|
2914
|
+
pinName: z.string(),
|
|
2915
|
+
status: z.string(),
|
|
2916
|
+
value: z.string()
|
|
2917
|
+
});
|
|
2918
|
+
const bridgeGetBlueprintDebuggerStateSuccessResponseSchema = z.object({
|
|
2919
|
+
blueprintPath: z.string(),
|
|
2920
|
+
callStack: z.array(bridgeDebuggerStackFrameSchema),
|
|
2921
|
+
graphName: z.string(),
|
|
2922
|
+
message: z.string().trim().min(1).optional(),
|
|
2923
|
+
nodeGuid: z.string(),
|
|
2924
|
+
nodeTitle: z.string(),
|
|
2925
|
+
ok: z.literal(true),
|
|
2926
|
+
paused: z.boolean(),
|
|
2927
|
+
requestId: requestIdSchema,
|
|
2928
|
+
type: z.literal(BRIDGE_GET_BLUEPRINT_DEBUGGER_STATE_REQUEST_TYPE),
|
|
2929
|
+
version: z.literal(2),
|
|
2930
|
+
watches: z.array(bridgeDebuggerWatchSchema)
|
|
2931
|
+
});
|
|
2932
|
+
const bridgeWatchBlueprintPinRequestSchema = z.object({
|
|
2933
|
+
action: pinWatchActionSchema,
|
|
2934
|
+
blueprintPath: assetPathSchema,
|
|
2935
|
+
graphName: debuggerGraphNameSchema.optional(),
|
|
2936
|
+
nodeGuid: nodeGuidSchema.optional(),
|
|
2937
|
+
nodeTitle: nodeTitleSchema.optional(),
|
|
2938
|
+
pinName: pinNameSchema.optional(),
|
|
2939
|
+
requestId: requestIdSchema,
|
|
2940
|
+
type: z.literal(BRIDGE_WATCH_BLUEPRINT_PIN_REQUEST_TYPE),
|
|
2941
|
+
version: z.literal(2)
|
|
2942
|
+
}).refine((value) => value.action === "clear_all" || (value.nodeGuid !== void 0 || value.nodeTitle !== void 0) && value.pinName !== void 0, {
|
|
2943
|
+
message: "A watch_blueprint_pin request other than 'clear_all' requires a pinName and a nodeGuid or nodeTitle.",
|
|
2944
|
+
path: ["pinName"]
|
|
2945
|
+
});
|
|
2946
|
+
const bridgeWatchBlueprintPinSuccessResponseSchema = z.object({
|
|
2947
|
+
blueprintPath: z.string(),
|
|
2948
|
+
graphName: z.string(),
|
|
2949
|
+
message: z.string().trim().min(1).optional(),
|
|
2950
|
+
nodeGuid: z.string(),
|
|
2951
|
+
nodeTitle: z.string(),
|
|
2952
|
+
ok: z.literal(true),
|
|
2953
|
+
pinName: z.string(),
|
|
2954
|
+
requestId: requestIdSchema,
|
|
2955
|
+
state: pinWatchStateSchema,
|
|
2956
|
+
type: z.literal(BRIDGE_WATCH_BLUEPRINT_PIN_REQUEST_TYPE),
|
|
2957
|
+
version: z.literal(2),
|
|
2958
|
+
watchCount: z.number().int().min(0)
|
|
2959
|
+
});
|
|
2960
|
+
const bridgeControlBlueprintDebuggerRequestSchema = z.object({
|
|
2961
|
+
action: debuggerActionSchema,
|
|
2962
|
+
requestId: requestIdSchema,
|
|
2963
|
+
type: z.literal(BRIDGE_CONTROL_BLUEPRINT_DEBUGGER_REQUEST_TYPE),
|
|
2964
|
+
version: z.literal(2)
|
|
2965
|
+
});
|
|
2966
|
+
const bridgeControlBlueprintDebuggerSuccessResponseSchema = z.object({
|
|
2967
|
+
action: debuggerActionSchema,
|
|
2968
|
+
message: z.string().trim().min(1).optional(),
|
|
2969
|
+
ok: z.literal(true),
|
|
2970
|
+
requestId: requestIdSchema,
|
|
2971
|
+
state: debuggerControlStateSchema,
|
|
2972
|
+
type: z.literal(BRIDGE_CONTROL_BLUEPRINT_DEBUGGER_REQUEST_TYPE),
|
|
2973
|
+
version: z.literal(2)
|
|
2974
|
+
});
|
|
2975
|
+
const bridgeSetBlueprintBreakpointResponseSchema = z.union([bridgeSetBlueprintBreakpointSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2976
|
+
const bridgeListBlueprintBreakpointsResponseSchema = z.union([bridgeListBlueprintBreakpointsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2977
|
+
const bridgeGetBlueprintDebuggerStateResponseSchema = z.union([bridgeGetBlueprintDebuggerStateSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2978
|
+
const bridgeWatchBlueprintPinResponseSchema = z.union([bridgeWatchBlueprintPinSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2979
|
+
const bridgeControlBlueprintDebuggerResponseSchema = z.union([bridgeControlBlueprintDebuggerSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
2980
|
+
function createBridgeSetBlueprintBreakpointRequest(blueprintPath, action, options = {}, requestId = randomUUID()) {
|
|
2981
|
+
return bridgeSetBlueprintBreakpointRequestSchema.parse({
|
|
2982
|
+
action,
|
|
2983
|
+
blueprintPath,
|
|
2984
|
+
graphName: options.graphName,
|
|
2985
|
+
nodeGuid: options.nodeGuid,
|
|
2986
|
+
nodeTitle: options.nodeTitle,
|
|
2987
|
+
requestId,
|
|
2988
|
+
type: BRIDGE_SET_BLUEPRINT_BREAKPOINT_REQUEST_TYPE,
|
|
2989
|
+
version: 2
|
|
2990
|
+
});
|
|
2991
|
+
}
|
|
2992
|
+
function createBridgeListBlueprintBreakpointsRequest(blueprintPath, requestId = randomUUID()) {
|
|
2993
|
+
return bridgeListBlueprintBreakpointsRequestSchema.parse({
|
|
2994
|
+
blueprintPath,
|
|
2995
|
+
requestId,
|
|
2996
|
+
type: BRIDGE_LIST_BLUEPRINT_BREAKPOINTS_REQUEST_TYPE,
|
|
2997
|
+
version: 2
|
|
2998
|
+
});
|
|
2999
|
+
}
|
|
3000
|
+
function createBridgeGetBlueprintDebuggerStateRequest(options = {}, requestId = randomUUID()) {
|
|
3001
|
+
return bridgeGetBlueprintDebuggerStateRequestSchema.parse({
|
|
3002
|
+
maxFrames: options.maxFrames ?? 32,
|
|
3003
|
+
maxWatches: options.maxWatches ?? 32,
|
|
3004
|
+
requestId,
|
|
3005
|
+
type: BRIDGE_GET_BLUEPRINT_DEBUGGER_STATE_REQUEST_TYPE,
|
|
3006
|
+
version: 2
|
|
3007
|
+
});
|
|
3008
|
+
}
|
|
3009
|
+
function createBridgeControlBlueprintDebuggerRequest(action, requestId = randomUUID()) {
|
|
3010
|
+
return bridgeControlBlueprintDebuggerRequestSchema.parse({
|
|
3011
|
+
action,
|
|
3012
|
+
requestId,
|
|
3013
|
+
type: BRIDGE_CONTROL_BLUEPRINT_DEBUGGER_REQUEST_TYPE,
|
|
3014
|
+
version: 2
|
|
3015
|
+
});
|
|
3016
|
+
}
|
|
3017
|
+
function createBridgeWatchBlueprintPinRequest(blueprintPath, action, options = {}, requestId = randomUUID()) {
|
|
3018
|
+
return bridgeWatchBlueprintPinRequestSchema.parse({
|
|
3019
|
+
action,
|
|
3020
|
+
blueprintPath,
|
|
3021
|
+
graphName: options.graphName,
|
|
3022
|
+
nodeGuid: options.nodeGuid,
|
|
3023
|
+
nodeTitle: options.nodeTitle,
|
|
3024
|
+
pinName: options.pinName,
|
|
3025
|
+
requestId,
|
|
3026
|
+
type: BRIDGE_WATCH_BLUEPRINT_PIN_REQUEST_TYPE,
|
|
3027
|
+
version: 2
|
|
3028
|
+
});
|
|
3029
|
+
}
|
|
3030
|
+
//#endregion
|
|
3031
|
+
//#region src/protocol/diagnostics.ts
|
|
3032
|
+
const BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE = "get_crash_callstack";
|
|
3033
|
+
const BRIDGE_CRASH_RECORD_KINDS = ["ensure", "fatal"];
|
|
3034
|
+
const BRIDGE_EXEC_CONSOLE_COMMAND_REQUEST_TYPE = "exec_console_command";
|
|
3035
|
+
const BRIDGE_STAT_SNAPSHOT_REQUEST_TYPE = "stat_snapshot";
|
|
3036
|
+
const BRIDGE_START_TRACE_REQUEST_TYPE = "start_trace";
|
|
3037
|
+
const BRIDGE_STOP_TRACE_REQUEST_TYPE = "stop_trace";
|
|
3038
|
+
const BRIDGE_EXEC_CONSOLE_TARGETS = [
|
|
3039
|
+
"editor",
|
|
3040
|
+
"pie",
|
|
3041
|
+
"none"
|
|
3042
|
+
];
|
|
3043
|
+
const BRIDGE_EXEC_CONSOLE_MAX_COMMAND_CHARS = 2048;
|
|
3044
|
+
const BRIDGE_START_TRACE_STATES = [
|
|
3045
|
+
"started",
|
|
3046
|
+
"already_tracing",
|
|
3047
|
+
"unsupported"
|
|
3048
|
+
];
|
|
3049
|
+
const BRIDGE_STOP_TRACE_STATES = [
|
|
3050
|
+
"stopped",
|
|
3051
|
+
"not_tracing",
|
|
3052
|
+
"unsupported"
|
|
3053
|
+
];
|
|
3054
|
+
const crashRecordKindSchema = z.enum(BRIDGE_CRASH_RECORD_KINDS);
|
|
3055
|
+
const crashMaxRecordsSchema = z.number().int().min(1).max(5);
|
|
3056
|
+
const crashMaxFramesSchema = z.number().int().min(1).max(64);
|
|
3057
|
+
const execConsoleTargetSchema = z.enum(BRIDGE_EXEC_CONSOLE_TARGETS);
|
|
3058
|
+
const consoleCommandSchema = z.string().trim().min(1).max(BRIDGE_EXEC_CONSOLE_MAX_COMMAND_CHARS);
|
|
3059
|
+
const consoleOutputLineSchema = z.string().max(512);
|
|
3060
|
+
const consoleOutputSchema = z.array(consoleOutputLineSchema).max(100);
|
|
3061
|
+
const startTraceStateSchema = z.enum(BRIDGE_START_TRACE_STATES);
|
|
3062
|
+
const stopTraceStateSchema = z.enum(BRIDGE_STOP_TRACE_STATES);
|
|
3063
|
+
const traceChannelSchema = z.string().trim().min(1).max(64).regex(/^[A-Za-z0-9_]+$/);
|
|
3064
|
+
const traceChannelArraySchema = z.array(traceChannelSchema).max(32);
|
|
3065
|
+
const traceFileNameSchema = z.string().trim().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/);
|
|
3066
|
+
const memoryMegabytesSchema = z.number().min(0);
|
|
3067
|
+
const frameTimingMillisecondsSchema = z.number().min(0);
|
|
3068
|
+
const bridgeGetCrashCallstackRequestSchema = z.object({
|
|
3069
|
+
maxFrames: crashMaxFramesSchema,
|
|
3070
|
+
maxRecords: crashMaxRecordsSchema,
|
|
3071
|
+
requestId: requestIdSchema,
|
|
3072
|
+
type: z.literal(BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE),
|
|
3073
|
+
version: z.literal(2)
|
|
3074
|
+
});
|
|
3075
|
+
const bridgeExecConsoleCommandRequestSchema = z.object({
|
|
3076
|
+
command: consoleCommandSchema,
|
|
3077
|
+
requestId: requestIdSchema,
|
|
3078
|
+
type: z.literal(BRIDGE_EXEC_CONSOLE_COMMAND_REQUEST_TYPE),
|
|
3079
|
+
version: z.literal(2)
|
|
3080
|
+
});
|
|
3081
|
+
const bridgeStatSnapshotRequestSchema = z.object({
|
|
3082
|
+
requestId: requestIdSchema,
|
|
3083
|
+
type: z.literal(BRIDGE_STAT_SNAPSHOT_REQUEST_TYPE),
|
|
3084
|
+
version: z.literal(2)
|
|
3085
|
+
});
|
|
3086
|
+
const bridgeStartTraceRequestSchema = z.object({
|
|
3087
|
+
channels: traceChannelArraySchema.default([]),
|
|
3088
|
+
fileName: traceFileNameSchema.optional(),
|
|
3089
|
+
requestId: requestIdSchema,
|
|
3090
|
+
type: z.literal(BRIDGE_START_TRACE_REQUEST_TYPE),
|
|
3091
|
+
version: z.literal(2)
|
|
3092
|
+
});
|
|
3093
|
+
const bridgeStopTraceRequestSchema = z.object({
|
|
3094
|
+
requestId: requestIdSchema,
|
|
3095
|
+
type: z.literal(BRIDGE_STOP_TRACE_REQUEST_TYPE),
|
|
3096
|
+
version: z.literal(2)
|
|
3097
|
+
});
|
|
3098
|
+
const bridgeCrashFrameSchema = z.object({
|
|
3099
|
+
address: nonEmptyStringSchema,
|
|
3100
|
+
file: z.string().trim().min(1).optional(),
|
|
3101
|
+
index: z.number().int().min(0),
|
|
3102
|
+
line: z.number().int().min(1).optional(),
|
|
3103
|
+
module: z.string().trim().min(1).optional(),
|
|
3104
|
+
symbol: z.string().trim().min(1).optional()
|
|
3105
|
+
});
|
|
3106
|
+
const bridgeCrashRecordSchema = z.object({
|
|
3107
|
+
frames: z.array(bridgeCrashFrameSchema),
|
|
3108
|
+
framesTruncated: z.boolean(),
|
|
3109
|
+
kind: crashRecordKindSchema,
|
|
3110
|
+
message: z.string(),
|
|
3111
|
+
occurredAt: nonEmptyStringSchema,
|
|
3112
|
+
recordId: nonEmptyStringSchema,
|
|
3113
|
+
threadId: z.number().int().min(0),
|
|
3114
|
+
totalFrameCount: z.number().int().min(0)
|
|
3115
|
+
});
|
|
3116
|
+
const bridgeGetCrashCallstackSuccessResponseSchema = z.object({
|
|
3117
|
+
ok: z.literal(true),
|
|
3118
|
+
records: z.array(bridgeCrashRecordSchema),
|
|
3119
|
+
requestId: requestIdSchema,
|
|
3120
|
+
totalCount: z.number().int().min(0),
|
|
3121
|
+
truncated: z.boolean(),
|
|
3122
|
+
type: z.literal(BRIDGE_GET_CRASH_CALLSTACK_REQUEST_TYPE),
|
|
3123
|
+
version: z.literal(2)
|
|
3124
|
+
});
|
|
3125
|
+
const bridgeExecConsoleCommandSuccessResponseSchema = z.object({
|
|
3126
|
+
handled: z.boolean(),
|
|
3127
|
+
ok: z.literal(true),
|
|
3128
|
+
output: consoleOutputSchema,
|
|
3129
|
+
requestId: requestIdSchema,
|
|
3130
|
+
target: execConsoleTargetSchema,
|
|
3131
|
+
truncated: z.boolean(),
|
|
3132
|
+
type: z.literal(BRIDGE_EXEC_CONSOLE_COMMAND_REQUEST_TYPE),
|
|
3133
|
+
version: z.literal(2)
|
|
3134
|
+
});
|
|
3135
|
+
const bridgeMemorySnapshotSchema = z.object({
|
|
3136
|
+
availablePhysicalMb: memoryMegabytesSchema,
|
|
3137
|
+
peakUsedPhysicalMb: memoryMegabytesSchema,
|
|
3138
|
+
peakUsedVirtualMb: memoryMegabytesSchema,
|
|
3139
|
+
usedPhysicalMb: memoryMegabytesSchema,
|
|
3140
|
+
usedVirtualMb: memoryMegabytesSchema
|
|
3141
|
+
});
|
|
3142
|
+
const bridgeStatSnapshotSuccessResponseSchema = z.object({
|
|
3143
|
+
capturedAt: nonEmptyStringSchema,
|
|
3144
|
+
fps: z.number().min(0),
|
|
3145
|
+
frameTimeMs: frameTimingMillisecondsSchema,
|
|
3146
|
+
gameThreadTimeMs: frameTimingMillisecondsSchema.optional(),
|
|
3147
|
+
memory: bridgeMemorySnapshotSchema,
|
|
3148
|
+
ok: z.literal(true),
|
|
3149
|
+
renderThreadTimeMs: frameTimingMillisecondsSchema.optional(),
|
|
3150
|
+
requestId: requestIdSchema,
|
|
3151
|
+
type: z.literal(BRIDGE_STAT_SNAPSHOT_REQUEST_TYPE),
|
|
3152
|
+
version: z.literal(2)
|
|
3153
|
+
});
|
|
3154
|
+
const bridgeStartTraceSuccessResponseSchema = z.object({
|
|
3155
|
+
message: nonEmptyStringSchema.optional(),
|
|
3156
|
+
ok: z.literal(true),
|
|
3157
|
+
requestId: requestIdSchema,
|
|
3158
|
+
state: startTraceStateSchema,
|
|
3159
|
+
tracePath: nonEmptyStringSchema.optional(),
|
|
2461
3160
|
type: z.literal(BRIDGE_START_TRACE_REQUEST_TYPE),
|
|
2462
3161
|
version: z.literal(2)
|
|
2463
3162
|
}).refine((value) => value.state !== "unsupported" || value.tracePath === void 0, {
|
|
@@ -3912,10 +4611,12 @@ const bridgeListActorsRequestSchema = z.object({
|
|
|
3912
4611
|
levelName: boundedStringSchema.optional(),
|
|
3913
4612
|
maxResults: levelMaxResultsSchema,
|
|
3914
4613
|
nameFilter: boundedStringSchema.optional(),
|
|
4614
|
+
pieInstanceIndex: pieInstanceIndexSchema.optional(),
|
|
3915
4615
|
requestId: requestIdSchema,
|
|
3916
4616
|
tag: boundedStringSchema.optional(),
|
|
3917
4617
|
type: z.literal(BRIDGE_LIST_ACTORS_REQUEST_TYPE),
|
|
3918
|
-
version: z.literal(2)
|
|
4618
|
+
version: z.literal(2),
|
|
4619
|
+
world: worldSelectorSchema.optional()
|
|
3919
4620
|
});
|
|
3920
4621
|
const bridgeGetActorDetailsRequestSchema = z.object({
|
|
3921
4622
|
actorPath: actorPathSchema,
|
|
@@ -3923,9 +4624,11 @@ const bridgeGetActorDetailsRequestSchema = z.object({
|
|
|
3923
4624
|
includeInherited: z.boolean().default(false),
|
|
3924
4625
|
maxResults: actorDetailMemberLimitSchema,
|
|
3925
4626
|
propertyCursor: levelCursorSchema.default(0),
|
|
4627
|
+
pieInstanceIndex: pieInstanceIndexSchema.optional(),
|
|
3926
4628
|
requestId: requestIdSchema,
|
|
3927
4629
|
type: z.literal(BRIDGE_GET_ACTOR_DETAILS_REQUEST_TYPE),
|
|
3928
|
-
version: z.literal(2)
|
|
4630
|
+
version: z.literal(2),
|
|
4631
|
+
world: worldSelectorSchema.optional()
|
|
3929
4632
|
});
|
|
3930
4633
|
const bridgeGetCurrentLevelRequestSchema = z.object({
|
|
3931
4634
|
requestId: requestIdSchema,
|
|
@@ -3993,9 +4696,11 @@ const bridgeSetActorPropertyEntrySchema = z.object({
|
|
|
3993
4696
|
const bridgeSetActorPropertyRequestSchema = z.object({
|
|
3994
4697
|
dryRun: z.boolean().default(false),
|
|
3995
4698
|
properties: z.array(bridgeSetActorPropertyEntrySchema).min(1).max(64),
|
|
4699
|
+
pieInstanceIndex: pieInstanceIndexSchema.optional(),
|
|
3996
4700
|
requestId: requestIdSchema,
|
|
3997
4701
|
type: z.literal(BRIDGE_SET_ACTOR_PROPERTY_REQUEST_TYPE),
|
|
3998
|
-
version: z.literal(2)
|
|
4702
|
+
version: z.literal(2),
|
|
4703
|
+
world: worldSelectorSchema.optional()
|
|
3999
4704
|
});
|
|
4000
4705
|
const bridgeSelectActorsRequestSchema = z.object({
|
|
4001
4706
|
actorPaths: z.array(actorPathSchema).max(64).default([]),
|
|
@@ -4216,10 +4921,12 @@ function createBridgeListActorsRequest(options = {}, requestId = randomUUID()) {
|
|
|
4216
4921
|
levelName: options.levelName,
|
|
4217
4922
|
maxResults: options.maxResults ?? 50,
|
|
4218
4923
|
nameFilter: options.nameFilter,
|
|
4924
|
+
pieInstanceIndex: options.pieInstanceIndex,
|
|
4219
4925
|
requestId,
|
|
4220
4926
|
tag: options.tag,
|
|
4221
4927
|
type: BRIDGE_LIST_ACTORS_REQUEST_TYPE,
|
|
4222
|
-
version: 2
|
|
4928
|
+
version: 2,
|
|
4929
|
+
world: options.world
|
|
4223
4930
|
});
|
|
4224
4931
|
}
|
|
4225
4932
|
function createBridgeGetActorDetailsRequest(actorPath, options = {}, requestId = randomUUID()) {
|
|
@@ -4228,10 +4935,12 @@ function createBridgeGetActorDetailsRequest(actorPath, options = {}, requestId =
|
|
|
4228
4935
|
componentCursor: options.componentCursor,
|
|
4229
4936
|
includeInherited: options.includeInherited,
|
|
4230
4937
|
maxResults: options.maxResults ?? 25,
|
|
4938
|
+
pieInstanceIndex: options.pieInstanceIndex,
|
|
4231
4939
|
propertyCursor: options.propertyCursor,
|
|
4232
4940
|
requestId,
|
|
4233
4941
|
type: BRIDGE_GET_ACTOR_DETAILS_REQUEST_TYPE,
|
|
4234
|
-
version: 2
|
|
4942
|
+
version: 2,
|
|
4943
|
+
world: options.world
|
|
4235
4944
|
});
|
|
4236
4945
|
}
|
|
4237
4946
|
function createBridgeGetCurrentLevelRequest(requestId = randomUUID()) {
|
|
@@ -4271,10 +4980,12 @@ function createBridgeSetActorTransformRequest(transforms, options = {}, requestI
|
|
|
4271
4980
|
function createBridgeSetActorPropertyRequest(properties, options = {}, requestId = randomUUID()) {
|
|
4272
4981
|
return bridgeSetActorPropertyRequestSchema.parse({
|
|
4273
4982
|
dryRun: options.dryRun,
|
|
4983
|
+
pieInstanceIndex: options.pieInstanceIndex,
|
|
4274
4984
|
properties,
|
|
4275
4985
|
requestId,
|
|
4276
4986
|
type: BRIDGE_SET_ACTOR_PROPERTY_REQUEST_TYPE,
|
|
4277
|
-
version: 2
|
|
4987
|
+
version: 2,
|
|
4988
|
+
world: options.world
|
|
4278
4989
|
});
|
|
4279
4990
|
}
|
|
4280
4991
|
function createBridgeSelectActorsRequest(actorPaths, options = {}, requestId = randomUUID()) {
|
|
@@ -5123,339 +5834,53 @@ const bridgeAddPostProcessMaterialSuccessResponseSchema = z.object({
|
|
|
5123
5834
|
materialPath: z.string(),
|
|
5124
5835
|
message: nonEmptyStringSchema.optional(),
|
|
5125
5836
|
ok: z.literal(true),
|
|
5126
|
-
packageDirty: z.boolean(),
|
|
5127
|
-
requestId: requestIdSchema,
|
|
5128
|
-
state: creativeEditStateSchema,
|
|
5129
|
-
type: z.literal(BRIDGE_ADD_POST_PROCESS_MATERIAL_REQUEST_TYPE),
|
|
5130
|
-
version: z.literal(2)
|
|
5131
|
-
});
|
|
5132
|
-
const bridgeCreatePostProcessVolumeResponseSchema = z.union([bridgeCreatePostProcessVolumeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
5133
|
-
const bridgeSetPostProcessSettingsResponseSchema = z.union([bridgeSetPostProcessSettingsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
5134
|
-
const bridgeAddPostProcessMaterialResponseSchema = z.union([bridgeAddPostProcessMaterialSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
5135
|
-
function createBridgeCreatePostProcessVolumeRequest(options = {}, requestId = randomUUID()) {
|
|
5136
|
-
return bridgeCreatePostProcessVolumeRequestSchema.parse({
|
|
5137
|
-
actorLabel: options.actorLabel,
|
|
5138
|
-
blendRadius: options.blendRadius,
|
|
5139
|
-
blendWeight: options.blendWeight,
|
|
5140
|
-
extent: options.extent,
|
|
5141
|
-
folderPath: options.folderPath,
|
|
5142
|
-
location: options.location,
|
|
5143
|
-
priority: options.priority,
|
|
5144
|
-
requestId,
|
|
5145
|
-
settings: options.settings,
|
|
5146
|
-
type: BRIDGE_CREATE_POST_PROCESS_VOLUME_REQUEST_TYPE,
|
|
5147
|
-
unbound: options.unbound,
|
|
5148
|
-
version: 2
|
|
5149
|
-
});
|
|
5150
|
-
}
|
|
5151
|
-
function createBridgeSetPostProcessSettingsRequest(actorPath, targetKind, settings, options = {}, requestId = randomUUID()) {
|
|
5152
|
-
return bridgeSetPostProcessSettingsRequestSchema.parse({
|
|
5153
|
-
actorPath,
|
|
5154
|
-
componentName: options.componentName,
|
|
5155
|
-
requestId,
|
|
5156
|
-
settings,
|
|
5157
|
-
targetKind,
|
|
5158
|
-
type: BRIDGE_SET_POST_PROCESS_SETTINGS_REQUEST_TYPE,
|
|
5159
|
-
version: 2
|
|
5160
|
-
});
|
|
5161
|
-
}
|
|
5162
|
-
function createBridgeAddPostProcessMaterialRequest(actorPath, materialPath, options = {}, requestId = randomUUID()) {
|
|
5163
|
-
return bridgeAddPostProcessMaterialRequestSchema.parse({
|
|
5164
|
-
actorPath,
|
|
5165
|
-
blendableLocation: options.blendableLocation,
|
|
5166
|
-
componentName: options.componentName,
|
|
5167
|
-
materialPath,
|
|
5168
|
-
requestId,
|
|
5169
|
-
targetKind: options.targetKind,
|
|
5170
|
-
type: BRIDGE_ADD_POST_PROCESS_MATERIAL_REQUEST_TYPE,
|
|
5171
|
-
version: 2,
|
|
5172
|
-
weight: options.weight
|
|
5173
|
-
});
|
|
5174
|
-
}
|
|
5175
|
-
//#endregion
|
|
5176
|
-
//#region src/protocol/graph.ts
|
|
5177
|
-
const BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE = "list_graph_nodes";
|
|
5178
|
-
const BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE = "add_graph_node";
|
|
5179
|
-
const BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE = "remove_graph_node";
|
|
5180
|
-
const BRIDGE_CONNECT_PINS_REQUEST_TYPE = "connect_pins";
|
|
5181
|
-
const BRIDGE_DISCONNECT_PINS_REQUEST_TYPE = "disconnect_pins";
|
|
5182
|
-
const BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE = "set_pin_default";
|
|
5183
|
-
const BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE = "list_available_nodes";
|
|
5184
|
-
const BRIDGE_GRAPH_PIN_VALUE_MAX_CHARS = 4096;
|
|
5185
|
-
const BRIDGE_GRAPH_NODE_POSITION_LIMIT = 1e6;
|
|
5186
|
-
const BRIDGE_GRAPH_NODE_KINDS = [
|
|
5187
|
-
"class",
|
|
5188
|
-
"function",
|
|
5189
|
-
"variable_get",
|
|
5190
|
-
"variable_set"
|
|
5191
|
-
];
|
|
5192
|
-
const graphPinNameSchema = z.string().trim().min(1).max(256);
|
|
5193
|
-
const graphPinValueSchema = z.string().max(BRIDGE_GRAPH_PIN_VALUE_MAX_CHARS);
|
|
5194
|
-
const graphNodeKindSchema = z.enum(BRIDGE_GRAPH_NODE_KINDS);
|
|
5195
|
-
const graphNodeMaxResultsSchema = z.number().int().min(1).max(100);
|
|
5196
|
-
const availableNodeMaxResultsSchema = z.number().int().min(1).max(100);
|
|
5197
|
-
const graphNodePositionSchema = z.object({
|
|
5198
|
-
x: z.number().int().min(-1e6).max(BRIDGE_GRAPH_NODE_POSITION_LIMIT).default(0),
|
|
5199
|
-
y: z.number().int().min(-1e6).max(BRIDGE_GRAPH_NODE_POSITION_LIMIT).default(0)
|
|
5200
|
-
});
|
|
5201
|
-
const bridgeListGraphNodesRequestSchema = z.object({
|
|
5202
|
-
assetPath: assetPathSchema,
|
|
5203
|
-
cursor: assetCursorSchema.optional(),
|
|
5204
|
-
graphName: graphNameSchema,
|
|
5205
|
-
loadIfNeeded: z.boolean().optional(),
|
|
5206
|
-
maxResults: graphNodeMaxResultsSchema.optional(),
|
|
5207
|
-
requestId: requestIdSchema,
|
|
5208
|
-
type: z.literal(BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE),
|
|
5209
|
-
version: z.literal(2)
|
|
5210
|
-
});
|
|
5211
|
-
const bridgeAddGraphNodeRequestFieldsSchema = z.object({
|
|
5212
|
-
assetPath: assetPathSchema,
|
|
5213
|
-
graphName: graphNameSchema,
|
|
5214
|
-
nodeClass: assetPathSchema.optional(),
|
|
5215
|
-
kind: graphNodeKindSchema,
|
|
5216
|
-
memberName: boundedStringSchema.optional(),
|
|
5217
|
-
memberParentClass: assetPathSchema.optional(),
|
|
5218
|
-
pinDefaults: z.record(graphPinNameSchema, graphPinValueSchema).refine((value) => Object.keys(value).length <= 64, { message: `An add_graph_node request carries at most ${String(64)} pin defaults.` }).optional(),
|
|
5219
|
-
position: graphNodePositionSchema.optional(),
|
|
5220
|
-
requestId: requestIdSchema,
|
|
5221
|
-
type: z.literal(BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE),
|
|
5222
|
-
version: z.literal(2)
|
|
5223
|
-
});
|
|
5224
|
-
const bridgeAddGraphNodeRequestSchema = bridgeAddGraphNodeRequestFieldsSchema.refine((value) => value.kind === "class" ? value.nodeClass !== void 0 : value.memberName !== void 0, {
|
|
5225
|
-
message: "kind 'class' requires nodeClass; every other kind requires memberName.",
|
|
5226
|
-
path: ["nodeClass"]
|
|
5227
|
-
});
|
|
5228
|
-
const bridgeRemoveGraphNodeRequestSchema = z.object({
|
|
5229
|
-
assetPath: assetPathSchema,
|
|
5230
|
-
graphName: graphNameSchema,
|
|
5231
|
-
nodeGuid: graphNodeGuidSchema,
|
|
5232
|
-
requestId: requestIdSchema,
|
|
5233
|
-
type: z.literal(BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE),
|
|
5234
|
-
version: z.literal(2)
|
|
5235
|
-
});
|
|
5236
|
-
const graphPinPairFields = {
|
|
5237
|
-
assetPath: assetPathSchema,
|
|
5238
|
-
graphName: graphNameSchema,
|
|
5239
|
-
requestId: requestIdSchema,
|
|
5240
|
-
sourceNodeGuid: graphNodeGuidSchema,
|
|
5241
|
-
sourcePinName: graphPinNameSchema,
|
|
5242
|
-
targetNodeGuid: graphNodeGuidSchema,
|
|
5243
|
-
targetPinName: graphPinNameSchema,
|
|
5244
|
-
version: z.literal(2)
|
|
5245
|
-
};
|
|
5246
|
-
const bridgeConnectPinsRequestSchema = z.object({
|
|
5247
|
-
...graphPinPairFields,
|
|
5248
|
-
type: z.literal(BRIDGE_CONNECT_PINS_REQUEST_TYPE)
|
|
5249
|
-
});
|
|
5250
|
-
const bridgeDisconnectPinsRequestSchema = z.object({
|
|
5251
|
-
...graphPinPairFields,
|
|
5252
|
-
type: z.literal(BRIDGE_DISCONNECT_PINS_REQUEST_TYPE)
|
|
5253
|
-
});
|
|
5254
|
-
const bridgeSetPinDefaultRequestSchema = z.object({
|
|
5255
|
-
assetPath: assetPathSchema,
|
|
5256
|
-
graphName: graphNameSchema,
|
|
5257
|
-
nodeGuid: graphNodeGuidSchema,
|
|
5258
|
-
pinName: graphPinNameSchema,
|
|
5259
|
-
requestId: requestIdSchema,
|
|
5260
|
-
type: z.literal(BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE),
|
|
5261
|
-
value: graphPinValueSchema,
|
|
5262
|
-
version: z.literal(2)
|
|
5263
|
-
});
|
|
5264
|
-
const bridgeListAvailableNodesRequestSchema = z.object({
|
|
5265
|
-
assetPath: assetPathSchema,
|
|
5266
|
-
cursor: assetCursorSchema.optional(),
|
|
5267
|
-
graphName: graphNameSchema,
|
|
5268
|
-
maxResults: availableNodeMaxResultsSchema.optional(),
|
|
5269
|
-
nameFilter: boundedStringSchema.optional(),
|
|
5270
|
-
requestId: requestIdSchema,
|
|
5271
|
-
type: z.literal(BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE),
|
|
5272
|
-
version: z.literal(2)
|
|
5273
|
-
});
|
|
5274
|
-
const bridgeListGraphNodesSuccessResponseSchema = z.object({
|
|
5275
|
-
assetPath: z.string(),
|
|
5276
|
-
graphName: z.string(),
|
|
5277
|
-
nextCursor: assetCursorSchema.optional(),
|
|
5278
|
-
nodeCount: z.number().int().min(0),
|
|
5279
|
-
nodes: z.array(bridgeBlueprintNodeSchema).max(100),
|
|
5280
|
-
ok: z.literal(true),
|
|
5281
|
-
requestId: requestIdSchema,
|
|
5282
|
-
truncated: z.boolean(),
|
|
5283
|
-
type: z.literal(BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE),
|
|
5284
|
-
version: z.literal(2)
|
|
5285
|
-
});
|
|
5286
|
-
const bridgeAddGraphNodeSuccessResponseSchema = z.object({
|
|
5287
|
-
assetPath: z.string(),
|
|
5288
|
-
graphName: z.string(),
|
|
5289
|
-
message: nonEmptyStringSchema.optional(),
|
|
5290
|
-
node: bridgeBlueprintNodeSchema,
|
|
5291
|
-
ok: z.literal(true),
|
|
5292
|
-
requestId: requestIdSchema,
|
|
5293
|
-
state: creativeEditStateSchema,
|
|
5294
|
-
type: z.literal(BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE),
|
|
5295
|
-
version: z.literal(2)
|
|
5296
|
-
});
|
|
5297
|
-
const bridgeRemoveGraphNodeSuccessResponseSchema = z.object({
|
|
5298
|
-
assetPath: z.string(),
|
|
5299
|
-
graphName: z.string(),
|
|
5300
|
-
message: nonEmptyStringSchema.optional(),
|
|
5301
|
-
nodeGuid: z.string(),
|
|
5302
|
-
ok: z.literal(true),
|
|
5303
|
-
removed: z.boolean(),
|
|
5304
|
-
requestId: requestIdSchema,
|
|
5305
|
-
state: creativeEditStateSchema,
|
|
5306
|
-
type: z.literal(BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE),
|
|
5307
|
-
version: z.literal(2)
|
|
5308
|
-
});
|
|
5309
|
-
const graphPinPairResponseFields = {
|
|
5310
|
-
assetPath: z.string(),
|
|
5311
|
-
graphName: z.string(),
|
|
5312
|
-
message: nonEmptyStringSchema.optional(),
|
|
5313
|
-
ok: z.literal(true),
|
|
5314
|
-
requestId: requestIdSchema,
|
|
5315
|
-
sourceNodeGuid: z.string(),
|
|
5316
|
-
sourcePinName: z.string(),
|
|
5317
|
-
state: creativeEditStateSchema,
|
|
5318
|
-
targetNodeGuid: z.string(),
|
|
5319
|
-
targetPinName: z.string(),
|
|
5320
|
-
version: z.literal(2)
|
|
5321
|
-
};
|
|
5322
|
-
const bridgeConnectPinsSuccessResponseSchema = z.object({
|
|
5323
|
-
...graphPinPairResponseFields,
|
|
5324
|
-
connected: z.boolean(),
|
|
5325
|
-
type: z.literal(BRIDGE_CONNECT_PINS_REQUEST_TYPE)
|
|
5326
|
-
});
|
|
5327
|
-
const bridgeDisconnectPinsSuccessResponseSchema = z.object({
|
|
5328
|
-
...graphPinPairResponseFields,
|
|
5329
|
-
disconnected: z.boolean(),
|
|
5330
|
-
type: z.literal(BRIDGE_DISCONNECT_PINS_REQUEST_TYPE)
|
|
5331
|
-
});
|
|
5332
|
-
const bridgeSetPinDefaultSuccessResponseSchema = z.object({
|
|
5333
|
-
assetPath: z.string(),
|
|
5334
|
-
graphName: z.string(),
|
|
5335
|
-
message: nonEmptyStringSchema.optional(),
|
|
5336
|
-
nodeGuid: z.string(),
|
|
5337
|
-
ok: z.literal(true),
|
|
5338
|
-
pinName: z.string(),
|
|
5339
|
-
requestId: requestIdSchema,
|
|
5340
|
-
state: creativeEditStateSchema,
|
|
5341
|
-
type: z.literal(BRIDGE_SET_PIN_DEFAULT_REQUEST_TYPE),
|
|
5342
|
-
value: z.string(),
|
|
5343
|
-
version: z.literal(2)
|
|
5344
|
-
});
|
|
5345
|
-
const bridgeGraphActionSchema = z.object({
|
|
5346
|
-
category: z.string(),
|
|
5347
|
-
keywords: z.string().optional(),
|
|
5348
|
-
memberName: z.string().optional(),
|
|
5349
|
-
memberParentClass: z.string().optional(),
|
|
5350
|
-
nodeClass: z.string(),
|
|
5351
|
-
nodeKind: graphNodeKindSchema,
|
|
5352
|
-
title: z.string(),
|
|
5353
|
-
tooltip: z.string().optional()
|
|
5354
|
-
});
|
|
5355
|
-
const bridgeListAvailableNodesSuccessResponseSchema = z.object({
|
|
5356
|
-
actions: z.array(bridgeGraphActionSchema).max(100),
|
|
5357
|
-
assetPath: z.string(),
|
|
5358
|
-
graphName: z.string(),
|
|
5359
|
-
nextCursor: assetCursorSchema.optional(),
|
|
5360
|
-
ok: z.literal(true),
|
|
5837
|
+
packageDirty: z.boolean(),
|
|
5361
5838
|
requestId: requestIdSchema,
|
|
5362
|
-
|
|
5363
|
-
|
|
5364
|
-
type: z.literal(BRIDGE_LIST_AVAILABLE_NODES_REQUEST_TYPE),
|
|
5839
|
+
state: creativeEditStateSchema,
|
|
5840
|
+
type: z.literal(BRIDGE_ADD_POST_PROCESS_MATERIAL_REQUEST_TYPE),
|
|
5365
5841
|
version: z.literal(2)
|
|
5366
5842
|
});
|
|
5367
|
-
const
|
|
5368
|
-
const
|
|
5369
|
-
const
|
|
5370
|
-
|
|
5371
|
-
|
|
5372
|
-
|
|
5373
|
-
|
|
5374
|
-
|
|
5375
|
-
|
|
5376
|
-
|
|
5377
|
-
|
|
5378
|
-
|
|
5379
|
-
loadIfNeeded: options.loadIfNeeded,
|
|
5380
|
-
maxResults: options.maxResults,
|
|
5381
|
-
requestId,
|
|
5382
|
-
type: BRIDGE_LIST_GRAPH_NODES_REQUEST_TYPE,
|
|
5383
|
-
version: 2
|
|
5384
|
-
});
|
|
5385
|
-
}
|
|
5386
|
-
function createBridgeAddGraphNodeRequest(assetPath, graphName, kind, options = {}, requestId = randomUUID()) {
|
|
5387
|
-
return bridgeAddGraphNodeRequestSchema.parse({
|
|
5388
|
-
assetPath,
|
|
5389
|
-
graphName,
|
|
5390
|
-
kind,
|
|
5391
|
-
memberName: options.memberName,
|
|
5392
|
-
memberParentClass: options.memberParentClass,
|
|
5393
|
-
nodeClass: options.nodeClass,
|
|
5394
|
-
pinDefaults: options.pinDefaults,
|
|
5395
|
-
position: options.position,
|
|
5396
|
-
requestId,
|
|
5397
|
-
type: BRIDGE_ADD_GRAPH_NODE_REQUEST_TYPE,
|
|
5398
|
-
version: 2
|
|
5399
|
-
});
|
|
5400
|
-
}
|
|
5401
|
-
function createBridgeRemoveGraphNodeRequest(assetPath, graphName, nodeGuid, requestId = randomUUID()) {
|
|
5402
|
-
return bridgeRemoveGraphNodeRequestSchema.parse({
|
|
5403
|
-
assetPath,
|
|
5404
|
-
graphName,
|
|
5405
|
-
nodeGuid,
|
|
5406
|
-
requestId,
|
|
5407
|
-
type: BRIDGE_REMOVE_GRAPH_NODE_REQUEST_TYPE,
|
|
5408
|
-
version: 2
|
|
5409
|
-
});
|
|
5410
|
-
}
|
|
5411
|
-
function createBridgeConnectPinsRequest(assetPath, graphName, source, target, requestId = randomUUID()) {
|
|
5412
|
-
return bridgeConnectPinsRequestSchema.parse({
|
|
5413
|
-
assetPath,
|
|
5414
|
-
graphName,
|
|
5415
|
-
requestId,
|
|
5416
|
-
sourceNodeGuid: source.nodeGuid,
|
|
5417
|
-
sourcePinName: source.pinName,
|
|
5418
|
-
targetNodeGuid: target.nodeGuid,
|
|
5419
|
-
targetPinName: target.pinName,
|
|
5420
|
-
type: BRIDGE_CONNECT_PINS_REQUEST_TYPE,
|
|
5421
|
-
version: 2
|
|
5422
|
-
});
|
|
5423
|
-
}
|
|
5424
|
-
function createBridgeDisconnectPinsRequest(assetPath, graphName, source, target, requestId = randomUUID()) {
|
|
5425
|
-
return bridgeDisconnectPinsRequestSchema.parse({
|
|
5426
|
-
assetPath,
|
|
5427
|
-
graphName,
|
|
5843
|
+
const bridgeCreatePostProcessVolumeResponseSchema = z.union([bridgeCreatePostProcessVolumeSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
5844
|
+
const bridgeSetPostProcessSettingsResponseSchema = z.union([bridgeSetPostProcessSettingsSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
5845
|
+
const bridgeAddPostProcessMaterialResponseSchema = z.union([bridgeAddPostProcessMaterialSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
5846
|
+
function createBridgeCreatePostProcessVolumeRequest(options = {}, requestId = randomUUID()) {
|
|
5847
|
+
return bridgeCreatePostProcessVolumeRequestSchema.parse({
|
|
5848
|
+
actorLabel: options.actorLabel,
|
|
5849
|
+
blendRadius: options.blendRadius,
|
|
5850
|
+
blendWeight: options.blendWeight,
|
|
5851
|
+
extent: options.extent,
|
|
5852
|
+
folderPath: options.folderPath,
|
|
5853
|
+
location: options.location,
|
|
5854
|
+
priority: options.priority,
|
|
5428
5855
|
requestId,
|
|
5429
|
-
|
|
5430
|
-
|
|
5431
|
-
|
|
5432
|
-
targetPinName: target.pinName,
|
|
5433
|
-
type: BRIDGE_DISCONNECT_PINS_REQUEST_TYPE,
|
|
5856
|
+
settings: options.settings,
|
|
5857
|
+
type: BRIDGE_CREATE_POST_PROCESS_VOLUME_REQUEST_TYPE,
|
|
5858
|
+
unbound: options.unbound,
|
|
5434
5859
|
version: 2
|
|
5435
5860
|
});
|
|
5436
5861
|
}
|
|
5437
|
-
function
|
|
5438
|
-
return
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
nodeGuid,
|
|
5442
|
-
pinName,
|
|
5862
|
+
function createBridgeSetPostProcessSettingsRequest(actorPath, targetKind, settings, options = {}, requestId = randomUUID()) {
|
|
5863
|
+
return bridgeSetPostProcessSettingsRequestSchema.parse({
|
|
5864
|
+
actorPath,
|
|
5865
|
+
componentName: options.componentName,
|
|
5443
5866
|
requestId,
|
|
5444
|
-
|
|
5445
|
-
|
|
5867
|
+
settings,
|
|
5868
|
+
targetKind,
|
|
5869
|
+
type: BRIDGE_SET_POST_PROCESS_SETTINGS_REQUEST_TYPE,
|
|
5446
5870
|
version: 2
|
|
5447
5871
|
});
|
|
5448
5872
|
}
|
|
5449
|
-
function
|
|
5450
|
-
return
|
|
5451
|
-
|
|
5452
|
-
|
|
5453
|
-
|
|
5454
|
-
|
|
5455
|
-
nameFilter: options.nameFilter,
|
|
5873
|
+
function createBridgeAddPostProcessMaterialRequest(actorPath, materialPath, options = {}, requestId = randomUUID()) {
|
|
5874
|
+
return bridgeAddPostProcessMaterialRequestSchema.parse({
|
|
5875
|
+
actorPath,
|
|
5876
|
+
blendableLocation: options.blendableLocation,
|
|
5877
|
+
componentName: options.componentName,
|
|
5878
|
+
materialPath,
|
|
5456
5879
|
requestId,
|
|
5457
|
-
|
|
5458
|
-
|
|
5880
|
+
targetKind: options.targetKind,
|
|
5881
|
+
type: BRIDGE_ADD_POST_PROCESS_MATERIAL_REQUEST_TYPE,
|
|
5882
|
+
version: 2,
|
|
5883
|
+
weight: options.weight
|
|
5459
5884
|
});
|
|
5460
5885
|
}
|
|
5461
5886
|
//#endregion
|
|
@@ -8073,6 +8498,46 @@ function createBridgeAddInputMappingRequest(contextPath, mappings, requestId = r
|
|
|
8073
8498
|
version: 2
|
|
8074
8499
|
});
|
|
8075
8500
|
}
|
|
8501
|
+
const BRIDGE_INJECT_INPUT_ACTION_REQUEST_TYPE = "inject_input_action";
|
|
8502
|
+
const bridgeInjectInputActionRequestSchema = z.object({
|
|
8503
|
+
actionPath: assetPathSchema,
|
|
8504
|
+
durationSeconds: z.number().min(0).max(60).optional(),
|
|
8505
|
+
pieInstanceIndex: pieInstanceIndexSchema.optional(),
|
|
8506
|
+
playerIndex: z.number().int().min(0).max(16).default(0),
|
|
8507
|
+
requestId: requestIdSchema,
|
|
8508
|
+
type: z.literal(BRIDGE_INJECT_INPUT_ACTION_REQUEST_TYPE),
|
|
8509
|
+
value: vectorInputSchema.default({
|
|
8510
|
+
x: 0,
|
|
8511
|
+
y: 0,
|
|
8512
|
+
z: 0
|
|
8513
|
+
}),
|
|
8514
|
+
version: z.literal(2)
|
|
8515
|
+
});
|
|
8516
|
+
const bridgeInjectInputActionSuccessResponseSchema = z.object({
|
|
8517
|
+
actionPath: z.string(),
|
|
8518
|
+
durationSeconds: z.number().min(0),
|
|
8519
|
+
ok: z.literal(true),
|
|
8520
|
+
pieInstanceIndex: z.number().int().min(0),
|
|
8521
|
+
playerIndex: z.number().int().min(0),
|
|
8522
|
+
requestId: requestIdSchema,
|
|
8523
|
+
type: z.literal(BRIDGE_INJECT_INPUT_ACTION_REQUEST_TYPE),
|
|
8524
|
+
valueType: z.string(),
|
|
8525
|
+
version: z.literal(2),
|
|
8526
|
+
worldName: z.string()
|
|
8527
|
+
});
|
|
8528
|
+
const bridgeInjectInputActionResponseSchema = z.union([bridgeInjectInputActionSuccessResponseSchema, bridgeErrorResponseSchema]);
|
|
8529
|
+
function createBridgeInjectInputActionRequest(actionPath, options = {}, requestId = randomUUID()) {
|
|
8530
|
+
return bridgeInjectInputActionRequestSchema.parse({
|
|
8531
|
+
actionPath,
|
|
8532
|
+
durationSeconds: options.durationSeconds,
|
|
8533
|
+
pieInstanceIndex: options.pieInstanceIndex,
|
|
8534
|
+
playerIndex: options.playerIndex,
|
|
8535
|
+
requestId,
|
|
8536
|
+
type: BRIDGE_INJECT_INPUT_ACTION_REQUEST_TYPE,
|
|
8537
|
+
value: options.value,
|
|
8538
|
+
version: 2
|
|
8539
|
+
});
|
|
8540
|
+
}
|
|
8076
8541
|
//#endregion
|
|
8077
8542
|
//#region src/protocol/behaviorTree.ts
|
|
8078
8543
|
const BRIDGE_CREATE_BEHAVIOR_TREE_REQUEST_TYPE = "create_behavior_tree";
|
|
@@ -9250,7 +9715,7 @@ function createBridgeSetDefaultGamemodeRequest(scope, gameModePath, options = {}
|
|
|
9250
9715
|
}
|
|
9251
9716
|
//#endregion
|
|
9252
9717
|
//#region src/version.ts
|
|
9253
|
-
const SERVER_VERSION = "1.
|
|
9718
|
+
const SERVER_VERSION = "1.9.1";
|
|
9254
9719
|
//#endregion
|
|
9255
9720
|
//#region src/bridgeSocketClient.ts
|
|
9256
9721
|
var BridgeSocketError = class extends Error {
|
|
@@ -10113,6 +10578,33 @@ async function sendBridgeSetProjectSettingsRequest(request, options) {
|
|
|
10113
10578
|
async function sendBridgeSetDefaultGamemodeRequest(request, options) {
|
|
10114
10579
|
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetDefaultGamemodeResponseSchema, request.requestId);
|
|
10115
10580
|
}
|
|
10581
|
+
async function sendBridgeCallActorFunctionRequest(request, options) {
|
|
10582
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeCallActorFunctionResponseSchema, request.requestId);
|
|
10583
|
+
}
|
|
10584
|
+
async function sendBridgeListPieWorldsRequest(request, options) {
|
|
10585
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeListPieWorldsResponseSchema, request.requestId);
|
|
10586
|
+
}
|
|
10587
|
+
async function sendBridgeGetNetStatsRequest(request, options) {
|
|
10588
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetNetStatsResponseSchema, request.requestId);
|
|
10589
|
+
}
|
|
10590
|
+
async function sendBridgeInjectInputActionRequest(request, options) {
|
|
10591
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeInjectInputActionResponseSchema, request.requestId);
|
|
10592
|
+
}
|
|
10593
|
+
async function sendBridgeSetBlueprintBreakpointRequest(request, options) {
|
|
10594
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeSetBlueprintBreakpointResponseSchema, request.requestId);
|
|
10595
|
+
}
|
|
10596
|
+
async function sendBridgeListBlueprintBreakpointsRequest(request, options) {
|
|
10597
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeListBlueprintBreakpointsResponseSchema, request.requestId);
|
|
10598
|
+
}
|
|
10599
|
+
async function sendBridgeGetBlueprintDebuggerStateRequest(request, options) {
|
|
10600
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeGetBlueprintDebuggerStateResponseSchema, request.requestId);
|
|
10601
|
+
}
|
|
10602
|
+
async function sendBridgeControlBlueprintDebuggerRequest(request, options) {
|
|
10603
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeControlBlueprintDebuggerResponseSchema, request.requestId);
|
|
10604
|
+
}
|
|
10605
|
+
async function sendBridgeWatchBlueprintPinRequest(request, options) {
|
|
10606
|
+
return parseBridgeResponse(await exchangeBridgeMessage(encodeBridgeFrame(request), options), bridgeWatchBlueprintPinResponseSchema, request.requestId);
|
|
10607
|
+
}
|
|
10116
10608
|
//#endregion
|
|
10117
10609
|
//#region src/enginePing.ts
|
|
10118
10610
|
async function pingRegistryEntry$1(entry, options) {
|
|
@@ -16103,6 +16595,227 @@ const dataTableToolDomain = {
|
|
|
16103
16595
|
]
|
|
16104
16596
|
};
|
|
16105
16597
|
//#endregion
|
|
16598
|
+
//#region src/tools/debugger.ts
|
|
16599
|
+
const setBlueprintBreakpointInputSchema = {
|
|
16600
|
+
action: bridgeSetBlueprintBreakpointRequestSchema.shape.action.describe("What to do: 'set' adds a breakpoint, 'clear' removes it, 'enable' and 'disable' toggle an existing one."),
|
|
16601
|
+
blueprintPath: bridgeSetBlueprintBreakpointRequestSchema.shape.blueprintPath.describe("Path of the Blueprint asset holding the node (e.g. /Game/BP/BP_Character)."),
|
|
16602
|
+
graphName: bridgeSetBlueprintBreakpointRequestSchema.shape.graphName.describe("Restrict a nodeTitle match to one graph (e.g. EventGraph). Ignored when nodeGuid is supplied."),
|
|
16603
|
+
nodeGuid: bridgeSetBlueprintBreakpointRequestSchema.shape.nodeGuid.describe("Guid of the graph node, as list_blueprint_breakpoints and get_blueprint_debugger_state report it. Takes precedence over nodeTitle."),
|
|
16604
|
+
nodeTitle: bridgeSetBlueprintBreakpointRequestSchema.shape.nodeTitle.describe("The node's displayed title (e.g. 'Print String'). Supply this when you have no guid; narrow it with graphName when the title repeats."),
|
|
16605
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the Blueprint.")
|
|
16606
|
+
};
|
|
16607
|
+
const listBlueprintBreakpointsInputSchema = {
|
|
16608
|
+
blueprintPath: bridgeListBlueprintBreakpointsRequestSchema.shape.blueprintPath.describe("Path of the Blueprint asset whose breakpoints should be listed."),
|
|
16609
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the Blueprint.")
|
|
16610
|
+
};
|
|
16611
|
+
const getBlueprintDebuggerStateInputSchema = {
|
|
16612
|
+
maxFrames: bridgeGetBlueprintDebuggerStateRequestSchema.shape.maxFrames.describe(`Maximum call stack frames to return (1-${String(64)}, default ${String(32)}), innermost first.`),
|
|
16613
|
+
maxWatches: bridgeGetBlueprintDebuggerStateRequestSchema.shape.maxWatches.describe(`Maximum watched pin values to return (1-${String(64)}, default ${String(32)}).`),
|
|
16614
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should report its Blueprint debugger state.")
|
|
16615
|
+
};
|
|
16616
|
+
const controlBlueprintDebuggerInputSchema = {
|
|
16617
|
+
action: bridgeControlBlueprintDebuggerRequestSchema.shape.action.describe("What to do: 'resume' continues play, 'step_over' / 'step_into' / 'step_out' advance one node, 'stop' ends the play session outright."),
|
|
16618
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor is paused at a Blueprint breakpoint.")
|
|
16619
|
+
};
|
|
16620
|
+
const watchBlueprintPinInputSchema = {
|
|
16621
|
+
action: bridgeWatchBlueprintPinRequestSchema.shape.action.describe("What to do: 'set' starts watching a pin, 'clear' stops watching one, 'clear_all' drops every watch on the Blueprint."),
|
|
16622
|
+
blueprintPath: bridgeWatchBlueprintPinRequestSchema.shape.blueprintPath.describe("Path of the Blueprint asset holding the pin (e.g. /Game/BP/BP_Character)."),
|
|
16623
|
+
graphName: bridgeWatchBlueprintPinRequestSchema.shape.graphName.describe("Restrict a nodeTitle match to one graph (e.g. EventGraph). Ignored when nodeGuid is supplied."),
|
|
16624
|
+
nodeGuid: bridgeWatchBlueprintPinRequestSchema.shape.nodeGuid.describe("Guid of the node owning the pin, as list_graph_nodes reports it. Takes precedence over nodeTitle."),
|
|
16625
|
+
nodeTitle: bridgeWatchBlueprintPinRequestSchema.shape.nodeTitle.describe("The owning node's displayed title (e.g. 'Print String'). Supply this when you have no guid."),
|
|
16626
|
+
pinName: bridgeWatchBlueprintPinRequestSchema.shape.pinName.describe("The pin's name, as list_graph_nodes reports it (e.g. 'InString'). Required unless action is 'clear_all'."),
|
|
16627
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the Blueprint.")
|
|
16628
|
+
};
|
|
16629
|
+
async function setBlueprintBreakpoint(input, dependencies) {
|
|
16630
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
16631
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
16632
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
16633
|
+
const response = await sendBridgeSetBlueprintBreakpointRequest(createBridgeSetBlueprintBreakpointRequest(input.blueprintPath, input.action, {
|
|
16634
|
+
graphName: input.graphName,
|
|
16635
|
+
nodeGuid: input.nodeGuid,
|
|
16636
|
+
nodeTitle: input.nodeTitle
|
|
16637
|
+
}), {
|
|
16638
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
16639
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
16640
|
+
port: entry.port,
|
|
16641
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
16642
|
+
});
|
|
16643
|
+
if (!response.ok) throw new Error(`Bridge set_blueprint_breakpoint failed (${response.error.code}): ${response.error.message}`);
|
|
16644
|
+
return {
|
|
16645
|
+
blueprintPath: response.blueprintPath,
|
|
16646
|
+
breakpointCount: response.breakpointCount,
|
|
16647
|
+
graphName: response.graphName,
|
|
16648
|
+
message: response.message,
|
|
16649
|
+
nodeGuid: response.nodeGuid,
|
|
16650
|
+
nodeTitle: response.nodeTitle,
|
|
16651
|
+
projectId: entry.projectId,
|
|
16652
|
+
state: response.state
|
|
16653
|
+
};
|
|
16654
|
+
}
|
|
16655
|
+
async function listBlueprintBreakpoints(input, dependencies) {
|
|
16656
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
16657
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
16658
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
16659
|
+
const response = await sendBridgeListBlueprintBreakpointsRequest(createBridgeListBlueprintBreakpointsRequest(input.blueprintPath), {
|
|
16660
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
16661
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
16662
|
+
port: entry.port,
|
|
16663
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
16664
|
+
});
|
|
16665
|
+
if (!response.ok) throw new Error(`Bridge list_blueprint_breakpoints failed (${response.error.code}): ${response.error.message}`);
|
|
16666
|
+
return {
|
|
16667
|
+
blueprintPath: response.blueprintPath,
|
|
16668
|
+
breakpoints: response.breakpoints,
|
|
16669
|
+
message: response.message,
|
|
16670
|
+
projectId: entry.projectId
|
|
16671
|
+
};
|
|
16672
|
+
}
|
|
16673
|
+
async function getBlueprintDebuggerState(input, dependencies) {
|
|
16674
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
16675
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
16676
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
16677
|
+
const response = await sendBridgeGetBlueprintDebuggerStateRequest(createBridgeGetBlueprintDebuggerStateRequest({
|
|
16678
|
+
maxFrames: input.maxFrames,
|
|
16679
|
+
maxWatches: input.maxWatches
|
|
16680
|
+
}), {
|
|
16681
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
16682
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
16683
|
+
port: entry.port,
|
|
16684
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
16685
|
+
});
|
|
16686
|
+
if (!response.ok) throw new Error(`Bridge get_blueprint_debugger_state failed (${response.error.code}): ${response.error.message}`);
|
|
16687
|
+
return {
|
|
16688
|
+
blueprintPath: response.blueprintPath,
|
|
16689
|
+
callStack: response.callStack,
|
|
16690
|
+
graphName: response.graphName,
|
|
16691
|
+
message: response.message,
|
|
16692
|
+
nodeGuid: response.nodeGuid,
|
|
16693
|
+
nodeTitle: response.nodeTitle,
|
|
16694
|
+
paused: response.paused,
|
|
16695
|
+
projectId: entry.projectId,
|
|
16696
|
+
watches: response.watches
|
|
16697
|
+
};
|
|
16698
|
+
}
|
|
16699
|
+
async function controlBlueprintDebugger(input, dependencies) {
|
|
16700
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
16701
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
16702
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
16703
|
+
const response = await sendBridgeControlBlueprintDebuggerRequest(createBridgeControlBlueprintDebuggerRequest(input.action), {
|
|
16704
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
16705
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
16706
|
+
port: entry.port,
|
|
16707
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
16708
|
+
});
|
|
16709
|
+
if (!response.ok) throw new Error(`Bridge control_blueprint_debugger failed (${response.error.code}): ${response.error.message}`);
|
|
16710
|
+
return {
|
|
16711
|
+
action: response.action,
|
|
16712
|
+
message: response.message,
|
|
16713
|
+
projectId: entry.projectId,
|
|
16714
|
+
state: response.state
|
|
16715
|
+
};
|
|
16716
|
+
}
|
|
16717
|
+
async function watchBlueprintPin(input, dependencies) {
|
|
16718
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
16719
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
16720
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
16721
|
+
const response = await sendBridgeWatchBlueprintPinRequest(createBridgeWatchBlueprintPinRequest(input.blueprintPath, input.action, {
|
|
16722
|
+
graphName: input.graphName,
|
|
16723
|
+
nodeGuid: input.nodeGuid,
|
|
16724
|
+
nodeTitle: input.nodeTitle,
|
|
16725
|
+
pinName: input.pinName
|
|
16726
|
+
}), {
|
|
16727
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
16728
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
16729
|
+
port: entry.port,
|
|
16730
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
16731
|
+
});
|
|
16732
|
+
if (!response.ok) throw new Error(`Bridge watch_blueprint_pin failed (${response.error.code}): ${response.error.message}`);
|
|
16733
|
+
return {
|
|
16734
|
+
blueprintPath: response.blueprintPath,
|
|
16735
|
+
graphName: response.graphName,
|
|
16736
|
+
message: response.message,
|
|
16737
|
+
nodeGuid: response.nodeGuid,
|
|
16738
|
+
nodeTitle: response.nodeTitle,
|
|
16739
|
+
pinName: response.pinName,
|
|
16740
|
+
projectId: normalizedProjectId,
|
|
16741
|
+
state: response.state,
|
|
16742
|
+
watchCount: response.watchCount
|
|
16743
|
+
};
|
|
16744
|
+
}
|
|
16745
|
+
function registerDebuggerTools(server, dependencies) {
|
|
16746
|
+
server.registerTool("set_blueprint_breakpoint", {
|
|
16747
|
+
description: "Set, clear, enable or disable a breakpoint on one Blueprint graph node, addressed by nodeGuid or by nodeTitle. Breakpoints survive until the editor closes, so set them before start_pie and the play session will halt on the node. Returns the resulting state and the Blueprint's total breakpoint count.",
|
|
16748
|
+
inputSchema: setBlueprintBreakpointInputSchema,
|
|
16749
|
+
title: "Set Blueprint Breakpoint"
|
|
16750
|
+
}, async ({ action, blueprintPath, graphName, nodeGuid, nodeTitle, projectId }) => {
|
|
16751
|
+
return toToolSuccess(await setBlueprintBreakpoint({
|
|
16752
|
+
action,
|
|
16753
|
+
blueprintPath,
|
|
16754
|
+
graphName,
|
|
16755
|
+
nodeGuid,
|
|
16756
|
+
nodeTitle,
|
|
16757
|
+
projectId
|
|
16758
|
+
}, dependencies));
|
|
16759
|
+
});
|
|
16760
|
+
server.registerTool("list_blueprint_breakpoints", {
|
|
16761
|
+
description: "List every breakpoint on one Blueprint, each with its node guid, node title, owning graph and enabled flag. The guids are what set_blueprint_breakpoint takes to clear or toggle a breakpoint precisely.",
|
|
16762
|
+
inputSchema: listBlueprintBreakpointsInputSchema,
|
|
16763
|
+
title: "List Blueprint Breakpoints"
|
|
16764
|
+
}, async ({ blueprintPath, projectId }) => {
|
|
16765
|
+
return toToolSuccess(await listBlueprintBreakpoints({
|
|
16766
|
+
blueprintPath,
|
|
16767
|
+
projectId
|
|
16768
|
+
}, dependencies));
|
|
16769
|
+
});
|
|
16770
|
+
server.registerTool("get_blueprint_debugger_state", {
|
|
16771
|
+
description: "Report whether Blueprint execution is paused at a breakpoint and, when it is, the node it stopped on, the call stack innermost first, and the value of every watched pin. Returns paused=false with a message when nothing is halted, so it is safe to poll while waiting for a breakpoint to hit.",
|
|
16772
|
+
inputSchema: getBlueprintDebuggerStateInputSchema,
|
|
16773
|
+
title: "Get Blueprint Debugger State"
|
|
16774
|
+
}, async ({ maxFrames, maxWatches, projectId }) => {
|
|
16775
|
+
return toToolSuccess(await getBlueprintDebuggerState({
|
|
16776
|
+
maxFrames,
|
|
16777
|
+
maxWatches,
|
|
16778
|
+
projectId
|
|
16779
|
+
}, dependencies));
|
|
16780
|
+
});
|
|
16781
|
+
server.registerTool("control_blueprint_debugger", {
|
|
16782
|
+
description: "Resume, step or stop a play session halted at a Blueprint breakpoint. 'stop' works whether or not execution is paused; every other action reports not_paused rather than silently doing nothing when nothing is halted.",
|
|
16783
|
+
inputSchema: controlBlueprintDebuggerInputSchema,
|
|
16784
|
+
title: "Control Blueprint Debugger"
|
|
16785
|
+
}, async ({ action, projectId }) => {
|
|
16786
|
+
return toToolSuccess(await controlBlueprintDebugger({
|
|
16787
|
+
action,
|
|
16788
|
+
projectId
|
|
16789
|
+
}, dependencies));
|
|
16790
|
+
});
|
|
16791
|
+
server.registerTool("watch_blueprint_pin", {
|
|
16792
|
+
description: "Start or stop watching a Blueprint pin, so get_blueprint_debugger_state reports its value whenever execution halts. Watches survive between play sessions and are what turns a breakpoint into a readable snapshot of local state; without one the debugger reports the paused node and call stack but no values.",
|
|
16793
|
+
inputSchema: watchBlueprintPinInputSchema,
|
|
16794
|
+
title: "Watch Blueprint Pin"
|
|
16795
|
+
}, async ({ action, blueprintPath, graphName, nodeGuid, nodeTitle, pinName, projectId }) => {
|
|
16796
|
+
return toToolSuccess(await watchBlueprintPin({
|
|
16797
|
+
action,
|
|
16798
|
+
blueprintPath,
|
|
16799
|
+
graphName,
|
|
16800
|
+
nodeGuid,
|
|
16801
|
+
nodeTitle,
|
|
16802
|
+
pinName,
|
|
16803
|
+
projectId
|
|
16804
|
+
}, dependencies));
|
|
16805
|
+
});
|
|
16806
|
+
}
|
|
16807
|
+
const debuggerToolDomain = {
|
|
16808
|
+
domain: "debugger",
|
|
16809
|
+
register: registerDebuggerTools,
|
|
16810
|
+
toolNames: [
|
|
16811
|
+
"set_blueprint_breakpoint",
|
|
16812
|
+
"list_blueprint_breakpoints",
|
|
16813
|
+
"get_blueprint_debugger_state",
|
|
16814
|
+
"control_blueprint_debugger",
|
|
16815
|
+
"watch_blueprint_pin"
|
|
16816
|
+
]
|
|
16817
|
+
};
|
|
16818
|
+
//#endregion
|
|
16106
16819
|
//#region src/traceAnalysis.ts
|
|
16107
16820
|
const SECONDS_TO_MS = 1e3;
|
|
16108
16821
|
const FRAME_ROOT_TIMER_NAMES = /* @__PURE__ */ new Set(["FEngineLoop::Tick"]);
|
|
@@ -17613,27 +18326,329 @@ function registerImportTools(server, dependencies) {
|
|
|
17613
18326
|
settings
|
|
17614
18327
|
}, dependencies));
|
|
17615
18328
|
});
|
|
17616
|
-
server.registerTool("get_import_job_status", {
|
|
17617
|
-
description: "Poll an import job started by import_asset or reimport_asset; returns state (running, succeeded, failed, unknown_job), which operation it was, and once finished the per-file results with the assets each one created plus successCount / failureCount and timing. Poll until the state leaves 'running' before referencing any imported asset.",
|
|
17618
|
-
inputSchema: getImportJobStatusInputSchema,
|
|
17619
|
-
title: "Get Import Job Status"
|
|
17620
|
-
}, async ({ importJobId, projectId }) => {
|
|
17621
|
-
return toToolSuccess(await getImportJobStatus({
|
|
17622
|
-
importJobId,
|
|
18329
|
+
server.registerTool("get_import_job_status", {
|
|
18330
|
+
description: "Poll an import job started by import_asset or reimport_asset; returns state (running, succeeded, failed, unknown_job), which operation it was, and once finished the per-file results with the assets each one created plus successCount / failureCount and timing. Poll until the state leaves 'running' before referencing any imported asset.",
|
|
18331
|
+
inputSchema: getImportJobStatusInputSchema,
|
|
18332
|
+
title: "Get Import Job Status"
|
|
18333
|
+
}, async ({ importJobId, projectId }) => {
|
|
18334
|
+
return toToolSuccess(await getImportJobStatus({
|
|
18335
|
+
importJobId,
|
|
18336
|
+
projectId
|
|
18337
|
+
}, dependencies));
|
|
18338
|
+
});
|
|
18339
|
+
}
|
|
18340
|
+
const importToolDomain = {
|
|
18341
|
+
domain: "import",
|
|
18342
|
+
register: registerImportTools,
|
|
18343
|
+
toolNames: [
|
|
18344
|
+
"import_asset",
|
|
18345
|
+
"reimport_asset",
|
|
18346
|
+
"set_import_settings",
|
|
18347
|
+
"get_import_job_status"
|
|
18348
|
+
]
|
|
18349
|
+
};
|
|
18350
|
+
const startPieInputSchema = {
|
|
18351
|
+
map: z.string().trim().min(1).max(512).optional().describe("Optional level/map path to load before play (e.g. /Game/Maps/MyLevel)."),
|
|
18352
|
+
mode: z.enum(BRIDGE_PIE_MODES).optional().describe("Play-in-Editor mode: 'selected_viewport', 'new_window' (default), or 'standalone'."),
|
|
18353
|
+
netMode: z.enum(BRIDGE_PIE_NET_MODES).optional().describe("Multiplayer net mode: 'standalone', 'listen_server', 'client', or 'dedicated_server'. Omit for single-player editor defaults."),
|
|
18354
|
+
numClients: z.number().int().min(1).max(16).optional().describe(`Number of client windows to launch (1-${String(16)}). With a server net mode, launches 1 server + N-1 clients.`),
|
|
18355
|
+
projectId: projectIdSchema,
|
|
18356
|
+
runUnderOneProcess: z.boolean().optional().describe("Run all multiplayer instances under a single process instead of separate processes.")
|
|
18357
|
+
};
|
|
18358
|
+
const getPieStatusInputSchema = {
|
|
18359
|
+
pieSessionId: z.string().trim().min(1).max(512).optional().describe("Optional pieSessionId returned by start_pie; omit to query the editor current PIE session."),
|
|
18360
|
+
projectId: projectIdSchema
|
|
18361
|
+
};
|
|
18362
|
+
const stopPieInputSchema = {
|
|
18363
|
+
pieSessionId: z.string().trim().min(1).max(512).optional().describe("Optional pieSessionId returned by start_pie; omit to stop the editor current PIE session."),
|
|
18364
|
+
projectId: projectIdSchema
|
|
18365
|
+
};
|
|
18366
|
+
const listLaunchDevicesInputSchema = { projectId: projectIdSchema };
|
|
18367
|
+
const launchOnDeviceInputSchema = {
|
|
18368
|
+
deviceId: z.string().trim().min(1).max(512).describe("Target device id from list_launch_devices (e.g. IOS@MyiPhone, Android@serial)."),
|
|
18369
|
+
map: z.string().trim().min(1).max(512).optional().describe("Optional level/map path to load on the device before play (e.g. /Game/Maps/MyLevel)."),
|
|
18370
|
+
projectId: projectIdSchema
|
|
18371
|
+
};
|
|
18372
|
+
async function startPie(input, dependencies) {
|
|
18373
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18374
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18375
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18376
|
+
const response = await sendBridgeStartPieRequest(createBridgeStartPieRequest(input.mode ?? "new_window", input.map, {
|
|
18377
|
+
netMode: input.netMode,
|
|
18378
|
+
numClients: input.numClients,
|
|
18379
|
+
runUnderOneProcess: input.runUnderOneProcess
|
|
18380
|
+
}), {
|
|
18381
|
+
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18382
|
+
host: "127.0.0.1",
|
|
18383
|
+
port: entry.port,
|
|
18384
|
+
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18385
|
+
});
|
|
18386
|
+
if (!response.ok) throw new Error(`Bridge protocol error (${response.error.code}): ${response.error.message}`);
|
|
18387
|
+
const result = {
|
|
18388
|
+
pieSessionId: response.pieSessionId,
|
|
18389
|
+
projectId: normalizedProjectId,
|
|
18390
|
+
state: response.state
|
|
18391
|
+
};
|
|
18392
|
+
if (response.message !== void 0) result.message = response.message;
|
|
18393
|
+
return result;
|
|
18394
|
+
}
|
|
18395
|
+
async function getPieStatus(input, dependencies) {
|
|
18396
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18397
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18398
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18399
|
+
const response = await sendBridgeGetPieStatusRequest(createBridgeGetPieStatusRequest(input.pieSessionId), {
|
|
18400
|
+
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18401
|
+
host: "127.0.0.1",
|
|
18402
|
+
port: entry.port,
|
|
18403
|
+
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18404
|
+
});
|
|
18405
|
+
if (!response.ok) throw new Error(`Bridge get_pie_status failed (${response.error.code}): ${response.error.message}`);
|
|
18406
|
+
return buildGetPieStatusResult(response, normalizedProjectId);
|
|
18407
|
+
}
|
|
18408
|
+
function buildGetPieStatusResult(response, projectId) {
|
|
18409
|
+
const result = {
|
|
18410
|
+
projectId,
|
|
18411
|
+
state: response.state
|
|
18412
|
+
};
|
|
18413
|
+
if (response.pieSessionId !== void 0) result.pieSessionId = response.pieSessionId;
|
|
18414
|
+
if (response.startedAt !== void 0) result.startedAt = response.startedAt;
|
|
18415
|
+
if (response.errorCount !== void 0) result.errorCount = response.errorCount;
|
|
18416
|
+
if (response.message !== void 0) result.message = response.message;
|
|
18417
|
+
return result;
|
|
18418
|
+
}
|
|
18419
|
+
async function stopPie(input, dependencies) {
|
|
18420
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18421
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18422
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18423
|
+
const response = await sendBridgeStopPieRequest(createBridgeStopPieRequest(input.pieSessionId), {
|
|
18424
|
+
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18425
|
+
host: "127.0.0.1",
|
|
18426
|
+
port: entry.port,
|
|
18427
|
+
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18428
|
+
});
|
|
18429
|
+
if (!response.ok) throw new Error(`Bridge stop_pie failed (${response.error.code}): ${response.error.message}`);
|
|
18430
|
+
const result = {
|
|
18431
|
+
projectId: normalizedProjectId,
|
|
18432
|
+
state: response.state,
|
|
18433
|
+
stopped: response.stopped
|
|
18434
|
+
};
|
|
18435
|
+
if (response.message !== void 0) result.message = response.message;
|
|
18436
|
+
return result;
|
|
18437
|
+
}
|
|
18438
|
+
async function listLaunchDevices(input, dependencies) {
|
|
18439
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18440
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18441
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18442
|
+
const response = await sendBridgeListLaunchDevicesRequest(createBridgeListLaunchDevicesRequest(), {
|
|
18443
|
+
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18444
|
+
host: "127.0.0.1",
|
|
18445
|
+
port: entry.port,
|
|
18446
|
+
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18447
|
+
});
|
|
18448
|
+
if (!response.ok) throw new Error(`Bridge list_launch_devices failed (${response.error.code}): ${response.error.message}`);
|
|
18449
|
+
return {
|
|
18450
|
+
devices: response.devices,
|
|
18451
|
+
projectId: normalizedProjectId
|
|
18452
|
+
};
|
|
18453
|
+
}
|
|
18454
|
+
async function launchOnDevice(input, dependencies) {
|
|
18455
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18456
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18457
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18458
|
+
const response = await sendBridgeLaunchOnDeviceRequest(createBridgeLaunchOnDeviceRequest(input.deviceId, input.map), {
|
|
18459
|
+
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18460
|
+
host: "127.0.0.1",
|
|
18461
|
+
port: entry.port,
|
|
18462
|
+
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18463
|
+
});
|
|
18464
|
+
if (!response.ok) throw new Error(`Bridge launch_on_device failed (${response.error.code}): ${response.error.message}`);
|
|
18465
|
+
const result = {
|
|
18466
|
+
launchSessionId: response.launchSessionId,
|
|
18467
|
+
projectId: normalizedProjectId,
|
|
18468
|
+
state: response.state
|
|
18469
|
+
};
|
|
18470
|
+
if (response.message !== void 0) result.message = response.message;
|
|
18471
|
+
return result;
|
|
18472
|
+
}
|
|
18473
|
+
function registerPieTools(server, dependencies) {
|
|
18474
|
+
server.registerTool("start_pie", {
|
|
18475
|
+
description: "Start a Play-in-Editor session in the registered Unreal editor for a project; play begins on the next editor tick (async). Returns starting/running/unsupported.",
|
|
18476
|
+
inputSchema: startPieInputSchema,
|
|
18477
|
+
title: "Start Play-in-Editor"
|
|
18478
|
+
}, async ({ map, mode, netMode, numClients, projectId, runUnderOneProcess }) => {
|
|
18479
|
+
return toToolSuccess(await startPie({
|
|
18480
|
+
map,
|
|
18481
|
+
mode,
|
|
18482
|
+
netMode,
|
|
18483
|
+
numClients,
|
|
18484
|
+
projectId,
|
|
18485
|
+
runUnderOneProcess
|
|
18486
|
+
}, dependencies));
|
|
18487
|
+
});
|
|
18488
|
+
server.registerTool("get_pie_status", {
|
|
18489
|
+
description: "Report the state of the Play-in-Editor session started by start_pie for a project: starting, running, stopped, or none. Reports running only after PIE has actually begun.",
|
|
18490
|
+
inputSchema: getPieStatusInputSchema,
|
|
18491
|
+
title: "Get Play-in-Editor Status"
|
|
18492
|
+
}, async ({ pieSessionId, projectId }) => {
|
|
18493
|
+
return toToolSuccess(await getPieStatus({
|
|
18494
|
+
pieSessionId,
|
|
18495
|
+
projectId
|
|
18496
|
+
}, dependencies));
|
|
18497
|
+
});
|
|
18498
|
+
server.registerTool("stop_pie", {
|
|
18499
|
+
description: "End the active Play-in-Editor session for a project. Returns stopped=true when a session was ended, or stopped=false (state none) when nothing was playing.",
|
|
18500
|
+
inputSchema: stopPieInputSchema,
|
|
18501
|
+
title: "Stop Play-in-Editor"
|
|
18502
|
+
}, async ({ pieSessionId, projectId }) => {
|
|
18503
|
+
return toToolSuccess(await stopPie({
|
|
18504
|
+
pieSessionId,
|
|
18505
|
+
projectId
|
|
18506
|
+
}, dependencies));
|
|
18507
|
+
});
|
|
18508
|
+
server.registerTool("list_launch_devices", {
|
|
18509
|
+
description: "List the target devices the registered Unreal editor can launch onto (iOS, Android, etc.), with each device id, name, platform, and connected/authorized state. Pick a deviceId for launch_on_device.",
|
|
18510
|
+
inputSchema: listLaunchDevicesInputSchema,
|
|
18511
|
+
title: "List Launch Devices"
|
|
18512
|
+
}, async ({ projectId }) => {
|
|
18513
|
+
return toToolSuccess(await listLaunchDevices({ projectId }, dependencies));
|
|
18514
|
+
});
|
|
18515
|
+
server.registerTool("launch_on_device", {
|
|
18516
|
+
description: "Launch (cook-on-the-fly + deploy, not package) the current project onto a connected target device by deviceId from list_launch_devices. Returns a launchSessionId and starting/unsupported state; deploy proceeds asynchronously.",
|
|
18517
|
+
inputSchema: launchOnDeviceInputSchema,
|
|
18518
|
+
title: "Launch On Device"
|
|
18519
|
+
}, async ({ deviceId, map, projectId }) => {
|
|
18520
|
+
return toToolSuccess(await launchOnDevice({
|
|
18521
|
+
deviceId,
|
|
18522
|
+
map,
|
|
18523
|
+
projectId
|
|
18524
|
+
}, dependencies));
|
|
18525
|
+
});
|
|
18526
|
+
}
|
|
18527
|
+
const pieToolDomain = {
|
|
18528
|
+
domain: "pie",
|
|
18529
|
+
register: (server, dependencies) => {
|
|
18530
|
+
registerPieTools(server, dependencies);
|
|
18531
|
+
registerPieRuntimeTools(server, dependencies);
|
|
18532
|
+
},
|
|
18533
|
+
toolNames: [
|
|
18534
|
+
"start_pie",
|
|
18535
|
+
"get_pie_status",
|
|
18536
|
+
"stop_pie",
|
|
18537
|
+
"list_launch_devices",
|
|
18538
|
+
"launch_on_device",
|
|
18539
|
+
"call_actor_function",
|
|
18540
|
+
"list_pie_worlds",
|
|
18541
|
+
"get_net_stats"
|
|
18542
|
+
]
|
|
18543
|
+
};
|
|
18544
|
+
const WORLD_SELECTOR_DESCRIPTION = "Which world to address: 'editor' (default) is the level open in the editor; 'pie' is a running Play-in-Editor session, whose actors are separate objects reflecting live gameplay state. A 'pie' request with no session running fails rather than falling back to the editor world.";
|
|
18545
|
+
const PIE_INSTANCE_INDEX_DESCRIPTION = "Which Play-in-Editor world to address, as list_pie_worlds reports its index. Omitted means the lowest running instance, which is the server in a listen-server session. Ignored unless world is \"pie\".";
|
|
18546
|
+
const callActorFunctionInputSchema = {
|
|
18547
|
+
actorPath: bridgeCallActorFunctionRequestSchema.shape.actorPath.describe("Full path name of the actor, as list_actors returns it. A path read from the editor world also addresses the same actor in a PIE world."),
|
|
18548
|
+
args: bridgeCallActorFunctionRequestSchema.shape.args.describe("Arguments to pass, each a { name, value } pair. Names are the UFunction parameter names get_class_reflection reports; values use the same ExportText format get_actor_details emits. Omitted parameters keep their zero value."),
|
|
18549
|
+
functionName: bridgeCallActorFunctionRequestSchema.shape.functionName.describe("Name of the BlueprintCallable function to invoke, as get_class_reflection reports it."),
|
|
18550
|
+
pieInstanceIndex: bridgeCallActorFunctionRequestSchema.shape.pieInstanceIndex.describe(PIE_INSTANCE_INDEX_DESCRIPTION),
|
|
18551
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actor."),
|
|
18552
|
+
world: bridgeCallActorFunctionRequestSchema.shape.world.describe(WORLD_SELECTOR_DESCRIPTION)
|
|
18553
|
+
};
|
|
18554
|
+
const listPieWorldsInputSchema = { projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should report its Play-in-Editor worlds.") };
|
|
18555
|
+
const getNetStatsInputSchema = {
|
|
18556
|
+
pieInstanceIndex: bridgeGetNetStatsRequestSchema.shape.pieInstanceIndex.describe("Restrict the report to one PIE world, as list_pie_worlds reports its index. Omitted reports every running world."),
|
|
18557
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should report its network statistics.")
|
|
18558
|
+
};
|
|
18559
|
+
async function callActorFunction(input, dependencies) {
|
|
18560
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18561
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18562
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18563
|
+
const response = await sendBridgeCallActorFunctionRequest(createBridgeCallActorFunctionRequest(input.actorPath, input.functionName, {
|
|
18564
|
+
args: input.args,
|
|
18565
|
+
pieInstanceIndex: input.pieInstanceIndex,
|
|
18566
|
+
world: input.world
|
|
18567
|
+
}), {
|
|
18568
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
18569
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
18570
|
+
port: entry.port,
|
|
18571
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
18572
|
+
});
|
|
18573
|
+
if (!response.ok) throw new Error(`Bridge call_actor_function failed (${response.error.code}): ${response.error.message}`);
|
|
18574
|
+
return {
|
|
18575
|
+
actorPath: response.actorPath,
|
|
18576
|
+
functionName: response.functionName,
|
|
18577
|
+
outputs: response.outputs,
|
|
18578
|
+
projectId: entry.projectId,
|
|
18579
|
+
returnValue: response.returnValue,
|
|
18580
|
+
worldName: response.worldName
|
|
18581
|
+
};
|
|
18582
|
+
}
|
|
18583
|
+
async function listPieWorlds(input, dependencies) {
|
|
18584
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18585
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18586
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18587
|
+
const response = await sendBridgeListPieWorldsRequest(createBridgeListPieWorldsRequest(), {
|
|
18588
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
18589
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
18590
|
+
port: entry.port,
|
|
18591
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
18592
|
+
});
|
|
18593
|
+
if (!response.ok) throw new Error(`Bridge list_pie_worlds failed (${response.error.code}): ${response.error.message}`);
|
|
18594
|
+
return {
|
|
18595
|
+
active: response.active,
|
|
18596
|
+
message: response.message,
|
|
18597
|
+
projectId: entry.projectId,
|
|
18598
|
+
worlds: response.worlds
|
|
18599
|
+
};
|
|
18600
|
+
}
|
|
18601
|
+
async function getNetStats(input, dependencies) {
|
|
18602
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18603
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18604
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18605
|
+
const response = await sendBridgeGetNetStatsRequest(createBridgeGetNetStatsRequest({ pieInstanceIndex: input.pieInstanceIndex }), {
|
|
18606
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
18607
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
18608
|
+
port: entry.port,
|
|
18609
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
18610
|
+
});
|
|
18611
|
+
if (!response.ok) throw new Error(`Bridge get_net_stats failed (${response.error.code}): ${response.error.message}`);
|
|
18612
|
+
return {
|
|
18613
|
+
active: response.active,
|
|
18614
|
+
message: response.message,
|
|
18615
|
+
projectId: entry.projectId,
|
|
18616
|
+
worlds: response.worlds
|
|
18617
|
+
};
|
|
18618
|
+
}
|
|
18619
|
+
function registerPieRuntimeTools(server, dependencies) {
|
|
18620
|
+
server.registerTool("call_actor_function", {
|
|
18621
|
+
description: "Invoke a BlueprintCallable function on one actor and return its return value and any out parameters. Set world to 'pie' to call into a running Play-in-Editor session, where the actor holds live gameplay state rather than its editor defaults. Functions that are not BlueprintCallable, and latent functions that need a calling graph, are rejected with an explicit error.",
|
|
18622
|
+
inputSchema: callActorFunctionInputSchema,
|
|
18623
|
+
title: "Call Actor Function"
|
|
18624
|
+
}, async ({ actorPath, args, functionName, pieInstanceIndex, projectId, world }) => {
|
|
18625
|
+
return toToolSuccess(await callActorFunction({
|
|
18626
|
+
actorPath,
|
|
18627
|
+
args,
|
|
18628
|
+
functionName,
|
|
18629
|
+
pieInstanceIndex,
|
|
18630
|
+
projectId,
|
|
18631
|
+
world
|
|
18632
|
+
}, dependencies));
|
|
18633
|
+
});
|
|
18634
|
+
server.registerTool("list_pie_worlds", {
|
|
18635
|
+
description: "List the worlds a running Play-in-Editor session owns, each with the engine's own instance index, net mode, server flag, map name, player count and actor count. The index is what every world-addressed tool takes as pieInstanceIndex, so this is how a multiplayer session becomes addressable. Reports active=false with a message rather than failing when nothing is playing.",
|
|
18636
|
+
inputSchema: listPieWorldsInputSchema,
|
|
18637
|
+
title: "List PIE Worlds"
|
|
18638
|
+
}, async ({ projectId }) => {
|
|
18639
|
+
return toToolSuccess(await listPieWorlds({ projectId }, dependencies));
|
|
18640
|
+
});
|
|
18641
|
+
server.registerTool("get_net_stats", {
|
|
18642
|
+
description: "Report per-world network statistics for a running Play-in-Editor session: each world's role and replicated actor count, and for every connection its address, ping, packet loss and throughput. Pass pieInstanceIndex to narrow it to one client. A standalone world reports hasNetDriver=false rather than failing.",
|
|
18643
|
+
inputSchema: getNetStatsInputSchema,
|
|
18644
|
+
title: "Get Net Stats"
|
|
18645
|
+
}, async ({ pieInstanceIndex, projectId }) => {
|
|
18646
|
+
return toToolSuccess(await getNetStats({
|
|
18647
|
+
pieInstanceIndex,
|
|
17623
18648
|
projectId
|
|
17624
18649
|
}, dependencies));
|
|
17625
18650
|
});
|
|
17626
18651
|
}
|
|
17627
|
-
const importToolDomain = {
|
|
17628
|
-
domain: "import",
|
|
17629
|
-
register: registerImportTools,
|
|
17630
|
-
toolNames: [
|
|
17631
|
-
"import_asset",
|
|
17632
|
-
"reimport_asset",
|
|
17633
|
-
"set_import_settings",
|
|
17634
|
-
"get_import_job_status"
|
|
17635
|
-
]
|
|
17636
|
-
};
|
|
17637
18652
|
//#endregion
|
|
17638
18653
|
//#region src/tools/input.ts
|
|
17639
18654
|
const createInputActionInputSchema = {
|
|
@@ -17708,13 +18723,67 @@ function registerInputTools(server, dependencies) {
|
|
|
17708
18723
|
}
|
|
17709
18724
|
const inputToolDomain = {
|
|
17710
18725
|
domain: "input",
|
|
17711
|
-
register:
|
|
18726
|
+
register: (server, dependencies) => {
|
|
18727
|
+
registerInputTools(server, dependencies);
|
|
18728
|
+
registerInputInjectionTools(server, dependencies);
|
|
18729
|
+
},
|
|
17712
18730
|
toolNames: [
|
|
17713
18731
|
"create_input_action",
|
|
17714
18732
|
"create_input_mapping_context",
|
|
17715
|
-
"add_input_mapping"
|
|
18733
|
+
"add_input_mapping",
|
|
18734
|
+
"inject_input_action"
|
|
17716
18735
|
]
|
|
17717
18736
|
};
|
|
18737
|
+
const injectInputActionInputSchema = {
|
|
18738
|
+
actionPath: bridgeInjectInputActionRequestSchema.shape.actionPath.describe("Path of the Enhanced Input Action asset to inject (e.g. /Game/Input/IA_Jump)."),
|
|
18739
|
+
durationSeconds: bridgeInjectInputActionRequestSchema.shape.durationSeconds.describe(`Hold the action for this many seconds by re-injecting it every frame (0-${String(60)}). Omitted injects for a single frame, which is enough for a pressed trigger but not for a held one.`),
|
|
18740
|
+
pieInstanceIndex: bridgeInjectInputActionRequestSchema.shape.pieInstanceIndex.describe(PIE_INSTANCE_INDEX_DESCRIPTION),
|
|
18741
|
+
playerIndex: bridgeInjectInputActionRequestSchema.shape.playerIndex.describe("Which local player in that world receives the input (default 0). Enhanced Input binds mapping contexts per player, so a split-screen or multi-window session has one target per window."),
|
|
18742
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor is running the Play-in-Editor session."),
|
|
18743
|
+
value: bridgeInjectInputActionRequestSchema.shape.value.describe("The value to inject, always as a vector: a digital action reads x != 0 as pressed, an Axis1D reads x, an Axis2D reads x and y. The response's valueType reports how the action actually read it.")
|
|
18744
|
+
};
|
|
18745
|
+
async function injectInputAction(input, dependencies) {
|
|
18746
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18747
|
+
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18748
|
+
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18749
|
+
const response = await sendBridgeInjectInputActionRequest(createBridgeInjectInputActionRequest(input.actionPath, {
|
|
18750
|
+
durationSeconds: input.durationSeconds,
|
|
18751
|
+
pieInstanceIndex: input.pieInstanceIndex,
|
|
18752
|
+
playerIndex: input.playerIndex,
|
|
18753
|
+
value: input.value
|
|
18754
|
+
}), {
|
|
18755
|
+
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
18756
|
+
host: BRIDGE_LOOPBACK_HOST,
|
|
18757
|
+
port: entry.port,
|
|
18758
|
+
readTimeoutMs: deriveEditorWorkTimeoutMs(dependencies.pingTimeoutMs)
|
|
18759
|
+
});
|
|
18760
|
+
if (!response.ok) throw new Error(`Bridge inject_input_action failed (${response.error.code}): ${response.error.message}`);
|
|
18761
|
+
return {
|
|
18762
|
+
actionPath: response.actionPath,
|
|
18763
|
+
durationSeconds: response.durationSeconds,
|
|
18764
|
+
pieInstanceIndex: response.pieInstanceIndex,
|
|
18765
|
+
playerIndex: response.playerIndex,
|
|
18766
|
+
projectId: entry.projectId,
|
|
18767
|
+
valueType: response.valueType,
|
|
18768
|
+
worldName: response.worldName
|
|
18769
|
+
};
|
|
18770
|
+
}
|
|
18771
|
+
function registerInputInjectionTools(server, dependencies) {
|
|
18772
|
+
server.registerTool("inject_input_action", {
|
|
18773
|
+
description: "Inject a value for one Enhanced Input Action into a running Play-in-Editor session, as if the player had triggered it. Pass durationSeconds to hold the action, which re-injects it every frame until it elapses. Requires a running PIE session and a local player at playerIndex; both are reported as explicit errors rather than silently doing nothing.",
|
|
18774
|
+
inputSchema: injectInputActionInputSchema,
|
|
18775
|
+
title: "Inject Input Action"
|
|
18776
|
+
}, async ({ actionPath, durationSeconds, pieInstanceIndex, playerIndex, projectId, value }) => {
|
|
18777
|
+
return toToolSuccess(await injectInputAction({
|
|
18778
|
+
actionPath,
|
|
18779
|
+
durationSeconds,
|
|
18780
|
+
pieInstanceIndex,
|
|
18781
|
+
playerIndex,
|
|
18782
|
+
projectId,
|
|
18783
|
+
value
|
|
18784
|
+
}, dependencies));
|
|
18785
|
+
});
|
|
18786
|
+
}
|
|
17718
18787
|
//#endregion
|
|
17719
18788
|
//#region src/mcpProgress.ts
|
|
17720
18789
|
function createProgressReporter(extra, logger) {
|
|
@@ -18367,194 +19436,6 @@ const packagingToolDomain = {
|
|
|
18367
19436
|
"cancel_package_job"
|
|
18368
19437
|
]
|
|
18369
19438
|
};
|
|
18370
|
-
const startPieInputSchema = {
|
|
18371
|
-
map: z.string().trim().min(1).max(512).optional().describe("Optional level/map path to load before play (e.g. /Game/Maps/MyLevel)."),
|
|
18372
|
-
mode: z.enum(BRIDGE_PIE_MODES).optional().describe("Play-in-Editor mode: 'selected_viewport', 'new_window' (default), or 'standalone'."),
|
|
18373
|
-
netMode: z.enum(BRIDGE_PIE_NET_MODES).optional().describe("Multiplayer net mode: 'standalone', 'listen_server', 'client', or 'dedicated_server'. Omit for single-player editor defaults."),
|
|
18374
|
-
numClients: z.number().int().min(1).max(16).optional().describe(`Number of client windows to launch (1-${String(16)}). With a server net mode, launches 1 server + N-1 clients.`),
|
|
18375
|
-
projectId: projectIdSchema,
|
|
18376
|
-
runUnderOneProcess: z.boolean().optional().describe("Run all multiplayer instances under a single process instead of separate processes.")
|
|
18377
|
-
};
|
|
18378
|
-
const getPieStatusInputSchema = {
|
|
18379
|
-
pieSessionId: z.string().trim().min(1).max(512).optional().describe("Optional pieSessionId returned by start_pie; omit to query the editor current PIE session."),
|
|
18380
|
-
projectId: projectIdSchema
|
|
18381
|
-
};
|
|
18382
|
-
const stopPieInputSchema = {
|
|
18383
|
-
pieSessionId: z.string().trim().min(1).max(512).optional().describe("Optional pieSessionId returned by start_pie; omit to stop the editor current PIE session."),
|
|
18384
|
-
projectId: projectIdSchema
|
|
18385
|
-
};
|
|
18386
|
-
const listLaunchDevicesInputSchema = { projectId: projectIdSchema };
|
|
18387
|
-
const launchOnDeviceInputSchema = {
|
|
18388
|
-
deviceId: z.string().trim().min(1).max(512).describe("Target device id from list_launch_devices (e.g. IOS@MyiPhone, Android@serial)."),
|
|
18389
|
-
map: z.string().trim().min(1).max(512).optional().describe("Optional level/map path to load on the device before play (e.g. /Game/Maps/MyLevel)."),
|
|
18390
|
-
projectId: projectIdSchema
|
|
18391
|
-
};
|
|
18392
|
-
async function startPie(input, dependencies) {
|
|
18393
|
-
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18394
|
-
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18395
|
-
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18396
|
-
const response = await sendBridgeStartPieRequest(createBridgeStartPieRequest(input.mode ?? "new_window", input.map, {
|
|
18397
|
-
netMode: input.netMode,
|
|
18398
|
-
numClients: input.numClients,
|
|
18399
|
-
runUnderOneProcess: input.runUnderOneProcess
|
|
18400
|
-
}), {
|
|
18401
|
-
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18402
|
-
host: "127.0.0.1",
|
|
18403
|
-
port: entry.port,
|
|
18404
|
-
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18405
|
-
});
|
|
18406
|
-
if (!response.ok) throw new Error(`Bridge protocol error (${response.error.code}): ${response.error.message}`);
|
|
18407
|
-
const result = {
|
|
18408
|
-
pieSessionId: response.pieSessionId,
|
|
18409
|
-
projectId: normalizedProjectId,
|
|
18410
|
-
state: response.state
|
|
18411
|
-
};
|
|
18412
|
-
if (response.message !== void 0) result.message = response.message;
|
|
18413
|
-
return result;
|
|
18414
|
-
}
|
|
18415
|
-
async function getPieStatus(input, dependencies) {
|
|
18416
|
-
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18417
|
-
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18418
|
-
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18419
|
-
const response = await sendBridgeGetPieStatusRequest(createBridgeGetPieStatusRequest(input.pieSessionId), {
|
|
18420
|
-
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18421
|
-
host: "127.0.0.1",
|
|
18422
|
-
port: entry.port,
|
|
18423
|
-
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18424
|
-
});
|
|
18425
|
-
if (!response.ok) throw new Error(`Bridge get_pie_status failed (${response.error.code}): ${response.error.message}`);
|
|
18426
|
-
return buildGetPieStatusResult(response, normalizedProjectId);
|
|
18427
|
-
}
|
|
18428
|
-
function buildGetPieStatusResult(response, projectId) {
|
|
18429
|
-
const result = {
|
|
18430
|
-
projectId,
|
|
18431
|
-
state: response.state
|
|
18432
|
-
};
|
|
18433
|
-
if (response.pieSessionId !== void 0) result.pieSessionId = response.pieSessionId;
|
|
18434
|
-
if (response.startedAt !== void 0) result.startedAt = response.startedAt;
|
|
18435
|
-
if (response.errorCount !== void 0) result.errorCount = response.errorCount;
|
|
18436
|
-
if (response.message !== void 0) result.message = response.message;
|
|
18437
|
-
return result;
|
|
18438
|
-
}
|
|
18439
|
-
async function stopPie(input, dependencies) {
|
|
18440
|
-
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18441
|
-
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18442
|
-
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18443
|
-
const response = await sendBridgeStopPieRequest(createBridgeStopPieRequest(input.pieSessionId), {
|
|
18444
|
-
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18445
|
-
host: "127.0.0.1",
|
|
18446
|
-
port: entry.port,
|
|
18447
|
-
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18448
|
-
});
|
|
18449
|
-
if (!response.ok) throw new Error(`Bridge stop_pie failed (${response.error.code}): ${response.error.message}`);
|
|
18450
|
-
const result = {
|
|
18451
|
-
projectId: normalizedProjectId,
|
|
18452
|
-
state: response.state,
|
|
18453
|
-
stopped: response.stopped
|
|
18454
|
-
};
|
|
18455
|
-
if (response.message !== void 0) result.message = response.message;
|
|
18456
|
-
return result;
|
|
18457
|
-
}
|
|
18458
|
-
async function listLaunchDevices(input, dependencies) {
|
|
18459
|
-
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18460
|
-
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18461
|
-
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18462
|
-
const response = await sendBridgeListLaunchDevicesRequest(createBridgeListLaunchDevicesRequest(), {
|
|
18463
|
-
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18464
|
-
host: "127.0.0.1",
|
|
18465
|
-
port: entry.port,
|
|
18466
|
-
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18467
|
-
});
|
|
18468
|
-
if (!response.ok) throw new Error(`Bridge list_launch_devices failed (${response.error.code}): ${response.error.message}`);
|
|
18469
|
-
return {
|
|
18470
|
-
devices: response.devices,
|
|
18471
|
-
projectId: normalizedProjectId
|
|
18472
|
-
};
|
|
18473
|
-
}
|
|
18474
|
-
async function launchOnDevice(input, dependencies) {
|
|
18475
|
-
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
18476
|
-
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
18477
|
-
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
18478
|
-
const response = await sendBridgeLaunchOnDeviceRequest(createBridgeLaunchOnDeviceRequest(input.deviceId, input.map), {
|
|
18479
|
-
connectTimeoutMs: dependencies.pingTimeoutMs,
|
|
18480
|
-
host: "127.0.0.1",
|
|
18481
|
-
port: entry.port,
|
|
18482
|
-
readTimeoutMs: dependencies.pingTimeoutMs
|
|
18483
|
-
});
|
|
18484
|
-
if (!response.ok) throw new Error(`Bridge launch_on_device failed (${response.error.code}): ${response.error.message}`);
|
|
18485
|
-
const result = {
|
|
18486
|
-
launchSessionId: response.launchSessionId,
|
|
18487
|
-
projectId: normalizedProjectId,
|
|
18488
|
-
state: response.state
|
|
18489
|
-
};
|
|
18490
|
-
if (response.message !== void 0) result.message = response.message;
|
|
18491
|
-
return result;
|
|
18492
|
-
}
|
|
18493
|
-
function registerPieTools(server, dependencies) {
|
|
18494
|
-
server.registerTool("start_pie", {
|
|
18495
|
-
description: "Start a Play-in-Editor session in the registered Unreal editor for a project; play begins on the next editor tick (async). Returns starting/running/unsupported.",
|
|
18496
|
-
inputSchema: startPieInputSchema,
|
|
18497
|
-
title: "Start Play-in-Editor"
|
|
18498
|
-
}, async ({ map, mode, netMode, numClients, projectId, runUnderOneProcess }) => {
|
|
18499
|
-
return toToolSuccess(await startPie({
|
|
18500
|
-
map,
|
|
18501
|
-
mode,
|
|
18502
|
-
netMode,
|
|
18503
|
-
numClients,
|
|
18504
|
-
projectId,
|
|
18505
|
-
runUnderOneProcess
|
|
18506
|
-
}, dependencies));
|
|
18507
|
-
});
|
|
18508
|
-
server.registerTool("get_pie_status", {
|
|
18509
|
-
description: "Report the state of the Play-in-Editor session started by start_pie for a project: starting, running, stopped, or none. Reports running only after PIE has actually begun.",
|
|
18510
|
-
inputSchema: getPieStatusInputSchema,
|
|
18511
|
-
title: "Get Play-in-Editor Status"
|
|
18512
|
-
}, async ({ pieSessionId, projectId }) => {
|
|
18513
|
-
return toToolSuccess(await getPieStatus({
|
|
18514
|
-
pieSessionId,
|
|
18515
|
-
projectId
|
|
18516
|
-
}, dependencies));
|
|
18517
|
-
});
|
|
18518
|
-
server.registerTool("stop_pie", {
|
|
18519
|
-
description: "End the active Play-in-Editor session for a project. Returns stopped=true when a session was ended, or stopped=false (state none) when nothing was playing.",
|
|
18520
|
-
inputSchema: stopPieInputSchema,
|
|
18521
|
-
title: "Stop Play-in-Editor"
|
|
18522
|
-
}, async ({ pieSessionId, projectId }) => {
|
|
18523
|
-
return toToolSuccess(await stopPie({
|
|
18524
|
-
pieSessionId,
|
|
18525
|
-
projectId
|
|
18526
|
-
}, dependencies));
|
|
18527
|
-
});
|
|
18528
|
-
server.registerTool("list_launch_devices", {
|
|
18529
|
-
description: "List the target devices the registered Unreal editor can launch onto (iOS, Android, etc.), with each device id, name, platform, and connected/authorized state. Pick a deviceId for launch_on_device.",
|
|
18530
|
-
inputSchema: listLaunchDevicesInputSchema,
|
|
18531
|
-
title: "List Launch Devices"
|
|
18532
|
-
}, async ({ projectId }) => {
|
|
18533
|
-
return toToolSuccess(await listLaunchDevices({ projectId }, dependencies));
|
|
18534
|
-
});
|
|
18535
|
-
server.registerTool("launch_on_device", {
|
|
18536
|
-
description: "Launch (cook-on-the-fly + deploy, not package) the current project onto a connected target device by deviceId from list_launch_devices. Returns a launchSessionId and starting/unsupported state; deploy proceeds asynchronously.",
|
|
18537
|
-
inputSchema: launchOnDeviceInputSchema,
|
|
18538
|
-
title: "Launch On Device"
|
|
18539
|
-
}, async ({ deviceId, map, projectId }) => {
|
|
18540
|
-
return toToolSuccess(await launchOnDevice({
|
|
18541
|
-
deviceId,
|
|
18542
|
-
map,
|
|
18543
|
-
projectId
|
|
18544
|
-
}, dependencies));
|
|
18545
|
-
});
|
|
18546
|
-
}
|
|
18547
|
-
const pieToolDomain = {
|
|
18548
|
-
domain: "pie",
|
|
18549
|
-
register: registerPieTools,
|
|
18550
|
-
toolNames: [
|
|
18551
|
-
"start_pie",
|
|
18552
|
-
"get_pie_status",
|
|
18553
|
-
"stop_pie",
|
|
18554
|
-
"list_launch_devices",
|
|
18555
|
-
"launch_on_device"
|
|
18556
|
-
]
|
|
18557
|
-
};
|
|
18558
19439
|
//#endregion
|
|
18559
19440
|
//#region src/tools/render.ts
|
|
18560
19441
|
const renderSequenceInputSchema = {
|
|
@@ -19130,16 +20011,20 @@ const listActorsInputSchema = {
|
|
|
19130
20011
|
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."),
|
|
19131
20012
|
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."),
|
|
19132
20013
|
nameFilter: bridgeListActorsRequestSchema.shape.nameFilter.describe("Optional case-insensitive substring matched against each actor label and path."),
|
|
20014
|
+
pieInstanceIndex: bridgeListActorsRequestSchema.shape.pieInstanceIndex.describe(PIE_INSTANCE_INDEX_DESCRIPTION),
|
|
19133
20015
|
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should list its actors."),
|
|
19134
|
-
tag: bridgeListActorsRequestSchema.shape.tag.describe("Optional exact-match actor tag (AActor::Tags) to filter by.")
|
|
20016
|
+
tag: bridgeListActorsRequestSchema.shape.tag.describe("Optional exact-match actor tag (AActor::Tags) to filter by."),
|
|
20017
|
+
world: bridgeListActorsRequestSchema.shape.world.describe(WORLD_SELECTOR_DESCRIPTION)
|
|
19135
20018
|
};
|
|
19136
20019
|
const getActorDetailsInputSchema = {
|
|
19137
20020
|
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)."),
|
|
19138
20021
|
componentCursor: bridgeGetActorDetailsRequestSchema.shape.componentCursor.describe("Offset into the component list (default 0). Pass the previous response nextComponentCursor to fetch the next page."),
|
|
19139
20022
|
includeInherited: bridgeGetActorDetailsRequestSchema.shape.includeInherited.describe("Whether to include properties inherited from parent classes (default false). Inherited properties are the bulk of any AActor subclass."),
|
|
19140
20023
|
maxResults: bridgeGetActorDetailsRequestSchema.shape.maxResults.default(25).describe("Maximum entries returned per page for each list (1-200, default 25)."),
|
|
20024
|
+
pieInstanceIndex: bridgeGetActorDetailsRequestSchema.shape.pieInstanceIndex.describe(PIE_INSTANCE_INDEX_DESCRIPTION),
|
|
19141
20025
|
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actor."),
|
|
19142
|
-
propertyCursor: bridgeGetActorDetailsRequestSchema.shape.propertyCursor.describe("Offset into the property list (default 0). Pass the previous response nextPropertyCursor to fetch the next page.")
|
|
20026
|
+
propertyCursor: bridgeGetActorDetailsRequestSchema.shape.propertyCursor.describe("Offset into the property list (default 0). Pass the previous response nextPropertyCursor to fetch the next page."),
|
|
20027
|
+
world: bridgeGetActorDetailsRequestSchema.shape.world.describe(WORLD_SELECTOR_DESCRIPTION)
|
|
19143
20028
|
};
|
|
19144
20029
|
const getCurrentLevelInputSchema = { projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should report its loaded level.") };
|
|
19145
20030
|
const spawnActorInputSchema = {
|
|
@@ -19159,8 +20044,10 @@ const setActorTransformInputSchema = {
|
|
|
19159
20044
|
};
|
|
19160
20045
|
const setActorPropertyInputSchema = {
|
|
19161
20046
|
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)."),
|
|
20047
|
+
pieInstanceIndex: bridgeSetActorPropertyRequestSchema.shape.pieInstanceIndex.describe(PIE_INSTANCE_INDEX_DESCRIPTION),
|
|
19162
20048
|
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor holds the actors."),
|
|
19163
|
-
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.")
|
|
20049
|
+
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."),
|
|
20050
|
+
world: bridgeSetActorPropertyRequestSchema.shape.world.describe(WORLD_SELECTOR_DESCRIPTION)
|
|
19164
20051
|
};
|
|
19165
20052
|
const selectActorsInputSchema = {
|
|
19166
20053
|
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."),
|
|
@@ -19190,7 +20077,9 @@ async function listActors(input, dependencies) {
|
|
|
19190
20077
|
levelName: input.levelName,
|
|
19191
20078
|
maxResults: input.maxResults,
|
|
19192
20079
|
nameFilter: input.nameFilter,
|
|
19193
|
-
|
|
20080
|
+
pieInstanceIndex: input.pieInstanceIndex,
|
|
20081
|
+
tag: input.tag,
|
|
20082
|
+
world: input.world
|
|
19194
20083
|
}), {
|
|
19195
20084
|
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
19196
20085
|
host: "127.0.0.1",
|
|
@@ -19215,7 +20104,9 @@ async function getActorDetails(input, dependencies) {
|
|
|
19215
20104
|
componentCursor: input.componentCursor,
|
|
19216
20105
|
includeInherited: input.includeInherited,
|
|
19217
20106
|
maxResults: input.maxResults,
|
|
19218
|
-
|
|
20107
|
+
pieInstanceIndex: input.pieInstanceIndex,
|
|
20108
|
+
propertyCursor: input.propertyCursor,
|
|
20109
|
+
world: input.world
|
|
19219
20110
|
}), {
|
|
19220
20111
|
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
19221
20112
|
host: "127.0.0.1",
|
|
@@ -19333,7 +20224,11 @@ async function setActorProperty(input, dependencies) {
|
|
|
19333
20224
|
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
19334
20225
|
const entry = dependencies.registry.getProject(normalizedProjectId);
|
|
19335
20226
|
if (!entry) throw new Error(`No registered Unreal engine was found for projectId '${normalizedProjectId}'.`);
|
|
19336
|
-
const response = await sendBridgeSetActorPropertyRequest(createBridgeSetActorPropertyRequest(input.properties, {
|
|
20227
|
+
const response = await sendBridgeSetActorPropertyRequest(createBridgeSetActorPropertyRequest(input.properties, {
|
|
20228
|
+
dryRun: input.dryRun,
|
|
20229
|
+
pieInstanceIndex: input.pieInstanceIndex,
|
|
20230
|
+
world: input.world
|
|
20231
|
+
}), {
|
|
19337
20232
|
connectTimeoutMs: deriveBridgeConnectTimeoutMs$1(dependencies.pingTimeoutMs),
|
|
19338
20233
|
host: "127.0.0.1",
|
|
19339
20234
|
port: entry.port,
|
|
@@ -19525,29 +20420,33 @@ function registerLevelTools(server, dependencies) {
|
|
|
19525
20420
|
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.",
|
|
19526
20421
|
inputSchema: listActorsInputSchema,
|
|
19527
20422
|
title: "List Actors"
|
|
19528
|
-
}, async ({ classNames, cursor, levelName, maxResults, nameFilter, projectId, tag }) => {
|
|
20423
|
+
}, async ({ classNames, cursor, levelName, maxResults, nameFilter, pieInstanceIndex, projectId, tag, world }) => {
|
|
19529
20424
|
return toToolSuccess(await listActors({
|
|
19530
20425
|
classNames,
|
|
19531
20426
|
cursor,
|
|
19532
20427
|
levelName,
|
|
19533
20428
|
maxResults,
|
|
19534
20429
|
nameFilter,
|
|
20430
|
+
pieInstanceIndex,
|
|
19535
20431
|
projectId,
|
|
19536
|
-
tag
|
|
20432
|
+
tag,
|
|
20433
|
+
world
|
|
19537
20434
|
}, dependencies));
|
|
19538
20435
|
});
|
|
19539
20436
|
server.registerTool("get_actor_details", {
|
|
19540
20437
|
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.",
|
|
19541
20438
|
inputSchema: getActorDetailsInputSchema,
|
|
19542
20439
|
title: "Get Actor Details"
|
|
19543
|
-
}, async ({ actorPath, componentCursor, includeInherited, maxResults, projectId, propertyCursor }) => {
|
|
20440
|
+
}, async ({ actorPath, componentCursor, includeInherited, maxResults, pieInstanceIndex, projectId, propertyCursor, world }) => {
|
|
19544
20441
|
return toToolSuccess(await getActorDetails({
|
|
19545
20442
|
actorPath,
|
|
19546
20443
|
componentCursor,
|
|
19547
20444
|
includeInherited,
|
|
19548
20445
|
maxResults,
|
|
20446
|
+
pieInstanceIndex,
|
|
19549
20447
|
projectId,
|
|
19550
|
-
propertyCursor
|
|
20448
|
+
propertyCursor,
|
|
20449
|
+
world
|
|
19551
20450
|
}, dependencies));
|
|
19552
20451
|
});
|
|
19553
20452
|
server.registerTool("get_current_level", {
|
|
@@ -19594,11 +20493,13 @@ function registerLevelTools(server, dependencies) {
|
|
|
19594
20493
|
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.",
|
|
19595
20494
|
inputSchema: setActorPropertyInputSchema,
|
|
19596
20495
|
title: "Set Actor Property"
|
|
19597
|
-
}, async ({ dryRun, projectId, properties }) => {
|
|
20496
|
+
}, async ({ dryRun, pieInstanceIndex, projectId, properties, world }) => {
|
|
19598
20497
|
return toToolSuccess(await setActorProperty({
|
|
19599
20498
|
dryRun,
|
|
20499
|
+
pieInstanceIndex,
|
|
19600
20500
|
projectId,
|
|
19601
|
-
properties
|
|
20501
|
+
properties,
|
|
20502
|
+
world
|
|
19602
20503
|
}, dependencies));
|
|
19603
20504
|
});
|
|
19604
20505
|
server.registerTool("select_actors", {
|
|
@@ -21514,15 +22415,150 @@ function registerViewportTools(server, dependencies) {
|
|
|
21514
22415
|
}
|
|
21515
22416
|
const viewportToolDomain = {
|
|
21516
22417
|
domain: "viewport",
|
|
21517
|
-
register:
|
|
22418
|
+
register: (server, dependencies) => {
|
|
22419
|
+
registerViewportTools(server, dependencies);
|
|
22420
|
+
registerViewportBaselineTools(server, dependencies);
|
|
22421
|
+
},
|
|
21518
22422
|
toolNames: [
|
|
21519
22423
|
"set_viewport_camera",
|
|
21520
22424
|
"focus_actors",
|
|
21521
22425
|
"set_view_mode",
|
|
21522
22426
|
"toggle_show_flags",
|
|
21523
|
-
"high_res_screenshot"
|
|
22427
|
+
"high_res_screenshot",
|
|
22428
|
+
"compare_viewport_baseline"
|
|
21524
22429
|
]
|
|
21525
22430
|
};
|
|
22431
|
+
const VIEWPORT_BASELINE_DEFAULT_MAX_MISMATCH_RATIO = .02;
|
|
22432
|
+
const compareViewportBaselineInputSchema = {
|
|
22433
|
+
baselineDir: z.string().trim().min(1).max(1024).optional().describe("Directory holding the baseline images. Defaults to <home>/.uemcp/baselines/<projectId>, so a project accumulates its own set without any setup."),
|
|
22434
|
+
baselineName: z.string().trim().min(1).max(128).regex(/^[A-Za-z0-9_-]+$/).describe("Name of the baseline to compare against, without an extension. Letters, digits, underscore and hyphen only, since it becomes a file name."),
|
|
22435
|
+
maxMismatchRatio: z.number().min(0).max(1).default(VIEWPORT_BASELINE_DEFAULT_MAX_MISMATCH_RATIO).describe(`Fraction of differing pixels tolerated before the comparison fails (0-1, default ${String(VIEWPORT_BASELINE_DEFAULT_MAX_MISMATCH_RATIO)}). The default absorbs the renderer's own frame-to-frame jitter; pass 0 to demand an exact match.`),
|
|
22436
|
+
pixelTolerance: z.number().int().min(0).max(255).default(16).describe(`Per-channel difference a pixel may have before it counts as differing (0-255, default ${String(16)}). Raise this rather than maxMismatchRatio to absorb anti-aliasing and dithering; pass 0 to compare exactly.`),
|
|
22437
|
+
projectId: projectIdSchema.describe("Canonical Unreal ProjectID whose registered editor should capture a frame."),
|
|
22438
|
+
updateBaseline: z.boolean().default(false).describe("Overwrite the baseline with this capture instead of comparing against it. Use after an intended visual change."),
|
|
22439
|
+
writeDiffImage: z.boolean().default(true).describe("Write a diff image next to the baseline when pixels differ, marking every differing pixel in red over a dimmed copy of the capture.")
|
|
22440
|
+
};
|
|
22441
|
+
function comparePngs(capture, baseline, pixelTolerance) {
|
|
22442
|
+
const diff = new PNG({
|
|
22443
|
+
height: capture.height,
|
|
22444
|
+
width: capture.width
|
|
22445
|
+
});
|
|
22446
|
+
const captureData = capture.data;
|
|
22447
|
+
const baselineData = baseline.data;
|
|
22448
|
+
const diffData = diff.data;
|
|
22449
|
+
let differingPixels = 0;
|
|
22450
|
+
for (let index = 0; index < captureData.length; index += 4) {
|
|
22451
|
+
let differs = false;
|
|
22452
|
+
for (let channel = 0; channel < 4; channel += 1) {
|
|
22453
|
+
const captureChannel = captureData[index + channel] ?? 0;
|
|
22454
|
+
const baselineChannel = baselineData[index + channel] ?? 0;
|
|
22455
|
+
if (Math.abs(captureChannel - baselineChannel) > pixelTolerance) {
|
|
22456
|
+
differs = true;
|
|
22457
|
+
break;
|
|
22458
|
+
}
|
|
22459
|
+
}
|
|
22460
|
+
if (differs) {
|
|
22461
|
+
differingPixels += 1;
|
|
22462
|
+
diffData[index] = 255;
|
|
22463
|
+
diffData[index + 1] = 0;
|
|
22464
|
+
diffData[index + 2] = 0;
|
|
22465
|
+
diffData[index + 3] = 255;
|
|
22466
|
+
continue;
|
|
22467
|
+
}
|
|
22468
|
+
const red = captureData[index] ?? 0;
|
|
22469
|
+
const green = captureData[index + 1] ?? 0;
|
|
22470
|
+
const blue = captureData[index + 2] ?? 0;
|
|
22471
|
+
const grey = Math.round((red + green + blue) / 3 * .25);
|
|
22472
|
+
diffData[index] = grey;
|
|
22473
|
+
diffData[index + 1] = grey;
|
|
22474
|
+
diffData[index + 2] = grey;
|
|
22475
|
+
diffData[index + 3] = 255;
|
|
22476
|
+
}
|
|
22477
|
+
return {
|
|
22478
|
+
diff,
|
|
22479
|
+
differingPixels
|
|
22480
|
+
};
|
|
22481
|
+
}
|
|
22482
|
+
async function readPng(filePath) {
|
|
22483
|
+
return PNG.sync.read(await readFile(filePath));
|
|
22484
|
+
}
|
|
22485
|
+
async function compareViewportBaseline(input, dependencies) {
|
|
22486
|
+
const normalizedProjectId = projectIdSchema.parse(input.projectId);
|
|
22487
|
+
const capture = await captureViewport({ projectId: normalizedProjectId }, dependencies);
|
|
22488
|
+
const pixelTolerance = input.pixelTolerance ?? 16;
|
|
22489
|
+
const maxMismatchRatio = input.maxMismatchRatio ?? .02;
|
|
22490
|
+
const baselineDir = input.baselineDir ?? join(homedir(), ".uemcp", "baselines", normalizedProjectId);
|
|
22491
|
+
const baselinePath = join(baselineDir, `${input.baselineName}.png`);
|
|
22492
|
+
const totalPixels = capture.width * capture.height;
|
|
22493
|
+
const common = {
|
|
22494
|
+
baselinePath,
|
|
22495
|
+
capturePath: capture.path,
|
|
22496
|
+
height: capture.height,
|
|
22497
|
+
maxMismatchRatio,
|
|
22498
|
+
pixelTolerance,
|
|
22499
|
+
projectId: normalizedProjectId,
|
|
22500
|
+
totalPixels,
|
|
22501
|
+
width: capture.width
|
|
22502
|
+
};
|
|
22503
|
+
const baselineExists = existsSync(baselinePath);
|
|
22504
|
+
if (!baselineExists || input.updateBaseline === true) {
|
|
22505
|
+
await mkdir(baselineDir, { recursive: true });
|
|
22506
|
+
await copyFile(capture.path, baselinePath);
|
|
22507
|
+
return {
|
|
22508
|
+
...common,
|
|
22509
|
+
differingPixels: 0,
|
|
22510
|
+
matched: true,
|
|
22511
|
+
mismatchRatio: 0,
|
|
22512
|
+
state: baselineExists ? "baseline_updated" : "baseline_created"
|
|
22513
|
+
};
|
|
22514
|
+
}
|
|
22515
|
+
const [captureImage, baselineImage] = await Promise.all([readPng(capture.path), readPng(baselinePath)]);
|
|
22516
|
+
if (captureImage.width !== baselineImage.width || captureImage.height !== baselineImage.height) return {
|
|
22517
|
+
...common,
|
|
22518
|
+
baselineHeight: baselineImage.height,
|
|
22519
|
+
baselineWidth: baselineImage.width,
|
|
22520
|
+
differingPixels: totalPixels,
|
|
22521
|
+
matched: false,
|
|
22522
|
+
mismatchRatio: 1,
|
|
22523
|
+
state: "size_mismatch"
|
|
22524
|
+
};
|
|
22525
|
+
const { diff, differingPixels } = comparePngs(captureImage, baselineImage, pixelTolerance);
|
|
22526
|
+
const mismatchRatio = totalPixels === 0 ? 0 : differingPixels / totalPixels;
|
|
22527
|
+
const matched = mismatchRatio <= maxMismatchRatio;
|
|
22528
|
+
let diffPath;
|
|
22529
|
+
if (!matched && input.writeDiffImage !== false) {
|
|
22530
|
+
diffPath = join(baselineDir, `${input.baselineName}.diff.png`);
|
|
22531
|
+
await mkdir(baselineDir, { recursive: true });
|
|
22532
|
+
await writeFile(diffPath, PNG.sync.write(diff));
|
|
22533
|
+
}
|
|
22534
|
+
return {
|
|
22535
|
+
...common,
|
|
22536
|
+
baselineHeight: baselineImage.height,
|
|
22537
|
+
baselineWidth: baselineImage.width,
|
|
22538
|
+
diffPath,
|
|
22539
|
+
differingPixels,
|
|
22540
|
+
matched,
|
|
22541
|
+
mismatchRatio,
|
|
22542
|
+
state: matched ? "matched" : "mismatched"
|
|
22543
|
+
};
|
|
22544
|
+
}
|
|
22545
|
+
function registerViewportBaselineTools(server, dependencies) {
|
|
22546
|
+
server.registerTool("compare_viewport_baseline", {
|
|
22547
|
+
description: "Capture the editor viewport and compare it against a stored baseline image, returning the fraction of differing pixels and writing a diff image that marks them in red. The first call for a baselineName stores the capture as the baseline; pass updateBaseline: true to replace it after an intended visual change. A capture whose size no longer matches the baseline is reported as size_mismatch rather than failing. The default tolerances absorb the frame-to-frame jitter a live viewport renders anyway, so a mismatch means the scene changed rather than that it was rendered again.",
|
|
22548
|
+
inputSchema: compareViewportBaselineInputSchema,
|
|
22549
|
+
title: "Compare Viewport Baseline"
|
|
22550
|
+
}, async ({ baselineDir, baselineName, maxMismatchRatio, pixelTolerance, projectId, updateBaseline, writeDiffImage }) => {
|
|
22551
|
+
return toToolSuccess(await compareViewportBaseline({
|
|
22552
|
+
baselineDir,
|
|
22553
|
+
baselineName,
|
|
22554
|
+
maxMismatchRatio,
|
|
22555
|
+
pixelTolerance,
|
|
22556
|
+
projectId,
|
|
22557
|
+
updateBaseline,
|
|
22558
|
+
writeDiffImage
|
|
22559
|
+
}, dependencies));
|
|
22560
|
+
});
|
|
22561
|
+
}
|
|
21526
22562
|
//#endregion
|
|
21527
22563
|
//#region src/tools/worldPartition.ts
|
|
21528
22564
|
const listDataLayersInputSchema = {
|
|
@@ -21603,6 +22639,7 @@ const TOOL_CATALOG = [
|
|
|
21603
22639
|
packagingToolDomain,
|
|
21604
22640
|
logsToolDomain,
|
|
21605
22641
|
pieToolDomain,
|
|
22642
|
+
debuggerToolDomain,
|
|
21606
22643
|
automationToolDomain,
|
|
21607
22644
|
jobsToolDomain,
|
|
21608
22645
|
editorToolDomain,
|