dominus-cli 0.5.1 → 0.5.3

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.
@@ -14,6 +14,70 @@ local IGNORED_PROPERTIES = {
14
14
  Archivable = true,
15
15
  }
16
16
 
17
+ -- Properties that are read-only / computed / redundant — strip in compact mode
18
+ local COMPACT_SKIP = {
19
+ -- Read-only computed
20
+ AbsolutePosition = true,
21
+ AbsoluteSize = true,
22
+ AbsoluteRotation = true,
23
+ AbsoluteCanvasSize = true,
24
+ TextBounds = true,
25
+ TextFits = true,
26
+ IsLoaded = true,
27
+ ContentText = true,
28
+ LocalizedText = true,
29
+ GuiState = true,
30
+ -- Deprecated / redundant (BrickColor duplicates Color3, Font duplicates FontFace)
31
+ BackgroundColor = true,
32
+ BorderColor = true,
33
+ TextColor = true,
34
+ Font = true,
35
+ FontSize = true,
36
+ -- Internal / security
37
+ Capabilities = true,
38
+ Sandboxed = true,
39
+ archivable = true,
40
+ className = true,
41
+ Localize = true,
42
+ -- Selection navigation (almost always nil/default)
43
+ NextSelectionDown = true,
44
+ NextSelectionLeft = true,
45
+ NextSelectionRight = true,
46
+ NextSelectionUp = true,
47
+ SelectionBehaviorDown = true,
48
+ SelectionBehaviorLeft = true,
49
+ SelectionBehaviorRight = true,
50
+ SelectionBehaviorUp = true,
51
+ SelectionGroup = true,
52
+ SelectionOrder = true,
53
+ SelectionImageObject = true,
54
+ -- Rarely useful defaults
55
+ Draggable = true,
56
+ InputSink = true,
57
+ RootLocalizationTable = true,
58
+ AutoLocalize = true,
59
+ OpenTypeFeatures = true,
60
+ OpenTypeFeaturesError = true,
61
+ Interactable = true,
62
+ Style = true,
63
+ BorderMode = true,
64
+ SizeConstraint = true,
65
+ }
66
+
67
+ -- Default values that are not worth reporting in compact mode
68
+ local COMPACT_DEFAULT_VALUES = {
69
+ ["0"] = true,
70
+ ["1"] = true,
71
+ ["false"] = true,
72
+ ["nil"] = true,
73
+ [""] = true,
74
+ ["Enum.AutomaticSize.None"] = true,
75
+ ["Enum.TextTruncate.None"] = true,
76
+ ["Enum.TextDirection.Auto"] = true,
77
+ ["Enum.ResamplerMode.Default"] = true,
78
+ ["Enum.ScaleType.Stretch"] = true,
79
+ }
80
+
17
81
  -- Cache property type maps per class to avoid repeated reflection calls
18
82
  local typeCache = {}
19
83
 
@@ -88,12 +152,54 @@ function Properties.get(path)
88
152
  return { properties = properties }
89
153
  end
90
154
 
91
- function Properties.getDescendants(path)
155
+ function Properties.getDescendants(path, compact)
92
156
  local rootInstance = Explorer.resolveInstance(path)
93
157
  if not rootInstance then
94
158
  return { success = false, error = "Instance not found: " .. path }
95
159
  end
96
160
 
161
+ -- In compact mode, skip noisy/default properties to reduce payload size
162
+ local shouldSkip = compact
163
+ and function(propName, valueStr)
164
+ if COMPACT_SKIP[propName] then
165
+ return true
166
+ end
167
+ -- Skip nil-valued properties
168
+ if valueStr == "nil" then
169
+ return true
170
+ end
171
+ return false
172
+ end
173
+ or function()
174
+ return false
175
+ end
176
+
177
+ -- Extra compact filter: skip properties that are clearly defaults and non-informative
178
+ local isBoringDefault = compact
179
+ and function(propName, valueStr)
180
+ -- These specific properties at default values are noise
181
+ local boringAtDefault = {
182
+ Active = "false",
183
+ Selectable = "false",
184
+ ClipsDescendants = "false",
185
+ TextWrap = "false",
186
+ TextWrapped = "false",
187
+ RichText = "false",
188
+ TextScaled = "false",
189
+ Rotation = "0",
190
+ LayoutOrder = "0",
191
+ MaxVisibleGraphemes = "-1",
192
+ SliceScale = "1",
193
+ LineHeight = "1",
194
+ BorderSizePixel = "1",
195
+ Visible = "true",
196
+ }
197
+ return boringAtDefault[propName] == valueStr
198
+ end
199
+ or function()
200
+ return false
201
+ end
202
+
97
203
  local function getProps(instance)
