dominus-cli 0.2.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +423 -70
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +18 -3
- package/dist/mcp.js.map +1 -1
- package/package.json +17 -16
- package/plugin/Dominus.rbxm +0 -0
- package/plugin/src/Executor.lua +1 -0
- package/plugin/src/Explorer.lua +123 -1
- package/plugin/src/Properties.lua +213 -28
- package/plugin/src/UIBuilder.lua +494 -32
- package/plugin/src/init.server.lua +111 -22
package/dist/index.js
CHANGED
|
@@ -221,6 +221,7 @@ var init_protocol = __esm({
|
|
|
221
221
|
SET_SCRIPT: "cli:set:script",
|
|
222
222
|
RUN_CODE: "cli:run",
|
|
223
223
|
GET_PROPERTIES: "cli:get:properties",
|
|
224
|
+
GET_DESCENDANTS_PROPERTIES: "cli:get:descendants:properties",
|
|
224
225
|
SET_PROPERTIES: "cli:set:properties",
|
|
225
226
|
INSERT_INSTANCE: "cli:insert",
|
|
226
227
|
DELETE_INSTANCE: "cli:delete",
|
|
@@ -234,7 +235,13 @@ var init_protocol = __esm({
|
|
|
234
235
|
END_TEST: "cli:test:end",
|
|
235
236
|
BUILD_UI: "cli:build:ui",
|
|
236
237
|
GET_REFLECTION: "cli:get:reflection",
|
|
237
|
-
UPLOAD_ASSET: "cli:upload:asset"
|
|
238
|
+
UPLOAD_ASSET: "cli:upload:asset",
|
|
239
|
+
SERIALIZE_UI: "cli:serialize:ui",
|
|
240
|
+
MOVE_INSTANCE: "cli:move:instance",
|
|
241
|
+
UNDO: "cli:undo",
|
|
242
|
+
REDO: "cli:redo",
|
|
243
|
+
BULK_SET_PROPERTIES: "cli:bulk:set:properties",
|
|
244
|
+
FIND_REPLACE_SCRIPTS: "cli:find:replace:scripts"
|
|
238
245
|
};
|
|
239
246
|
}
|
|
240
247
|
});
|
|
@@ -1119,16 +1126,65 @@ var init_get_properties = __esm({
|
|
|
1119
1126
|
}
|
|
1120
1127
|
});
|
|
1121
1128
|
|
|
1129
|
+
// src/tools/studio/get-descendants-properties.ts
|
|
1130
|
+
var get_descendants_properties_exports = {};
|
|
1131
|
+
__export(get_descendants_properties_exports, {
|
|
1132
|
+
tool: () => tool6
|
|
1133
|
+
});
|
|
1134
|
+
var tool6;
|
|
1135
|
+
var init_get_descendants_properties = __esm({
|
|
1136
|
+
"src/tools/studio/get-descendants-properties.ts"() {
|
|
1137
|
+
init_protocol();
|
|
1138
|
+
tool6 = {
|
|
1139
|
+
name: "get_descendants_properties",
|
|
1140
|
+
description: "Easily get all descendants of a UI instance (or any instance) and all of their properties.",
|
|
1141
|
+
parameters: {
|
|
1142
|
+
type: "object",
|
|
1143
|
+
properties: {
|
|
1144
|
+
path: {
|
|
1145
|
+
type: "string",
|
|
1146
|
+
description: 'Full instance path (e.g., "Workspace.Part", "StarterGui.ScreenGui")'
|
|
1147
|
+
},
|
|
1148
|
+
outputFile: {
|
|
1149
|
+
type: "string",
|
|
1150
|
+
description: "Optional file path to write the JSON result to, useful for very large trees where context limits apply."
|
|
1151
|
+
}
|
|
1152
|
+
},
|
|
1153
|
+
required: ["path"]
|
|
1154
|
+
},
|
|
1155
|
+
async execute(params, ctx) {
|
|
1156
|
+
if (!ctx.isStudioConnected()) {
|
|
1157
|
+
return { success: false, error: "Studio is not connected" };
|
|
1158
|
+
}
|
|
1159
|
+
const response = await ctx.sendToStudio(
|
|
1160
|
+
CliMsg.GET_DESCENDANTS_PROPERTIES,
|
|
1161
|
+
{ path: params.path },
|
|
1162
|
+
1e3 * 60 * 5
|
|
1163
|
+
// 5 minute timeout since getting ALL descendants can take a very long time
|
|
1164
|
+
);
|
|
1165
|
+
if (params.outputFile && typeof params.outputFile === "string") {
|
|
1166
|
+
const fs6 = await import('fs/promises');
|
|
1167
|
+
const path5 = await import('path');
|
|
1168
|
+
const outputPath = path5.resolve(process.cwd(), params.outputFile);
|
|
1169
|
+
await fs6.writeFile(outputPath, JSON.stringify(response.payload, null, 2), "utf-8");
|
|
1170
|
+
return { success: true, data: `Successfully saved descendants to ${outputPath}` };
|
|
1171
|
+
}
|
|
1172
|
+
return { success: true, data: response.payload };
|
|
1173
|
+
}
|
|
1174
|
+
};
|
|
1175
|
+
}
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1122
1178
|
// src/tools/studio/set-properties.ts
|
|
1123
1179
|
var set_properties_exports = {};
|
|
1124
1180
|
__export(set_properties_exports, {
|
|
1125
|
-
tool: () =>
|
|
1181
|
+
tool: () => tool7
|
|
1126
1182
|
});
|
|
1127
|
-
var
|
|
1183
|
+
var tool7;
|
|
1128
1184
|
var init_set_properties = __esm({
|
|
1129
1185
|
"src/tools/studio/set-properties.ts"() {
|
|
1130
1186
|
init_protocol();
|
|
1131
|
-
|
|
1187
|
+
tool7 = {
|
|
1132
1188
|
name: "set_properties",
|
|
1133
1189
|
description: "Set properties on an instance in Roblox Studio.",
|
|
1134
1190
|
parameters: {
|
|
@@ -1166,13 +1222,13 @@ var init_set_properties = __esm({
|
|
|
1166
1222
|
// src/tools/studio/insert-instance.ts
|
|
1167
1223
|
var insert_instance_exports = {};
|
|
1168
1224
|
__export(insert_instance_exports, {
|
|
1169
|
-
tool: () =>
|
|
1225
|
+
tool: () => tool8
|
|
1170
1226
|
});
|
|
1171
|
-
var
|
|
1227
|
+
var tool8;
|
|
1172
1228
|
var init_insert_instance = __esm({
|
|
1173
1229
|
"src/tools/studio/insert-instance.ts"() {
|
|
1174
1230
|
init_protocol();
|
|
1175
|
-
|
|
1231
|
+
tool8 = {
|
|
1176
1232
|
name: "insert_instance",
|
|
1177
1233
|
description: "Insert a new instance into the Roblox Studio DataModel.",
|
|
1178
1234
|
parameters: {
|
|
@@ -1220,13 +1276,13 @@ var init_insert_instance = __esm({
|
|
|
1220
1276
|
// src/tools/studio/delete-instance.ts
|
|
1221
1277
|
var delete_instance_exports = {};
|
|
1222
1278
|
__export(delete_instance_exports, {
|
|
1223
|
-
tool: () =>
|
|
1279
|
+
tool: () => tool9
|
|
1224
1280
|
});
|
|
1225
|
-
var
|
|
1281
|
+
var tool9;
|
|
1226
1282
|
var init_delete_instance = __esm({
|
|
1227
1283
|
"src/tools/studio/delete-instance.ts"() {
|
|
1228
1284
|
init_protocol();
|
|
1229
|
-
|
|
1285
|
+
tool9 = {
|
|
1230
1286
|
name: "delete_instance",
|
|
1231
1287
|
description: "Delete an instance from the Roblox Studio DataModel by path.",
|
|
1232
1288
|
parameters: {
|
|
@@ -1257,13 +1313,13 @@ var init_delete_instance = __esm({
|
|
|
1257
1313
|
// src/tools/studio/get-output.ts
|
|
1258
1314
|
var get_output_exports = {};
|
|
1259
1315
|
__export(get_output_exports, {
|
|
1260
|
-
tool: () =>
|
|
1316
|
+
tool: () => tool10
|
|
1261
1317
|
});
|
|
1262
|
-
var
|
|
1318
|
+
var tool10;
|
|
1263
1319
|
var init_get_output = __esm({
|
|
1264
1320
|
"src/tools/studio/get-output.ts"() {
|
|
1265
1321
|
init_protocol();
|
|
1266
|
-
|
|
1322
|
+
tool10 = {
|
|
1267
1323
|
name: "get_output",
|
|
1268
1324
|
description: "Get recent output log entries from Roblox Studio (prints, warnings, errors).",
|
|
1269
1325
|
parameters: {
|
|
@@ -1298,13 +1354,13 @@ var init_get_output = __esm({
|
|
|
1298
1354
|
// src/tools/studio/get-selection.ts
|
|
1299
1355
|
var get_selection_exports = {};
|
|
1300
1356
|
__export(get_selection_exports, {
|
|
1301
|
-
tool: () =>
|
|
1357
|
+
tool: () => tool11
|
|
1302
1358
|
});
|
|
1303
|
-
var
|
|
1359
|
+
var tool11;
|
|
1304
1360
|
var init_get_selection = __esm({
|
|
1305
1361
|
"src/tools/studio/get-selection.ts"() {
|
|
1306
1362
|
init_protocol();
|
|
1307
|
-
|
|
1363
|
+
tool11 = {
|
|
1308
1364
|
name: "get_selection",
|
|
1309
1365
|
description: "Get the currently selected instances in Roblox Studio.",
|
|
1310
1366
|
parameters: {
|
|
@@ -1325,13 +1381,13 @@ var init_get_selection = __esm({
|
|
|
1325
1381
|
// src/tools/studio/search-scripts.ts
|
|
1326
1382
|
var search_scripts_exports = {};
|
|
1327
1383
|
__export(search_scripts_exports, {
|
|
1328
|
-
tool: () =>
|
|
1384
|
+
tool: () => tool12
|
|
1329
1385
|
});
|
|
1330
|
-
var
|
|
1386
|
+
var tool12;
|
|
1331
1387
|
var init_search_scripts = __esm({
|
|
1332
1388
|
"src/tools/studio/search-scripts.ts"() {
|
|
1333
1389
|
init_protocol();
|
|
1334
|
-
|
|
1390
|
+
tool12 = {
|
|
1335
1391
|
name: "search_scripts",
|
|
1336
1392
|
description: "Search across all scripts in Roblox Studio for a text pattern. Returns matching lines with context.",
|
|
1337
1393
|
parameters: {
|
|
@@ -1366,13 +1422,13 @@ var init_search_scripts = __esm({
|
|
|
1366
1422
|
// src/tools/studio/run-tests.ts
|
|
1367
1423
|
var run_tests_exports = {};
|
|
1368
1424
|
__export(run_tests_exports, {
|
|
1369
|
-
tool: () =>
|
|
1425
|
+
tool: () => tool13
|
|
1370
1426
|
});
|
|
1371
|
-
var
|
|
1427
|
+
var tool13;
|
|
1372
1428
|
var init_run_tests = __esm({
|
|
1373
1429
|
"src/tools/studio/run-tests.ts"() {
|
|
1374
1430
|
init_protocol();
|
|
1375
|
-
|
|
1431
|
+
tool13 = {
|
|
1376
1432
|
name: "run_tests",
|
|
1377
1433
|
description: "Run tests in Roblox Studio using StudioTestService. Can run all tests or a specific test by name.",
|
|
1378
1434
|
parameters: {
|
|
@@ -1406,13 +1462,13 @@ var init_run_tests = __esm({
|
|
|
1406
1462
|
// src/tools/studio/get-class-info.ts
|
|
1407
1463
|
var get_class_info_exports = {};
|
|
1408
1464
|
__export(get_class_info_exports, {
|
|
1409
|
-
tool: () =>
|
|
1465
|
+
tool: () => tool14
|
|
1410
1466
|
});
|
|
1411
|
-
var
|
|
1467
|
+
var tool14;
|
|
1412
1468
|
var init_get_class_info = __esm({
|
|
1413
1469
|
"src/tools/studio/get-class-info.ts"() {
|
|
1414
1470
|
init_protocol();
|
|
1415
|
-
|
|
1471
|
+
tool14 = {
|
|
1416
1472
|
name: "get_class_info",
|
|
1417
1473
|
description: "Look up the full schema of a Roblox class using ReflectionService. Returns all properties (with their types), methods (with parameters), and events. ALWAYS call this before creating or modifying GUI/UI elements (Frame, TextLabel, ImageLabel, etc.) to know the correct property names and expected types (e.g., Size is UDim2 for GUI, Vector3 for Parts).",
|
|
1418
1474
|
parameters: {
|
|
@@ -1443,13 +1499,13 @@ var init_get_class_info = __esm({
|
|
|
1443
1499
|
// src/tools/studio/create-ui.ts
|
|
1444
1500
|
var create_ui_exports = {};
|
|
1445
1501
|
__export(create_ui_exports, {
|
|
1446
|
-
tool: () =>
|
|
1502
|
+
tool: () => tool15
|
|
1447
1503
|
});
|
|
1448
|
-
var
|
|
1504
|
+
var tool15;
|
|
1449
1505
|
var init_create_ui = __esm({
|
|
1450
1506
|
"src/tools/studio/create-ui.ts"() {
|
|
1451
1507
|
init_protocol();
|
|
1452
|
-
|
|
1508
|
+
tool15 = {
|
|
1453
1509
|
name: "create_ui",
|
|
1454
1510
|
description: 'Create an entire UI tree in Roblox Studio in a SINGLE call. Pass a declarative JSON tree with ClassName, Name, properties, and Children. All types are auto-coerced natively in Luau \u2014 UDim2, Color3, Font, enums all work. This is 10x faster than run_code for UI because it handles everything in one round-trip with no Luau syntax issues. Replaces any existing instance with the same name.\n\nExample: create a pastel hello world screen:\n{\n "parent": "StarterGui",\n "tree": {\n "ClassName": "ScreenGui",\n "Name": "HelloWorld",\n "ResetOnSpawn": false,\n "Children": [{\n "ClassName": "Frame",\n "Name": "Background",\n "Size": [1, 0, 1, 0],\n "BackgroundColor3": "#F0E6FF",\n "Children": [\n { "ClassName": "UICorner", "CornerRadius": [0, 12] },\n { "ClassName": "TextLabel", "Name": "Title", "Text": "Hello World!",\n "Size": [0.5, 0, 0.1, 0], "Position": [0.25, 0, 0.45, 0],\n "BackgroundTransparency": 1, "TextColor3": "#6C5CE7",\n "TextScaled": true, "Font": "GothamBold" }\n ]\n }]\n }\n}',
|
|
1455
1511
|
parameters: {
|
|
@@ -1461,7 +1517,11 @@ var init_create_ui = __esm({
|
|
|
1461
1517
|
},
|
|
1462
1518
|
tree: {
|
|
1463
1519
|
type: "object",
|
|
1464
|
-
description: 'The root UI node. Each node has: ClassName (string), Name (string), any properties as key-value pairs, and Children (array of child nodes). Property values are auto-coerced:\n UDim2: [xScale, xOffset, yScale, yOffset] or {XScale, XOffset, YScale, YOffset}\n Color3: "#hex", "rgb(r,g,b)", [r,g,b], or BrickColor name\n UDim: [scale, offset] or number\n Vector2: {x, y} or [
|
|
1520
|
+
description: 'The root UI node. Each node has: ClassName (string), Name (string), any properties as key-value pairs, and Children (array of child nodes). Property values are auto-coerced:\n UDim2: [xScale, xOffset, yScale, yOffset] or {XScale, XOffset, YScale, YOffset}\n Color3: "#hex", "rgb(r,g,b)", [r,g,b], or BrickColor name\n UDim: [scale, offset] or number\n Vector2: [x, y] or {x, y} (auto-disambiguated from UDim by property name)\n NumberRange: [min, max] or number\n Rect: [minX, minY, maxX, maxY] or {MinX, MinY, MaxX, MaxY}\n Font: "GothamBold", "SourceSans", etc. (Enum.Font names)\n Enums: string name like "Center", "Left", "Fit"\n FontFace: {Family, Weight, Style}\n 2-element arrays are auto-disambiguated: AnchorPoint\u2192Vector2, CornerRadius/Padding\u2192UDim, etc.'
|
|
1521
|
+
},
|
|
1522
|
+
animate: {
|
|
1523
|
+
type: "boolean",
|
|
1524
|
+
description: "If true, task.wait() will be injected between creation of nodes so that the UI writes out dynamically."
|
|
1465
1525
|
}
|
|
1466
1526
|
},
|
|
1467
1527
|
required: ["tree"]
|
|
@@ -1472,6 +1532,7 @@ var init_create_ui = __esm({
|
|
|
1472
1532
|
}
|
|
1473
1533
|
const response = await ctx.sendToStudio(CliMsg.BUILD_UI, {
|
|
1474
1534
|
parent: params.parent ?? "StarterGui",
|
|
1535
|
+
animate: params.animate,
|
|
1475
1536
|
tree: params.tree
|
|
1476
1537
|
});
|
|
1477
1538
|
const payload = response.payload;
|
|
@@ -1490,13 +1551,13 @@ var init_create_ui = __esm({
|
|
|
1490
1551
|
// src/tools/studio/execute-run-test.ts
|
|
1491
1552
|
var execute_run_test_exports = {};
|
|
1492
1553
|
__export(execute_run_test_exports, {
|
|
1493
|
-
tool: () =>
|
|
1554
|
+
tool: () => tool16
|
|
1494
1555
|
});
|
|
1495
|
-
var
|
|
1556
|
+
var tool16;
|
|
1496
1557
|
var init_execute_run_test = __esm({
|
|
1497
1558
|
"src/tools/studio/execute-run-test.ts"() {
|
|
1498
1559
|
init_protocol();
|
|
1499
|
-
|
|
1560
|
+
tool16 = {
|
|
1500
1561
|
name: "execute_run_test",
|
|
1501
1562
|
description: "Start a Run mode test session in Roblox Studio using StudioTestService:ExecuteRunModeAsync(). Passes args that server scripts can retrieve via GetTestArgs(). Yields until the session ends (via EndTest or manual stop). Returns the value passed to EndTest(). Use this for headless automated tests \u2014 no player character, just server scripts running.",
|
|
1502
1563
|
parameters: {
|
|
@@ -1535,13 +1596,13 @@ var init_execute_run_test = __esm({
|
|
|
1535
1596
|
// src/tools/studio/execute-play-test.ts
|
|
1536
1597
|
var execute_play_test_exports = {};
|
|
1537
1598
|
__export(execute_play_test_exports, {
|
|
1538
|
-
tool: () =>
|
|
1599
|
+
tool: () => tool17
|
|
1539
1600
|
});
|
|
1540
|
-
var
|
|
1601
|
+
var tool17;
|
|
1541
1602
|
var init_execute_play_test = __esm({
|
|
1542
1603
|
"src/tools/studio/execute-play-test.ts"() {
|
|
1543
1604
|
init_protocol();
|
|
1544
|
-
|
|
1605
|
+
tool17 = {
|
|
1545
1606
|
name: "execute_play_test",
|
|
1546
1607
|
description: "Start a solo Play mode test session in Roblox Studio using StudioTestService:ExecutePlayModeAsync(). Passes args that server scripts can retrieve via GetTestArgs(). Yields until the session ends (via EndTest or manual stop). Returns the value passed to EndTest(). Use this for tests that need a player character and full client-server simulation.",
|
|
1547
1608
|
parameters: {
|
|
@@ -1580,13 +1641,13 @@ var init_execute_play_test = __esm({
|
|
|
1580
1641
|
// src/tools/studio/create-part.ts
|
|
1581
1642
|
var create_part_exports = {};
|
|
1582
1643
|
__export(create_part_exports, {
|
|
1583
|
-
tool: () =>
|
|
1644
|
+
tool: () => tool18
|
|
1584
1645
|
});
|
|
1585
|
-
var
|
|
1646
|
+
var tool18;
|
|
1586
1647
|
var init_create_part = __esm({
|
|
1587
1648
|
"src/tools/studio/create-part.ts"() {
|
|
1588
1649
|
init_protocol();
|
|
1589
|
-
|
|
1650
|
+
tool18 = {
|
|
1590
1651
|
name: "create_part",
|
|
1591
1652
|
description: "Create a Part in Roblox Studio with position, size, color, material and more \u2014 all in one call. Much faster than insert_instance + set_properties separately.",
|
|
1592
1653
|
parameters: {
|
|
@@ -1679,7 +1740,7 @@ var init_create_part = __esm({
|
|
|
1679
1740
|
// src/tools/studio/clone-instance.ts
|
|
1680
1741
|
var clone_instance_exports = {};
|
|
1681
1742
|
__export(clone_instance_exports, {
|
|
1682
|
-
tool: () =>
|
|
1743
|
+
tool: () => tool19
|
|
1683
1744
|
});
|
|
1684
1745
|
function buildCloneCode(params) {
|
|
1685
1746
|
const path5 = params.path;
|
|
@@ -1714,11 +1775,11 @@ function buildCloneCode(params) {
|
|
|
1714
1775
|
lines.push(`print("Cloned: " .. clone:GetFullName())`);
|
|
1715
1776
|
return lines.join("\n");
|
|
1716
1777
|
}
|
|
1717
|
-
var
|
|
1778
|
+
var tool19;
|
|
1718
1779
|
var init_clone_instance = __esm({
|
|
1719
1780
|
"src/tools/studio/clone-instance.ts"() {
|
|
1720
1781
|
init_protocol();
|
|
1721
|
-
|
|
1782
|
+
tool19 = {
|
|
1722
1783
|
name: "clone_instance",
|
|
1723
1784
|
description: "Clone an existing instance in Roblox Studio and optionally reposition/rename it. Great for duplicating parts, models, or entire trees.",
|
|
1724
1785
|
parameters: {
|
|
@@ -1754,13 +1815,13 @@ var init_clone_instance = __esm({
|
|
|
1754
1815
|
// src/tools/studio/group-instances.ts
|
|
1755
1816
|
var group_instances_exports = {};
|
|
1756
1817
|
__export(group_instances_exports, {
|
|
1757
|
-
tool: () =>
|
|
1818
|
+
tool: () => tool20
|
|
1758
1819
|
});
|
|
1759
|
-
var
|
|
1820
|
+
var tool20;
|
|
1760
1821
|
var init_group_instances = __esm({
|
|
1761
1822
|
"src/tools/studio/group-instances.ts"() {
|
|
1762
1823
|
init_protocol();
|
|
1763
|
-
|
|
1824
|
+
tool20 = {
|
|
1764
1825
|
name: "group_instances",
|
|
1765
1826
|
description: 'Group multiple instances under a new Model or Folder. Useful for organizing parts into objects (e.g., grouping trunk + leaves into a "Tree" model).',
|
|
1766
1827
|
parameters: {
|
|
@@ -1820,7 +1881,7 @@ var init_group_instances = __esm({
|
|
|
1820
1881
|
// src/tools/studio/build-multiple.ts
|
|
1821
1882
|
var build_multiple_exports = {};
|
|
1822
1883
|
__export(build_multiple_exports, {
|
|
1823
|
-
tool: () =>
|
|
1884
|
+
tool: () => tool21
|
|
1824
1885
|
});
|
|
1825
1886
|
function generateBatchCode(parts, groupName, groupParent) {
|
|
1826
1887
|
const lines = [];
|
|
@@ -1879,11 +1940,11 @@ function generateBatchCode(parts, groupName, groupParent) {
|
|
|
1879
1940
|
lines.push(`print("Built ${parts.length} parts${groupName ? ` in ${groupName}` : ""}")`);
|
|
1880
1941
|
return lines.join("\n");
|
|
1881
1942
|
}
|
|
1882
|
-
var
|
|
1943
|
+
var tool21;
|
|
1883
1944
|
var init_build_multiple = __esm({
|
|
1884
1945
|
"src/tools/studio/build-multiple.ts"() {
|
|
1885
1946
|
init_protocol();
|
|
1886
|
-
|
|
1947
|
+
tool21 = {
|
|
1887
1948
|
name: "build_multiple",
|
|
1888
1949
|
description: "Create multiple parts/instances in one batch call. Send an array of specs and they all get created in a single Studio round-trip. Ideal for building trees, houses, vehicles, terrain \u2014 anything composed of multiple parts.",
|
|
1889
1950
|
parameters: {
|
|
@@ -1952,16 +2013,234 @@ var init_build_multiple = __esm({
|
|
|
1952
2013
|
}
|
|
1953
2014
|
});
|
|
1954
2015
|
|
|
2016
|
+
// src/tools/studio/serialize-ui.ts
|
|
2017
|
+
var serialize_ui_exports = {};
|
|
2018
|
+
__export(serialize_ui_exports, {
|
|
2019
|
+
tool: () => tool22
|
|
2020
|
+
});
|
|
2021
|
+
var tool22;
|
|
2022
|
+
var init_serialize_ui = __esm({
|
|
2023
|
+
"src/tools/studio/serialize-ui.ts"() {
|
|
2024
|
+
init_protocol();
|
|
2025
|
+
tool22 = {
|
|
2026
|
+
name: "serialize_ui",
|
|
2027
|
+
description: "Serialize an existing UI tree from Roblox Studio into create_ui-compatible JSON. This is the reverse of create_ui \u2014 read any instance and get back a declarative JSON tree you can modify and pass back to create_ui. Perfect for cloning, templating, or refactoring UIs.\n\nThe output includes ClassName, Name, all non-default properties (with values converted to JSON-friendly formats like [r,g,b] for Color3, [xS,xO,yS,yO] for UDim2, etc.), and Children.",
|
|
2028
|
+
parameters: {
|
|
2029
|
+
type: "object",
|
|
2030
|
+
properties: {
|
|
2031
|
+
path: {
|
|
2032
|
+
type: "string",
|
|
2033
|
+
description: 'Instance path to serialize (e.g. "StarterGui.MyScreenGui")'
|
|
2034
|
+
},
|
|
2035
|
+
maxDepth: {
|
|
2036
|
+
type: "number",
|
|
2037
|
+
description: "Maximum depth to serialize (default: 50)"
|
|
2038
|
+
}
|
|
2039
|
+
},
|
|
2040
|
+
required: ["path"]
|
|
2041
|
+
},
|
|
2042
|
+
async execute(params, ctx) {
|
|
2043
|
+
if (!ctx.isStudioConnected()) {
|
|
2044
|
+
return { success: false, error: "Studio is not connected" };
|
|
2045
|
+
}
|
|
2046
|
+
const response = await ctx.sendToStudio(CliMsg.SERIALIZE_UI, {
|
|
2047
|
+
path: params.path,
|
|
2048
|
+
maxDepth: params.maxDepth ?? 50
|
|
2049
|
+
}, 1e3 * 60 * 2);
|
|
2050
|
+
const payload = response.payload;
|
|
2051
|
+
if (!payload.success) {
|
|
2052
|
+
return { success: false, error: payload.error ?? "Serialization failed" };
|
|
2053
|
+
}
|
|
2054
|
+
return { success: true, data: payload.tree };
|
|
2055
|
+
}
|
|
2056
|
+
};
|
|
2057
|
+
}
|
|
2058
|
+
});
|
|
2059
|
+
|
|
2060
|
+
// src/tools/studio/move-instance.ts
|
|
2061
|
+
var move_instance_exports = {};
|
|
2062
|
+
__export(move_instance_exports, {
|
|
2063
|
+
tool: () => tool23
|
|
2064
|
+
});
|
|
2065
|
+
var tool23;
|
|
2066
|
+
var init_move_instance = __esm({
|
|
2067
|
+
"src/tools/studio/move-instance.ts"() {
|
|
2068
|
+
init_protocol();
|
|
2069
|
+
tool23 = {
|
|
2070
|
+
name: "move_instance",
|
|
2071
|
+
description: "Move (reparent) an instance to a new parent in Roblox Studio. This preserves the instance and all its descendants \u2014 much better than delete + recreate. Sets a ChangeHistoryService waypoint so the move can be undone.",
|
|
2072
|
+
parameters: {
|
|
2073
|
+
type: "object",
|
|
2074
|
+
properties: {
|
|
2075
|
+
path: {
|
|
2076
|
+
type: "string",
|
|
2077
|
+
description: 'Full path of the instance to move (e.g. "Workspace.OldFolder.MyPart")'
|
|
2078
|
+
},
|
|
2079
|
+
newParent: {
|
|
2080
|
+
type: "string",
|
|
2081
|
+
description: 'Full path of the new parent (e.g. "Workspace.NewFolder")'
|
|
2082
|
+
}
|
|
2083
|
+
},
|
|
2084
|
+
required: ["path", "newParent"]
|
|
2085
|
+
},
|
|
2086
|
+
async execute(params, ctx) {
|
|
2087
|
+
if (!ctx.isStudioConnected()) {
|
|
2088
|
+
return { success: false, error: "Studio is not connected" };
|
|
2089
|
+
}
|
|
2090
|
+
const response = await ctx.sendToStudio(CliMsg.MOVE_INSTANCE, {
|
|
2091
|
+
path: params.path,
|
|
2092
|
+
newParent: params.newParent
|
|
2093
|
+
});
|
|
2094
|
+
const payload = response.payload;
|
|
2095
|
+
if (!payload.success) {
|
|
2096
|
+
return { success: false, error: payload.error ?? "Move failed" };
|
|
2097
|
+
}
|
|
2098
|
+
return { success: true, data: { newPath: payload.newPath } };
|
|
2099
|
+
}
|
|
2100
|
+
};
|
|
2101
|
+
}
|
|
2102
|
+
});
|
|
2103
|
+
|
|
2104
|
+
// src/tools/studio/bulk-set-properties.ts
|
|
2105
|
+
var bulk_set_properties_exports = {};
|
|
2106
|
+
__export(bulk_set_properties_exports, {
|
|
2107
|
+
tool: () => tool24
|
|
2108
|
+
});
|
|
2109
|
+
var tool24;
|
|
2110
|
+
var init_bulk_set_properties = __esm({
|
|
2111
|
+
"src/tools/studio/bulk-set-properties.ts"() {
|
|
2112
|
+
init_protocol();
|
|
2113
|
+
tool24 = {
|
|
2114
|
+
name: "bulk_set_properties",
|
|
2115
|
+
description: 'Set properties on multiple instances at once in a single call. Much faster than calling set_properties repeatedly. Supports two modes:\n1. Explicit paths: provide an array of {path, properties} objects\n2. By class filter: provide a root path, className filter, and properties to apply to all matches\n\nExample (explicit): [{"path": "StarterGui.HUD.Title", "properties": {"TextColor3": "#fff"}}, ...]\nExample (filter): root="StarterGui.HUD", className="TextLabel", properties={"Font": "GothamBold"}',
|
|
2116
|
+
parameters: {
|
|
2117
|
+
type: "object",
|
|
2118
|
+
properties: {
|
|
2119
|
+
targets: {
|
|
2120
|
+
type: "array",
|
|
2121
|
+
description: "Array of {path, properties} objects for explicit mode.",
|
|
2122
|
+
items: {
|
|
2123
|
+
type: "object",
|
|
2124
|
+
description: "A target with path and properties to set."
|
|
2125
|
+
}
|
|
2126
|
+
},
|
|
2127
|
+
root: {
|
|
2128
|
+
type: "string",
|
|
2129
|
+
description: "Root instance path to search under (filter mode)"
|
|
2130
|
+
},
|
|
2131
|
+
className: {
|
|
2132
|
+
type: "string",
|
|
2133
|
+
description: "Only apply to instances of this ClassName (filter mode)"
|
|
2134
|
+
},
|
|
2135
|
+
properties: {
|
|
2136
|
+
type: "object",
|
|
2137
|
+
description: "Properties to set on all matched instances (filter mode)"
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
},
|
|
2141
|
+
async execute(params, ctx) {
|
|
2142
|
+
if (!ctx.isStudioConnected()) {
|
|
2143
|
+
return { success: false, error: "Studio is not connected" };
|
|
2144
|
+
}
|
|
2145
|
+
const response = await ctx.sendToStudio(CliMsg.BULK_SET_PROPERTIES, {
|
|
2146
|
+
targets: params.targets,
|
|
2147
|
+
root: params.root,
|
|
2148
|
+
className: params.className,
|
|
2149
|
+
properties: params.properties
|
|
2150
|
+
}, 1e3 * 60);
|
|
2151
|
+
const payload = response.payload;
|
|
2152
|
+
if (!payload.success) {
|
|
2153
|
+
return { success: false, error: payload.error ?? "Bulk set failed" };
|
|
2154
|
+
}
|
|
2155
|
+
return {
|
|
2156
|
+
success: true,
|
|
2157
|
+
data: {
|
|
2158
|
+
modified: payload.modified,
|
|
2159
|
+
errors: payload.errors?.length ? payload.errors : void 0
|
|
2160
|
+
}
|
|
2161
|
+
};
|
|
2162
|
+
}
|
|
2163
|
+
};
|
|
2164
|
+
}
|
|
2165
|
+
});
|
|
2166
|
+
|
|
2167
|
+
// src/tools/studio/find-replace-scripts.ts
|
|
2168
|
+
var find_replace_scripts_exports = {};
|
|
2169
|
+
__export(find_replace_scripts_exports, {
|
|
2170
|
+
tool: () => tool25
|
|
2171
|
+
});
|
|
2172
|
+
var tool25;
|
|
2173
|
+
var init_find_replace_scripts = __esm({
|
|
2174
|
+
"src/tools/studio/find-replace-scripts.ts"() {
|
|
2175
|
+
init_protocol();
|
|
2176
|
+
tool25 = {
|
|
2177
|
+
name: "find_replace_scripts",
|
|
2178
|
+
description: 'Find and replace text across all scripts in the game (or under a root path). Supports plain text and Lua pattern matching. Returns a list of modified scripts with match counts.\n\nUse dryRun=true to preview changes without applying them.\nExample: find="workspace" replace="Workspace" root="ServerScriptService"',
|
|
2179
|
+
parameters: {
|
|
2180
|
+
type: "object",
|
|
2181
|
+
properties: {
|
|
2182
|
+
find: {
|
|
2183
|
+
type: "string",
|
|
2184
|
+
description: "Text or Lua pattern to search for"
|
|
2185
|
+
},
|
|
2186
|
+
replace: {
|
|
2187
|
+
type: "string",
|
|
2188
|
+
description: "Replacement text (supports Lua pattern captures like %1, %2)"
|
|
2189
|
+
},
|
|
2190
|
+
root: {
|
|
2191
|
+
type: "string",
|
|
2192
|
+
description: "Root path to limit search scope (optional, searches entire game if omitted)"
|
|
2193
|
+
},
|
|
2194
|
+
usePattern: {
|
|
2195
|
+
type: "boolean",
|
|
2196
|
+
description: "If true, treat find/replace as Lua patterns. Default: false (plain text)"
|
|
2197
|
+
},
|
|
2198
|
+
dryRun: {
|
|
2199
|
+
type: "boolean",
|
|
2200
|
+
description: "If true, report matches but do not modify scripts. Default: false"
|
|
2201
|
+
}
|
|
2202
|
+
},
|
|
2203
|
+
required: ["find", "replace"]
|
|
2204
|
+
},
|
|
2205
|
+
async execute(params, ctx) {
|
|
2206
|
+
if (!ctx.isStudioConnected()) {
|
|
2207
|
+
return { success: false, error: "Studio is not connected" };
|
|
2208
|
+
}
|
|
2209
|
+
const response = await ctx.sendToStudio(CliMsg.FIND_REPLACE_SCRIPTS, {
|
|
2210
|
+
find: params.find,
|
|
2211
|
+
replace: params.replace,
|
|
2212
|
+
root: params.root,
|
|
2213
|
+
usePattern: params.usePattern ?? false,
|
|
2214
|
+
dryRun: params.dryRun ?? false
|
|
2215
|
+
}, 1e3 * 60 * 5);
|
|
2216
|
+
const payload = response.payload;
|
|
2217
|
+
if (!payload.success) {
|
|
2218
|
+
return { success: false, error: payload.error ?? "Find/replace failed" };
|
|
2219
|
+
}
|
|
2220
|
+
return {
|
|
2221
|
+
success: true,
|
|
2222
|
+
data: {
|
|
2223
|
+
totalFiles: payload.totalFiles,
|
|
2224
|
+
totalMatches: payload.totalMatches,
|
|
2225
|
+
modified: payload.modified,
|
|
2226
|
+
dryRun: params.dryRun ?? false
|
|
2227
|
+
}
|
|
2228
|
+
};
|
|
2229
|
+
}
|
|
2230
|
+
};
|
|
2231
|
+
}
|
|
2232
|
+
});
|
|
2233
|
+
|
|
1955
2234
|
// src/tools/memory/recall.ts
|
|
1956
2235
|
var recall_exports = {};
|
|
1957
2236
|
__export(recall_exports, {
|
|
1958
|
-
tool: () =>
|
|
2237
|
+
tool: () => tool26
|
|
1959
2238
|
});
|
|
1960
|
-
var
|
|
2239
|
+
var tool26;
|
|
1961
2240
|
var init_recall = __esm({
|
|
1962
2241
|
"src/tools/memory/recall.ts"() {
|
|
1963
2242
|
init_store();
|
|
1964
|
-
|
|
2243
|
+
tool26 = {
|
|
1965
2244
|
name: "recall_memory",
|
|
1966
2245
|
description: "Search your memory for previously learned facts about the current project. Use this to recall architecture decisions, patterns, known bugs, or user preferences.",
|
|
1967
2246
|
parameters: {
|
|
@@ -2000,13 +2279,13 @@ var init_recall = __esm({
|
|
|
2000
2279
|
// src/tools/memory/remember.ts
|
|
2001
2280
|
var remember_exports = {};
|
|
2002
2281
|
__export(remember_exports, {
|
|
2003
|
-
tool: () =>
|
|
2282
|
+
tool: () => tool27
|
|
2004
2283
|
});
|
|
2005
|
-
var
|
|
2284
|
+
var tool27;
|
|
2006
2285
|
var init_remember = __esm({
|
|
2007
2286
|
"src/tools/memory/remember.ts"() {
|
|
2008
2287
|
init_store();
|
|
2009
|
-
|
|
2288
|
+
tool27 = {
|
|
2010
2289
|
name: "remember",
|
|
2011
2290
|
description: "Store a fact about the current project in persistent memory. Use this to remember architecture decisions, patterns, bugs found, or user preferences so you can recall them in future sessions.",
|
|
2012
2291
|
parameters: {
|
|
@@ -2046,12 +2325,12 @@ var init_remember = __esm({
|
|
|
2046
2325
|
// src/tools/cloud/upload-asset.ts
|
|
2047
2326
|
var upload_asset_exports = {};
|
|
2048
2327
|
__export(upload_asset_exports, {
|
|
2049
|
-
tool: () =>
|
|
2328
|
+
tool: () => tool28
|
|
2050
2329
|
});
|
|
2051
|
-
var
|
|
2330
|
+
var tool28;
|
|
2052
2331
|
var init_upload_asset = __esm({
|
|
2053
2332
|
"src/tools/cloud/upload-asset.ts"() {
|
|
2054
|
-
|
|
2333
|
+
tool28 = {
|
|
2055
2334
|
name: "upload_asset",
|
|
2056
2335
|
description: "Upload a local file (image, model, audio) to Roblox via the Open Cloud API. Requires an Open Cloud API key configured in dominus.",
|
|
2057
2336
|
parameters: {
|
|
@@ -2147,6 +2426,57 @@ var init_upload_asset = __esm({
|
|
|
2147
2426
|
}
|
|
2148
2427
|
});
|
|
2149
2428
|
|
|
2429
|
+
// src/tools/studio/undo-redo.ts
|
|
2430
|
+
var undo_redo_exports = {};
|
|
2431
|
+
__export(undo_redo_exports, {
|
|
2432
|
+
redoTool: () => redoTool,
|
|
2433
|
+
undoTool: () => undoTool
|
|
2434
|
+
});
|
|
2435
|
+
var undoTool, redoTool;
|
|
2436
|
+
var init_undo_redo = __esm({
|
|
2437
|
+
"src/tools/studio/undo-redo.ts"() {
|
|
2438
|
+
init_protocol();
|
|
2439
|
+
undoTool = {
|
|
2440
|
+
name: "undo",
|
|
2441
|
+
description: "Undo the last action in Roblox Studio using ChangeHistoryService. Works just like Ctrl+Z. Use this to roll back mistakes.",
|
|
2442
|
+
parameters: {
|
|
2443
|
+
type: "object",
|
|
2444
|
+
properties: {}
|
|
2445
|
+
},
|
|
2446
|
+
async execute(_params, ctx) {
|
|
2447
|
+
if (!ctx.isStudioConnected()) {
|
|
2448
|
+
return { success: false, error: "Studio is not connected" };
|
|
2449
|
+
}
|
|
2450
|
+
const response = await ctx.sendToStudio(CliMsg.UNDO, {});
|
|
2451
|
+
const payload = response.payload;
|
|
2452
|
+
if (!payload.success) {
|
|
2453
|
+
return { success: false, error: payload.error ?? "Undo failed" };
|
|
2454
|
+
}
|
|
2455
|
+
return { success: true, data: "Undo performed" };
|
|
2456
|
+
}
|
|
2457
|
+
};
|
|
2458
|
+
redoTool = {
|
|
2459
|
+
name: "redo",
|
|
2460
|
+
description: "Redo the last undone action in Roblox Studio using ChangeHistoryService. Works just like Ctrl+Y.",
|
|
2461
|
+
parameters: {
|
|
2462
|
+
type: "object",
|
|
2463
|
+
properties: {}
|
|
2464
|
+
},
|
|
2465
|
+
async execute(_params, ctx) {
|
|
2466
|
+
if (!ctx.isStudioConnected()) {
|
|
2467
|
+
return { success: false, error: "Studio is not connected" };
|
|
2468
|
+
}
|
|
2469
|
+
const response = await ctx.sendToStudio(CliMsg.REDO, {});
|
|
2470
|
+
const payload = response.payload;
|
|
2471
|
+
if (!payload.success) {
|
|
2472
|
+
return { success: false, error: payload.error ?? "Redo failed" };
|
|
2473
|
+
}
|
|
2474
|
+
return { success: true, data: "Redo performed" };
|
|
2475
|
+
}
|
|
2476
|
+
};
|
|
2477
|
+
}
|
|
2478
|
+
});
|
|
2479
|
+
|
|
2150
2480
|
// src/mcp/server.ts
|
|
2151
2481
|
var server_exports = {};
|
|
2152
2482
|
__export(server_exports, {
|
|
@@ -2228,6 +2558,19 @@ async function startMcpServer() {
|
|
|
2228
2558
|
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
2229
2559
|
}
|
|
2230
2560
|
);
|
|
2561
|
+
mcp.tool(
|
|
2562
|
+
"get_descendants_properties",
|
|
2563
|
+
"Easily get all descendants of a UI instance (or any instance) and all of their properties.",
|
|
2564
|
+
{
|
|
2565
|
+
path: z.string().describe('Full instance path (e.g., "Workspace.Part", "StarterGui.ScreenGui")'),
|
|
2566
|
+
outputFile: z.string().optional().describe("Optional file path to write to prevent limit errors/timeouts")
|
|
2567
|
+
},
|
|
2568
|
+
async ({ path: path5, outputFile }) => {
|
|
2569
|
+
assertConnected();
|
|
2570
|
+
const res = await bridge.sendRequest(CliMsg.GET_DESCENDANTS_PROPERTIES, { path: path5, outputFile }, 1e3 * 60 * 5);
|
|
2571
|
+
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
2572
|
+
}
|
|
2573
|
+
);
|
|
2231
2574
|
mcp.tool(
|
|
2232
2575
|
"set_properties",
|
|
2233
2576
|
"Set properties on an instance in Roblox Studio",
|
|
@@ -2327,13 +2670,14 @@ async function startMcpServer() {
|
|
|
2327
2670
|
parent: z.string().optional().describe('Parent: "StarterGui", "PlayerGui", or path. Default: StarterGui'),
|
|
2328
2671
|
tree: z.record(z.unknown()).describe(
|
|
2329
2672
|
'Root UI node: {ClassName, Name, properties..., Children: [{...}, ...]}. UDim2 as [xScale, xOffset, yScale, yOffset], Color3 as "#hex", Font as "GothamBold"'
|
|
2330
|
-
)
|
|
2673
|
+
),
|
|
2674
|
+
animate: z.boolean().optional().describe("If true, task.wait() will be injected between creation of nodes so that the UI writes out dynamically.")
|
|
2331
2675
|
},
|
|
2332
|
-
async ({ parent, tree }) => {
|
|
2676
|
+
async ({ parent, tree, animate }) => {
|
|
2333
2677
|
assertConnected();
|
|
2334
2678
|
const res = await bridge.sendRequest(
|
|
2335
2679
|
CliMsg.BUILD_UI,
|
|
2336
|
-
{ parent: parent ?? "StarterGui", tree }
|
|
2680
|
+
{ parent: parent ?? "StarterGui", tree, animate }
|
|
2337
2681
|
);
|
|
2338
2682
|
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
2339
2683
|
}
|
|
@@ -3775,13 +4119,13 @@ var AIProvider = class {
|
|
|
3775
4119
|
yield { type: "done" };
|
|
3776
4120
|
}
|
|
3777
4121
|
};
|
|
3778
|
-
function toolToOpenAI(
|
|
4122
|
+
function toolToOpenAI(tool29) {
|
|
3779
4123
|
return {
|
|
3780
4124
|
type: "function",
|
|
3781
4125
|
function: {
|
|
3782
|
-
name:
|
|
3783
|
-
description:
|
|
3784
|
-
parameters:
|
|
4126
|
+
name: tool29.name,
|
|
4127
|
+
description: tool29.description,
|
|
4128
|
+
parameters: tool29.parameters
|
|
3785
4129
|
}
|
|
3786
4130
|
};
|
|
3787
4131
|
}
|
|
@@ -4237,11 +4581,11 @@ var AgentLoop = class {
|
|
|
4237
4581
|
// src/tools/registry.ts
|
|
4238
4582
|
var ToolRegistry = class {
|
|
4239
4583
|
tools = /* @__PURE__ */ new Map();
|
|
4240
|
-
register(
|
|
4241
|
-
if (this.tools.has(
|
|
4242
|
-
throw new Error(`Tool already registered: ${
|
|
4584
|
+
register(tool29) {
|
|
4585
|
+
if (this.tools.has(tool29.name)) {
|
|
4586
|
+
throw new Error(`Tool already registered: ${tool29.name}`);
|
|
4243
4587
|
}
|
|
4244
|
-
this.tools.set(
|
|
4588
|
+
this.tools.set(tool29.name, tool29);
|
|
4245
4589
|
}
|
|
4246
4590
|
get(name) {
|
|
4247
4591
|
return this.tools.get(name);
|
|
@@ -4253,12 +4597,12 @@ var ToolRegistry = class {
|
|
|
4253
4597
|
return this.getAll();
|
|
4254
4598
|
}
|
|
4255
4599
|
async execute(call, ctx) {
|
|
4256
|
-
const
|
|
4257
|
-
if (!
|
|
4600
|
+
const tool29 = this.tools.get(call.name);
|
|
4601
|
+
if (!tool29) {
|
|
4258
4602
|
return { success: false, error: `Unknown tool: ${call.name}` };
|
|
4259
4603
|
}
|
|
4260
4604
|
try {
|
|
4261
|
-
return await
|
|
4605
|
+
return await tool29.execute(call.arguments, ctx);
|
|
4262
4606
|
} catch (err) {
|
|
4263
4607
|
const message = err instanceof Error ? err.message : String(err);
|
|
4264
4608
|
return { success: false, error: message };
|
|
@@ -4276,6 +4620,7 @@ function createDefaultRegistry() {
|
|
|
4276
4620
|
Promise.resolve().then(() => (init_run_code(), run_code_exports)),
|
|
4277
4621
|
Promise.resolve().then(() => (init_get_explorer(), get_explorer_exports)),
|
|
4278
4622
|
Promise.resolve().then(() => (init_get_properties(), get_properties_exports)),
|
|
4623
|
+
Promise.resolve().then(() => (init_get_descendants_properties(), get_descendants_properties_exports)),
|
|
4279
4624
|
Promise.resolve().then(() => (init_set_properties(), set_properties_exports)),
|
|
4280
4625
|
Promise.resolve().then(() => (init_insert_instance(), insert_instance_exports)),
|
|
4281
4626
|
Promise.resolve().then(() => (init_delete_instance(), delete_instance_exports)),
|
|
@@ -4291,6 +4636,10 @@ function createDefaultRegistry() {
|
|
|
4291
4636
|
Promise.resolve().then(() => (init_clone_instance(), clone_instance_exports)),
|
|
4292
4637
|
Promise.resolve().then(() => (init_group_instances(), group_instances_exports)),
|
|
4293
4638
|
Promise.resolve().then(() => (init_build_multiple(), build_multiple_exports)),
|
|
4639
|
+
Promise.resolve().then(() => (init_serialize_ui(), serialize_ui_exports)),
|
|
4640
|
+
Promise.resolve().then(() => (init_move_instance(), move_instance_exports)),
|
|
4641
|
+
Promise.resolve().then(() => (init_bulk_set_properties(), bulk_set_properties_exports)),
|
|
4642
|
+
Promise.resolve().then(() => (init_find_replace_scripts(), find_replace_scripts_exports)),
|
|
4294
4643
|
Promise.resolve().then(() => (init_recall(), recall_exports)),
|
|
4295
4644
|
Promise.resolve().then(() => (init_remember(), remember_exports)),
|
|
4296
4645
|
Promise.resolve().then(() => (init_upload_asset(), upload_asset_exports))
|
|
@@ -4301,6 +4650,10 @@ function createDefaultRegistry() {
|
|
|
4301
4650
|
if (m.tool) registry.register(m.tool);
|
|
4302
4651
|
})
|
|
4303
4652
|
);
|
|
4653
|
+
void Promise.resolve().then(() => (init_undo_redo(), undo_redo_exports)).then((m) => {
|
|
4654
|
+
registry.register(m.undoTool);
|
|
4655
|
+
registry.register(m.redoTool);
|
|
4656
|
+
});
|
|
4304
4657
|
return registry;
|
|
4305
4658
|
}
|
|
4306
4659
|
|