dominus-cli 0.5.2 → 0.5.4

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 CHANGED
@@ -678,6 +678,7 @@ These are built-in lessons that ship with Dominus. Follow them exactly.
678
678
  - Single 3D part \u2192 \`create_part\`
679
679
  - Many 3D parts (tree, building, vehicle) \u2192 \`build_multiple\` with \`groupName\`
680
680
  - Full UI tree \u2192 \`create_ui\` (one call, never loop \`insert_instance\` for UI)
681
+ - **Convert/export existing UI \u2192 \`serialize_ui\`** (NOT get_descendants_properties)
681
682
  - Adjusting an existing instance \u2192 \`set_properties\` (not \`run_code\`)
682
683
  - Anything exotic or procedural \u2192 \`run_code\` as last resort
683
684
 
@@ -685,6 +686,23 @@ These are built-in lessons that ship with Dominus. Follow them exactly.
685
686
  - After a build, call \`get_explorer\` or \`get_selection\` to confirm the tree looks right.
686
687
  - After editing a script, read it back.
687
688
  - After \`run_code\`, check \`get_output\` for errors.
689
+
690
+ ### serialize_ui \u2014 the RIGHT tool for UI conversion
691
+ - **Use \`serialize_ui\` when converting existing UI to Roact/React/Fusion components.** It returns a minimal JSON tree with only non-default properties, already in JSON-friendly formats.
692
+ - **Do NOT use \`get_descendants_properties\` for UI conversion** \u2014 it returns a flat list with ~50+ properties per instance (including read-only, deprecated, nil, and default values), which bloats context and confuses conversion.
693
+ - \`serialize_ui\` output maps 1:1 to \`create_ui\` input \u2014 you can round-trip UI through it.
694
+ - The tree structure preserves parent-child hierarchy, so Roact/React children mapping is direct.
695
+
696
+ ### UI \u2192 Roact/React conversion cheat-sheet
697
+ - \`serialize_ui\` path \u2192 JSON tree \u2192 map each node to \`Roact.createElement(ClassName, props, childrenDict)\`
698
+ - UDim2 arrays \`[xS, xO, yS, yO]\` \u2192 \`UDim2.new(xS, xO, yS, yO)\`
699
+ - Color3 hex strings \u2192 \`Color3.fromHex("#RRGGBB")\`
700
+ - Vector2 arrays \u2192 \`Vector2.new(x, y)\`
701
+ - UDim arrays \u2192 \`UDim.new(s, o)\`
702
+ - Enum strings like \`"Center"\` \u2192 \`Enum.TextXAlignment.Center\`
703
+ - FontFace \u2192 \`Font.new(family, weight, style)\`
704
+ - UI modifiers (UICorner, UIStroke, UIGradient, UIListLayout, UIPadding) are CHILDREN not props
705
+ - Use instance Name as dictionary key in children table
688
706
  `;
689
707
  }
690
708
  });