98
204
  local properties = {}
99
205
 
@@ -101,17 +207,20 @@ function Properties.getDescendants(path)
101
207
  local info = {}
102
208
  local propData = ReflectionService:GetPropertiesOfClass(instance.ClassName)
103
209
  for _, prop in propData do
104
- if not IGNORED_PROPERTIES[prop.Name] then
210
+ if not IGNORED_PROPERTIES[prop.Name] and not shouldSkip(prop.Name, "") then
105
211
  local valueOk, value = pcall(function()
106
212
  return instance[prop.Name]
107
213
  end)
108
214
  if valueOk then
109
- table.insert(info, {
110
- name = prop.Name,
111
- value = tostring(value),
112
- type = prop.ValueType and tostring(prop.ValueType) or typeof(value),
113
- category = prop.Category or "Other",
114
- })
215
+ local valueStr = tostring(value)
216
+ if not shouldSkip(prop.Name, valueStr) and not isBoringDefault(prop.Name, valueStr) then
217
+ table.insert(info, {
218
+ name = prop.Name,
219
+ value = valueStr,
220
+ type = prop.ValueType and tostring(prop.ValueType) or typeof(value),
221
+ category = prop.Category or "Other",
222
+ })
223
+ end
115
224
  end
116
225
  end
117
226
  end
@@ -434,6 +434,19 @@ local function applyProperty(instance, key, value)
434
434
  end)
435
435
  end
436
436
 
437
+ local RESERVED_KEYS = {
438
+ ClassName = true,
439
+ className = true,
440
+ Name = true,
441
+ name = true,
442
+ Children = true,
443
+ children = true,
444
+ properties = true,
445
+ Properties = true,
446
+ props = true,
447
+ Props = true,
448
+ }
449
+
437
450
  local function buildNode(spec, parent, animate)
438
451
  local className = spec.ClassName or spec.className or "Frame"
439
452
  local name = spec.Name or spec.name or className
@@ -441,20 +454,25 @@ local function buildNode(spec, parent, animate)
441
454
  local instance = Instance.new(className)
442
455
  instance.Name = name
443
456
 
444
- -- Apply all properties
457
+ -- Apply flattened top-level properties
445
458
  for key, value in spec do
446
- if
447
- key ~= "ClassName"
448
- and key ~= "className"
449
- and key ~= "Name"
450
- and key ~= "name"
451
- and key ~= "Children"
452
- and key ~= "children"
453
- then
459
+ if not RESERVED_KEYS[key] then
454
460
  applyProperty(instance, key, value)
455
461
  end
456
462
  end
457
463
 
464
+ -- Also accept a nested "properties" / "Properties" / "props" bag for convenience.
465
+ -- This lets callers group properties explicitly without the key being misread
466
+ -- as an instance property name.
467
+ local propBag = spec.properties or spec.Properties or spec.props or spec.Props
468
+ if type(propBag) == "table" then
469
+ for key, value in propBag do
470
+ if not RESERVED_KEYS[key] then
471
+ applyProperty(instance, key, value)
472
+ end
473
+ end
474
+ end
475
+
458
476
  -- Set parent after properties to avoid unnecessary layout computations
459
477
  instance.Parent = parent
460
478
 
@@ -82,7 +82,11 @@ local function handleMessage(rawMessage)
82
82
  ts = os.clock(),
83
83
  }))
84
84
  elseif msgType == "cli:get:descendants:properties" then
85
- local result = Properties.getDescendants(payload.path)
85
+ local compact = payload.compact
86
+ if compact == nil then
87
+ compact = true
88
+ end -- default to compact
89
+ local result = Properties.getDescendants(payload.path, compact)
86
90
  WsClient.send(Protocol.encode({
87
91
  id = msgId,
88
92
  type = "studio:response",