dominus-cli 0.5.5 → 0.5.7
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 +27 -181
- package/dist/index.js.map +1 -1
- package/dist/mcp.js +15 -187
- package/dist/mcp.js.map +1 -1
- package/package.json +1 -1
package/dist/mcp.js
CHANGED
|
@@ -41,13 +41,7 @@ var CliMsg = {
|
|
|
41
41
|
EXECUTE_PLAY_TEST: "cli:test:play",
|
|
42
42
|
BUILD_UI: "cli:build:ui",
|
|
43
43
|
GET_REFLECTION: "cli:get:reflection",
|
|
44
|
-
SERIALIZE_UI: "cli:serialize:ui"
|
|
45
|
-
MOVE_INSTANCE: "cli:move:instance",
|
|
46
|
-
UNDO: "cli:undo",
|
|
47
|
-
REDO: "cli:redo",
|
|
48
|
-
BULK_SET_PROPERTIES: "cli:bulk:set:properties",
|
|
49
|
-
FIND_REPLACE_SCRIPTS: "cli:find:replace:scripts"
|
|
50
|
-
};
|
|
44
|
+
SERIALIZE_UI: "cli:serialize:ui"};
|
|
51
45
|
function createMessage(type, payload) {
|
|
52
46
|
return { id: nanoid(), type, payload, ts: Date.now() };
|
|
53
47
|
}
|
|
@@ -667,8 +661,20 @@ These are built-in lessons that ship with Dominus. Follow them exactly.
|
|
|
667
661
|
- Full UI tree \u2192 \`create_ui\` (one call, never loop \`insert_instance\` for UI)
|
|
668
662
|
- **Convert/export existing UI \u2192 \`serialize_ui\`** (NOT get_descendants_properties)
|
|
669
663
|
- Adjusting an existing instance \u2192 \`set_properties\` (not \`run_code\`)
|
|
664
|
+
- **Inspecting user's selection \u2192 \`get_selection\`, then \`get_properties\` or \`serialize_ui\`**
|
|
665
|
+
- **Reading properties \u2192 \`get_properties\` (NEVER \`run_code\` with dump scripts)**
|
|
666
|
+
- **Browsing the tree \u2192 \`get_explorer\`**
|
|
670
667
|
- Anything exotic or procedural \u2192 \`run_code\` as last resort
|
|
671
668
|
|
|
669
|
+
### NEVER use run_code for:
|
|
670
|
+
- Getting properties of an instance \u2192 use \`get_properties\` or \`serialize_ui\`
|
|
671
|
+
- Dumping selection info \u2192 use \`get_selection\` + \`get_properties\`
|
|
672
|
+
- Creating instances \u2192 use \`create_part\`, \`create_ui\`, \`insert_instance\`, \`build_multiple\`
|
|
673
|
+
- Modifying properties \u2192 use \`set_properties\` or \`bulk_set_properties\`
|
|
674
|
+
- Reading scripts \u2192 use \`read_script\`
|
|
675
|
+
- Browsing the explorer \u2192 use \`get_explorer\`
|
|
676
|
+
\`run_code\` is ONLY for procedural logic, terrain generation, raycasts, physics queries, or custom algorithms with no tool equivalent.
|
|
677
|
+
|
|
672
678
|
### Verification habits
|
|
673
679
|
- After a build, call \`get_explorer\` or \`get_selection\` to confirm the tree looks right.
|
|
674
680
|
- After editing a script, read it back.
|
|
@@ -747,7 +753,7 @@ async function startMcpServer() {
|
|
|
747
753
|
);
|
|
748
754
|
mcp.tool(
|
|
749
755
|
"run_code",
|
|
750
|
-
"Execute Luau code in Roblox Studio
|
|
756
|
+
"Execute arbitrary Luau code in Roblox Studio. LAST RESORT \u2014 only use when no dedicated tool exists. Do NOT use for: reading properties (use get_properties/get_selection/serialize_ui), creating instances (use create_part/create_ui/insert_instance/build_multiple), modifying properties (use set_properties/bulk_set_properties), or inspecting the tree (use get_explorer). Valid uses: complex procedural generation, terrain algorithms, raycasting, custom logic with no tool equivalent.",
|
|
751
757
|
{ code: z.string().describe("Luau code to execute") },
|
|
752
758
|
async ({ code }) => {
|
|
753
759
|
assertConnected();
|
|
@@ -843,7 +849,7 @@ async function startMcpServer() {
|
|
|
843
849
|
);
|
|
844
850
|
mcp.tool(
|
|
845
851
|
"get_selection",
|
|
846
|
-
|
|
852
|
+
'Get the currently selected instances in Roblox Studio. Returns paths and class names of all selected objects. Use this FIRST when the user says "my selection" or "what I have selected". Then use get_properties or serialize_ui on the returned paths to inspect details.',
|
|
847
853
|
{},
|
|
848
854
|
async () => {
|
|
849
855
|
assertConnected();
|
|
@@ -1118,184 +1124,6 @@ async function startMcpServer() {
|
|
|
1118
1124
|
return { content: [{ type: "text", text: JSON.stringify(res.payload.tree, null, 2) }] };
|
|
1119
1125
|
}
|
|
1120
1126
|
);
|
|
1121
|
-
mcp.tool(
|
|
1122
|
-
"move_instance",
|
|
1123
|
-
"Move (reparent) an instance to a new parent in Roblox Studio. Preserves the instance and all descendants \u2014 much better than delete + recreate. Sets a ChangeHistoryService waypoint so the move can be undone.",
|
|
1124
|
-
{
|
|
1125
|
-
path: z.string().describe('Full path of the instance to move (e.g. "Workspace.OldFolder.MyPart")'),
|
|
1126
|
-
newParent: z.string().describe('Full path of the new parent (e.g. "Workspace.NewFolder")')
|
|
1127
|
-
},
|
|
1128
|
-
async ({ path: path2, newParent }) => {
|
|
1129
|
-
assertConnected();
|
|
1130
|
-
const res = await bridge.sendRequest(
|
|
1131
|
-
CliMsg.MOVE_INSTANCE,
|
|
1132
|
-
{ path: path2, newParent }
|
|
1133
|
-
);
|
|
1134
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
1135
|
-
}
|
|
1136
|
-
);
|
|
1137
|
-
mcp.tool(
|
|
1138
|
-
"bulk_set_properties",
|
|
1139
|
-
"Set properties on multiple instances at once in a single call. Much faster than calling set_properties repeatedly. Two modes:\n1. Explicit: provide targets array of {path, properties} objects\n2. Filter: provide root + className + properties to apply to all matches",
|
|
1140
|
-
{
|
|
1141
|
-
targets: z.array(z.object({
|
|
1142
|
-
path: z.string(),
|
|
1143
|
-
properties: z.record(z.unknown())
|
|
1144
|
-
})).optional().describe("Array of {path, properties} for explicit mode"),
|
|
1145
|
-
root: z.string().optional().describe("Root path to search under (filter mode)"),
|
|
1146
|
-
className: z.string().optional().describe("Only apply to instances of this ClassName (filter mode)"),
|
|
1147
|
-
properties: z.record(z.unknown()).optional().describe("Properties to set on all matches (filter mode)")
|
|
1148
|
-
},
|
|
1149
|
-
async (params) => {
|
|
1150
|
-
assertConnected();
|
|
1151
|
-
const res = await bridge.sendRequest(
|
|
1152
|
-
CliMsg.BULK_SET_PROPERTIES,
|
|
1153
|
-
{
|
|
1154
|
-
targets: params.targets,
|
|
1155
|
-
root: params.root,
|
|
1156
|
-
className: params.className,
|
|
1157
|
-
properties: params.properties
|
|
1158
|
-
},
|
|
1159
|
-
1e3 * 60
|
|
1160
|
-
);
|
|
1161
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
1162
|
-
}
|
|
1163
|
-
);
|
|
1164
|
-
mcp.tool(
|
|
1165
|
-
"find_replace_scripts",
|
|
1166
|
-
"Find and replace text across all scripts in the game (or under a root path). Supports plain text and Lua patterns. Use dryRun=true to preview changes without applying.",
|
|
1167
|
-
{
|
|
1168
|
-
find: z.string().describe("Text or Lua pattern to search for"),
|
|
1169
|
-
replace: z.string().describe("Replacement text (supports Lua pattern captures like %1, %2)"),
|
|
1170
|
-
root: z.string().optional().describe("Root path to limit search scope (optional)"),
|
|
1171
|
-
usePattern: z.boolean().optional().default(false).describe("Treat find/replace as Lua patterns"),
|
|
1172
|
-
dryRun: z.boolean().optional().default(false).describe("Preview matches without modifying scripts")
|
|
1173
|
-
},
|
|
1174
|
-
async (params) => {
|
|
1175
|
-
assertConnected();
|
|
1176
|
-
const res = await bridge.sendRequest(
|
|
1177
|
-
CliMsg.FIND_REPLACE_SCRIPTS,
|
|
1178
|
-
{
|
|
1179
|
-
find: params.find,
|
|
1180
|
-
replace: params.replace,
|
|
1181
|
-
root: params.root,
|
|
1182
|
-
usePattern: params.usePattern,
|
|
1183
|
-
dryRun: params.dryRun
|
|
1184
|
-
},
|
|
1185
|
-
1e3 * 60 * 5
|
|
1186
|
-
);
|
|
1187
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
1188
|
-
}
|
|
1189
|
-
);
|
|
1190
|
-
mcp.tool(
|
|
1191
|
-
"undo",
|
|
1192
|
-
"Undo the last action in Roblox Studio (ChangeHistoryService). Works like Ctrl+Z. Use to roll back mistakes.",
|
|
1193
|
-
{},
|
|
1194
|
-
async () => {
|
|
1195
|
-
assertConnected();
|
|
1196
|
-
const res = await bridge.sendRequest(CliMsg.UNDO, {});
|
|
1197
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload) }] };
|
|
1198
|
-
}
|
|
1199
|
-
);
|
|
1200
|
-
mcp.tool(
|
|
1201
|
-
"redo",
|
|
1202
|
-
"Redo the last undone action in Roblox Studio (ChangeHistoryService). Works like Ctrl+Y.",
|
|
1203
|
-
{},
|
|
1204
|
-
async () => {
|
|
1205
|
-
assertConnected();
|
|
1206
|
-
const res = await bridge.sendRequest(CliMsg.REDO, {});
|
|
1207
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload) }] };
|
|
1208
|
-
}
|
|
1209
|
-
);
|
|
1210
|
-
mcp.tool(
|
|
1211
|
-
"move_instance",
|
|
1212
|
-
"Move (reparent) an instance to a new parent in Roblox Studio. Preserves the instance and all descendants \u2014 much better than delete + recreate. Sets a ChangeHistoryService waypoint so the move can be undone.",
|
|
1213
|
-
{
|
|
1214
|
-
path: z.string().describe('Full path of the instance to move (e.g. "Workspace.OldFolder.MyPart")'),
|
|
1215
|
-
newParent: z.string().describe('Full path of the new parent (e.g. "Workspace.NewFolder")')
|
|
1216
|
-
},
|
|
1217
|
-
async ({ path: path2, newParent }) => {
|
|
1218
|
-
assertConnected();
|
|
1219
|
-
const res = await bridge.sendRequest(
|
|
1220
|
-
CliMsg.MOVE_INSTANCE,
|
|
1221
|
-
{ path: path2, newParent }
|
|
1222
|
-
);
|
|
1223
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
1224
|
-
}
|
|
1225
|
-
);
|
|
1226
|
-
mcp.tool(
|
|
1227
|
-
"bulk_set_properties",
|
|
1228
|
-
"Set properties on multiple instances at once in a single call. Much faster than calling set_properties repeatedly. Two modes:\n1. Explicit: provide targets array of {path, properties} objects\n2. Filter: provide root + className + properties to apply to all matches",
|
|
1229
|
-
{
|
|
1230
|
-
targets: z.array(z.object({
|
|
1231
|
-
path: z.string(),
|
|
1232
|
-
properties: z.record(z.unknown())
|
|
1233
|
-
})).optional().describe("Array of {path, properties} for explicit mode"),
|
|
1234
|
-
root: z.string().optional().describe("Root path to search under (filter mode)"),
|
|
1235
|
-
className: z.string().optional().describe("Only apply to instances of this ClassName (filter mode)"),
|
|
1236
|
-
properties: z.record(z.unknown()).optional().describe("Properties to set on all matches (filter mode)")
|
|
1237
|
-
},
|
|
1238
|
-
async (params) => {
|
|
1239
|
-
assertConnected();
|
|
1240
|
-
const res = await bridge.sendRequest(
|
|
1241
|
-
CliMsg.BULK_SET_PROPERTIES,
|
|
1242
|
-
{
|
|
1243
|
-
targets: params.targets,
|
|
1244
|
-
root: params.root,
|
|
1245
|
-
className: params.className,
|
|
1246
|
-
properties: params.properties
|
|
1247
|
-
},
|
|
1248
|
-
1e3 * 60
|
|
1249
|
-
);
|
|
1250
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
1251
|
-
}
|
|
1252
|
-
);
|
|
1253
|
-
mcp.tool(
|
|
1254
|
-
"find_replace_scripts",
|
|
1255
|
-
"Find and replace text across all scripts in the game (or under a root path). Supports plain text and Lua patterns. Use dryRun=true to preview changes without applying.",
|
|
1256
|
-
{
|
|
1257
|
-
find: z.string().describe("Text or Lua pattern to search for"),
|
|
1258
|
-
replace: z.string().describe("Replacement text (supports Lua pattern captures like %1, %2)"),
|
|
1259
|
-
root: z.string().optional().describe("Root path to limit search scope (optional)"),
|
|
1260
|
-
usePattern: z.boolean().optional().default(false).describe("Treat find/replace as Lua patterns"),
|
|
1261
|
-
dryRun: z.boolean().optional().default(false).describe("Preview matches without modifying scripts")
|
|
1262
|
-
},
|
|
1263
|
-
async (params) => {
|
|
1264
|
-
assertConnected();
|
|
1265
|
-
const res = await bridge.sendRequest(
|
|
1266
|
-
CliMsg.FIND_REPLACE_SCRIPTS,
|
|
1267
|
-
{
|
|
1268
|
-
find: params.find,
|
|
1269
|
-
replace: params.replace,
|
|
1270
|
-
root: params.root,
|
|
1271
|
-
usePattern: params.usePattern,
|
|
1272
|
-
dryRun: params.dryRun
|
|
1273
|
-
},
|
|
1274
|
-
1e3 * 60 * 5
|
|
1275
|
-
);
|
|
1276
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
|
|
1277
|
-
}
|
|
1278
|
-
);
|
|
1279
|
-
mcp.tool(
|
|
1280
|
-
"undo",
|
|
1281
|
-
"Undo the last action in Roblox Studio (ChangeHistoryService). Works like Ctrl+Z. Use to roll back mistakes.",
|
|
1282
|
-
{},
|
|
1283
|
-
async () => {
|
|
1284
|
-
assertConnected();
|
|
1285
|
-
const res = await bridge.sendRequest(CliMsg.UNDO, {});
|
|
1286
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload) }] };
|
|
1287
|
-
}
|
|
1288
|
-
);
|
|
1289
|
-
mcp.tool(
|
|
1290
|
-
"redo",
|
|
1291
|
-
"Redo the last undone action in Roblox Studio (ChangeHistoryService). Works like Ctrl+Y.",
|
|
1292
|
-
{},
|
|
1293
|
-
async () => {
|
|
1294
|
-
assertConnected();
|
|
1295
|
-
const res = await bridge.sendRequest(CliMsg.REDO, {});
|
|
1296
|
-
return { content: [{ type: "text", text: JSON.stringify(res.payload) }] };
|
|
1297
|
-
}
|
|
1298
|
-
);
|
|
1299
1127
|
mcp.tool(
|
|
1300
1128
|
"recall_memory",
|
|
1301
1129
|
"Search persistent memory for facts about the current Roblox project",
|