@@ -1198,7 +1216,7 @@ var init_get_descendants_properties = __esm({
1198
1216
  init_protocol();
1199
1217
  tool6 = {
1200
1218
  name: "get_descendants_properties",
1201
- description: "Easily get all descendants of a UI instance (or any instance) and all of their properties.",
1219
+ description: "Easily get all descendants of a UI instance (or any instance) and all of their properties. By default uses compact mode which strips read-only, nil, deprecated, and default-valued properties to keep responses small.",
1202
1220
  parameters: {
1203
1221
  type: "object",
1204
1222
  properties: {
@@ -1206,6 +1224,10 @@ var init_get_descendants_properties = __esm({
1206
1224
  type: "string",
1207
1225
  description: 'Full instance path (e.g., "Workspace.Part", "StarterGui.ScreenGui")'
1208
1226
  },
1227
+ compact: {
1228
+ type: "boolean",
1229
+ description: "When true (default), strips read-only, nil, deprecated, and default-valued properties to massively reduce response size. Set to false for full property dump."
1230
+ },
1209
1231
  outputFile: {
1210
1232
  type: "string",
1211
1233
  description: "Optional file path to write the JSON result to, useful for very large trees where context limits apply."
@@ -1217,9 +1239,10 @@ var init_get_descendants_properties = __esm({
1217
1239
  if (!ctx.isStudioConnected()) {
1218
1240
  return { success: false, error: "Studio is not connected" };
1219
1241
  }
1242
+ const compact = params.compact !== false;
1220
1243
  const response = await ctx.sendToStudio(
1221
1244
  CliMsg.GET_DESCENDANTS_PROPERTIES,
1222
- { path: params.path },
1245
+ { path: params.path, compact },
1223
1246
  1e3 * 60 * 5
1224
1247
  // 5 minute timeout since getting ALL descendants can take a very long time
1225
1248
  );
@@ -2623,14 +2646,15 @@ async function startMcpServer() {
2623
2646
  );
2624
2647
  mcp.tool(
2625
2648
  "get_descendants_properties",
2626
- "Easily get all descendants of a UI instance (or any instance) and all of their properties.",
2649
+ "Easily get all descendants of a UI instance (or any instance) and all of their properties. By default uses compact mode which strips read-only, nil, deprecated, and default-valued properties to keep responses small.",
2627
2650
  {
2628
2651
  path: z.string().describe('Full instance path (e.g., "Workspace.Part", "StarterGui.ScreenGui")'),
2652
+ compact: z.boolean().optional().default(true).describe("Strip noisy/default properties (default true). Set false for full dump."),
2629
2653
  outputFile: z.string().optional().describe("Optional file path to write to prevent limit errors/timeouts")
2630
2654
  },
2631
- async ({ path: path5, outputFile }) => {
2655
+ async ({ path: path5, compact, outputFile }) => {
2632
2656
  assertConnected();
2633
- const res = await bridge.sendRequest(CliMsg.GET_DESCENDANTS_PROPERTIES, { path: path5, outputFile }, 1e3 * 60 * 5);
2657
+ const res = await bridge.sendRequest(CliMsg.GET_DESCENDANTS_PROPERTIES, { path: path5, compact, outputFile }, 1e3 * 60 * 5);
2634
2658
  return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
2635
2659
  }
2636
2660
  );
@@ -2947,6 +2971,26 @@ async function startMcpServer() {
2947
2971
  return { content: [{ type: "text", text: JSON.stringify(res.payload, null, 2) }] };
2948
2972
  }
2949
2973
  );
2974
+ mcp.tool(
2975
+ "serialize_ui",
2976
+ "Serialize an existing Roblox UI tree into a compact, create_ui-compatible JSON tree. This is the reverse of create_ui \u2014 reads any GUI instance and returns a declarative JSON tree with ClassName, Name, non-default properties (Color3 as hex, UDim2 as arrays, etc.), and Children. Perfect for: converting existing UI to Roact/React components, cloning/templating, understanding UI structure, or refactoring. Use this INSTEAD of get_descendants_properties when you need to recreate or convert UI.",
2977
+ {
2978
+ path: z.string().describe('Instance path to serialize (e.g. "StarterGui.MyScreenGui")'),
2979
+ maxDepth: z.number().optional().default(50).describe("Maximum tree depth (default 50)")
2980
+ },
2981
+ async ({ path: path5, maxDepth }) => {
2982
+ assertConnected();
2983
+ const res = await bridge.sendRequest(
2984
+ CliMsg.SERIALIZE_UI,
2985
+ { path: path5, maxDepth },
2986
+ 1e3 * 60 * 2
2987
+ );
2988
+ if (!res.payload.success) {
2989
+ return { content: [{ type: "text", text: `Error: ${res.payload.error ?? "Serialization failed"}` }] };
2990
+ }
2991
+ return { content: [{ type: "text", text: JSON.stringify(res.payload.tree, null, 2) }] };
2992
+ }
2993
+ );
2950
2994
  mcp.tool(
2951
2995
  "recall_memory",
2952
2996
  "Search persistent memory for facts about the current Roblox project",
@@ -4347,6 +4391,66 @@ GUI classes use DIFFERENT property types than 3D parts:
4347
4391
  - All enum properties from string names
4348
4392
  - Color3 from hex "#RRGGBB", "rgb(r,g,b)", or BrickColor name strings
4349
4393
 
4394
+ ## Serializing & Converting Existing UI
4395
+ When the user asks to convert, export, recreate, or turn an existing UI into a React/Roact component:
4396
+
4397
+ **Use \`serialize_ui\` \u2014 NOT \`get_descendants_properties\`.**
4398
+ \`serialize_ui\` returns a clean, minimal JSON tree with only non-default properties, values already in JSON-friendly formats (hex colors, UDim2 arrays, enum names), and a proper parent-child hierarchy. It's purpose-built for this exact workflow.
4399
+
4400
+ \`get_descendants_properties\` returns a flat list with ALL properties (including read-only, defaults, deprecated) \u2014 it's much larger and harder to convert.
4401
+
4402
+ ### Roblox UI \u2192 Roact/React Conversion Workflow
4403
+ 1. Call \`serialize_ui\` with the path (e.g. \`StarterGui.MyScreenGui.MyFrame\`)
4404
+ 2. The result is a tree like:
4405
+ \`\`\`json
4406
+ {
4407
+ "ClassName": "Frame", "Name": "MyFrame",
4408
+ "Size": [0.5, 0, 0.3, 0], "BackgroundColor3": "#1a1a2e",
4409
+ "Children": [
4410
+ { "ClassName": "UICorner", "CornerRadius": [0, 8] },
4411
+ { "ClassName": "TextLabel", "Name": "Title", "Text": "Hello",
4412
+ "Size": [1, 0, 0.2, 0], "TextColor3": "#ffffff", "BackgroundTransparency": 1 }
4413
+ ]
4414
+ }
4415
+ \`\`\`
4416
+ 3. Convert to Roact/React-lua using these mappings:
4417
+ - Each JSON node \u2192 \`Roact.createElement(ClassName, props, children)\` or \`React.createElement\`
4418
+ - \`UDim2\` arrays \`[xS, xO, yS, yO]\` \u2192 \`UDim2.new(xS, xO, yS, yO)\`
4419
+ - \`Color3\` hex \`"#RRGGBB"\` \u2192 \`Color3.fromHex("#RRGGBB")\`
4420
+ - \`Vector2\` arrays \`[x, y]\` \u2192 \`Vector2.new(x, y)\`
4421
+ - \`UDim\` arrays \`[s, o]\` \u2192 \`UDim.new(s, o)\`
4422
+ - Enum strings \`"Center"\` \u2192 \`Enum.TextXAlignment.Center\` (resolve the full enum path)
4423
+ - \`Children\` array \u2192 child elements table
4424
+ - UI modifiers (UICorner, UIStroke, UIGradient, UIListLayout, UIPadding, UIScale) \u2192 children of the parent element
4425
+
4426
+ ### Example Roact output:
4427
+ \`\`\`lua
4428
+ local function MyFrame()
4429
+ return Roact.createElement("Frame", {
4430
+ Size = UDim2.new(0.5, 0, 0.3, 0),
4431
+ BackgroundColor3 = Color3.fromHex("#1a1a2e"),
4432
+ }, {
4433
+ Corner = Roact.createElement("UICorner", {
4434
+ CornerRadius = UDim.new(0, 8),
4435
+ }),
4436
+ Title = Roact.createElement("TextLabel", {
4437
+ Size = UDim2.new(1, 0, 0.2, 0),
4438
+ Text = "Hello",
4439
+ TextColor3 = Color3.fromHex("#ffffff"),
4440
+ BackgroundTransparency = 1,
4441
+ }),
4442
+ })
4443
+ end
4444
+ \`\`\`
4445
+
4446
+ ### Key rules for conversion:
4447
+ - Use the instance \`Name\` as the dictionary key in the children table
4448
+ - UI modifiers (UICorner, UIStroke, etc.) are CHILDREN, not props
4449
+ - Keep the exact property values from serialize_ui \u2014 don't guess or approximate
4450
+ - For Fusion: \`New "Frame" { Size = UDim2.new(...), [Children] = { ... } }\`
4451
+ - Preserve ZIndex ordering when relevant
4452
+ - FontFace objects \u2192 \`Font.new("rbxasset://fonts/families/...", Enum.FontWeight.Bold)\`
4453
+
4350
4454
  ## ReflectionService
4351
4455
  The \`get_class_info\` tool queries Roblox's ReflectionService to return the complete API surface for any class:
4352
4456
  - All properties with their exact ValueType