@akiojin/unity-mcp-server 2.16.0 → 2.25.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.
Files changed (135) hide show
  1. package/LICENSE +0 -0
  2. package/README.md +153 -100
  3. package/bin/unity-mcp-server +7 -1
  4. package/package.json +30 -7
  5. package/src/core/codeIndex.js +0 -0
  6. package/src/core/codeIndexDb.js +0 -0
  7. package/src/core/config.js +47 -14
  8. package/src/core/indexWatcher.js +84 -15
  9. package/src/core/jobManager.js +178 -0
  10. package/src/core/projectInfo.js +21 -67
  11. package/src/core/server.js +15 -2
  12. package/src/core/unityConnection.js +0 -0
  13. package/src/handlers/addressables/AddressablesAnalyzeToolHandler.js +170 -0
  14. package/src/handlers/addressables/AddressablesBuildToolHandler.js +145 -0
  15. package/src/handlers/addressables/AddressablesManageToolHandler.js +266 -0
  16. package/src/handlers/analysis/AnalyzeSceneContentsToolHandler.js +1 -1
  17. package/src/handlers/analysis/FindByComponentToolHandler.js +2 -2
  18. package/src/handlers/analysis/GetAnimatorStateToolHandler.js +1 -1
  19. package/src/handlers/analysis/GetComponentValuesToolHandler.js +2 -2
  20. package/src/handlers/analysis/GetGameObjectDetailsToolHandler.js +1 -1
  21. package/src/handlers/analysis/GetInputActionsStateToolHandler.js +1 -1
  22. package/src/handlers/analysis/GetObjectReferencesToolHandler.js +2 -2
  23. package/src/handlers/asset/{AssetDatabaseToolHandler.js → AssetDatabaseManageToolHandler.js} +2 -2
  24. package/src/handlers/asset/{AssetDependencyToolHandler.js → AssetDependencyAnalyzeToolHandler.js} +2 -2
  25. package/src/handlers/asset/{AssetImportSettingsToolHandler.js → AssetImportSettingsManageToolHandler.js} +2 -2
  26. package/src/handlers/asset/{CreateMaterialToolHandler.js → AssetMaterialCreateToolHandler.js} +2 -2
  27. package/src/handlers/asset/{ModifyMaterialToolHandler.js → AssetMaterialModifyToolHandler.js} +2 -2
  28. package/src/handlers/asset/{CreatePrefabToolHandler.js → AssetPrefabCreateToolHandler.js} +2 -2
  29. package/src/handlers/asset/{ExitPrefabModeToolHandler.js → AssetPrefabExitModeToolHandler.js} +2 -2
  30. package/src/handlers/asset/{InstantiatePrefabToolHandler.js → AssetPrefabInstantiateToolHandler.js} +2 -2
  31. package/src/handlers/asset/{ModifyPrefabToolHandler.js → AssetPrefabModifyToolHandler.js} +2 -2
  32. package/src/handlers/asset/{OpenPrefabToolHandler.js → AssetPrefabOpenToolHandler.js} +2 -2
  33. package/src/handlers/asset/{SavePrefabToolHandler.js → AssetPrefabSaveToolHandler.js} +2 -2
  34. package/src/handlers/base/BaseToolHandler.js +0 -0
  35. package/src/handlers/compilation/{GetCompilationStateToolHandler.js → CompilationGetStateToolHandler.js} +2 -2
  36. package/src/handlers/component/{AddComponentToolHandler.js → ComponentAddToolHandler.js} +2 -2
  37. package/src/handlers/component/ComponentFieldSetToolHandler.js +419 -0
  38. package/src/handlers/component/{GetComponentTypesToolHandler.js → ComponentGetTypesToolHandler.js} +2 -2
  39. package/src/handlers/component/{ListComponentsToolHandler.js → ComponentListToolHandler.js} +2 -2
  40. package/src/handlers/component/{ModifyComponentToolHandler.js → ComponentModifyToolHandler.js} +2 -2
  41. package/src/handlers/component/{RemoveComponentToolHandler.js → ComponentRemoveToolHandler.js} +2 -2
  42. package/src/handlers/console/{ClearConsoleToolHandler.js → ConsoleClearToolHandler.js} +2 -2
  43. package/src/handlers/console/{ReadConsoleToolHandler.js → ConsoleReadToolHandler.js} +83 -64
  44. package/src/handlers/editor/{LayerManagementToolHandler.js → EditorLayersManageToolHandler.js} +2 -2
  45. package/src/handlers/editor/{SelectionToolHandler.js → EditorSelectionManageToolHandler.js} +2 -2
  46. package/src/handlers/editor/{TagManagementToolHandler.js → EditorTagsManageToolHandler.js} +2 -2
  47. package/src/handlers/editor/{ToolManagementToolHandler.js → EditorToolsManageToolHandler.js} +2 -2
  48. package/src/handlers/editor/{WindowManagementToolHandler.js → EditorWindowsManageToolHandler.js} +2 -2
  49. package/src/handlers/gameobject/{CreateGameObjectToolHandler.js → GameObjectCreateToolHandler.js} +3 -3
  50. package/src/handlers/gameobject/{DeleteGameObjectToolHandler.js → GameObjectDeleteToolHandler.js} +3 -3
  51. package/src/handlers/gameobject/{FindGameObjectToolHandler.js → GameObjectFindToolHandler.js} +3 -3
  52. package/src/handlers/gameobject/{GetHierarchyToolHandler.js → GameObjectGetHierarchyToolHandler.js} +3 -3
  53. package/src/handlers/gameobject/{ModifyGameObjectToolHandler.js → GameObjectModifyToolHandler.js} +3 -3
  54. package/src/handlers/index.js +331 -293
  55. package/src/handlers/input/{AddInputActionToolHandler.js → InputActionAddToolHandler.js} +2 -2
  56. package/src/handlers/input/{CreateActionMapToolHandler.js → InputActionMapCreateToolHandler.js} +2 -2
  57. package/src/handlers/input/{RemoveActionMapToolHandler.js → InputActionMapRemoveToolHandler.js} +2 -2
  58. package/src/handlers/input/{RemoveInputActionToolHandler.js → InputActionRemoveToolHandler.js} +2 -2
  59. package/src/handlers/input/{AddInputBindingToolHandler.js → InputBindingAddToolHandler.js} +2 -2
  60. package/src/handlers/input/{CreateCompositeBindingToolHandler.js → InputBindingCompositeCreateToolHandler.js} +2 -2
  61. package/src/handlers/input/{RemoveAllBindingsToolHandler.js → InputBindingRemoveAllToolHandler.js} +2 -2
  62. package/src/handlers/input/{RemoveInputBindingToolHandler.js → InputBindingRemoveToolHandler.js} +2 -2
  63. package/src/handlers/input/{ManageControlSchemesToolHandler.js → InputControlSchemesManageToolHandler.js} +2 -2
  64. package/src/handlers/input/{GamepadSimulationHandler.js → InputGamepadSimulateToolHandler.js} +3 -3
  65. package/src/handlers/input/{KeyboardSimulationHandler.js → InputKeyboardSimulateToolHandler.js} +3 -3
  66. package/src/handlers/input/{MouseSimulationHandler.js → InputMouseSimulateToolHandler.js} +3 -3
  67. package/src/handlers/input/{InputSystemHandler.js → InputSystemControlToolHandler.js} +4 -4
  68. package/src/handlers/input/{TouchSimulationHandler.js → InputTouchSimulateToolHandler.js} +3 -3
  69. package/src/handlers/menu/{ExecuteMenuItemToolHandler.js → MenuItemExecuteToolHandler.js} +2 -2
  70. package/src/handlers/package/PackageManagerToolHandler.js +1 -1
  71. package/src/handlers/package/RegistryConfigToolHandler.js +1 -1
  72. package/src/handlers/playmode/{GetEditorStateToolHandler.js → PlaymodeGetStateToolHandler.js} +3 -3
  73. package/src/handlers/playmode/{PauseToolHandler.js → PlaymodePauseToolHandler.js} +4 -4
  74. package/src/handlers/playmode/{PlayToolHandler.js → PlaymodePlayToolHandler.js} +4 -4
  75. package/src/handlers/playmode/{StopToolHandler.js → PlaymodeStopToolHandler.js} +4 -4
  76. package/src/handlers/playmode/{WaitForEditorStateToolHandler.js → PlaymodeWaitForStateToolHandler.js} +3 -3
  77. package/src/handlers/scene/GetSceneInfoToolHandler.js +1 -1
  78. package/src/handlers/scene/{CreateSceneToolHandler.js → SceneCreateToolHandler.js} +2 -2
  79. package/src/handlers/scene/{ListScenesToolHandler.js → SceneListToolHandler.js} +2 -2
  80. package/src/handlers/scene/{LoadSceneToolHandler.js → SceneLoadToolHandler.js} +2 -2
  81. package/src/handlers/scene/{SaveSceneToolHandler.js → SceneSaveToolHandler.js} +2 -2
  82. package/src/handlers/screenshot/{AnalyzeScreenshotToolHandler.js → ScreenshotAnalyzeToolHandler.js} +2 -2
  83. package/src/handlers/screenshot/{CaptureScreenshotToolHandler.js → ScreenshotCaptureToolHandler.js} +2 -2
  84. package/src/handlers/script/{BuildCodeIndexToolHandler.js → CodeIndexBuildToolHandler.js} +127 -17
  85. package/src/handlers/script/CodeIndexStatusToolHandler.js +129 -0
  86. package/src/handlers/script/CodeIndexUpdateToolHandler.js +234 -0
  87. package/src/handlers/script/{ScriptCreateClassFileToolHandler.js → ScriptCreateClassToolHandler.js} +2 -2
  88. package/src/handlers/script/ScriptEditSnippetToolHandler.js +272 -0
  89. package/src/handlers/script/ScriptEditStructuredToolHandler.js +1 -1
  90. package/src/handlers/script/ScriptPackagesListToolHandler.js +0 -0
  91. package/src/handlers/script/ScriptReadToolHandler.js +0 -0
  92. package/src/handlers/script/ScriptRefactorRenameToolHandler.js +0 -0
  93. package/src/handlers/script/ScriptRefsFindToolHandler.js +0 -0
  94. package/src/handlers/script/ScriptRemoveSymbolToolHandler.js +0 -0
  95. package/src/handlers/script/ScriptSearchToolHandler.js +0 -0
  96. package/src/handlers/script/ScriptSymbolFindToolHandler.js +0 -0
  97. package/src/handlers/script/ScriptSymbolsGetToolHandler.js +0 -0
  98. package/src/handlers/settings/{GetProjectSettingsToolHandler.js → SettingsGetToolHandler.js} +2 -2
  99. package/src/handlers/settings/{UpdateProjectSettingsToolHandler.js → SettingsUpdateToolHandler.js} +2 -2
  100. package/src/handlers/system/{GetCommandStatsToolHandler.js → SystemGetCommandStatsToolHandler.js} +2 -3
  101. package/src/handlers/system/{PingToolHandler.js → SystemPingToolHandler.js} +3 -3
  102. package/src/handlers/system/{RefreshAssetsToolHandler.js → SystemRefreshAssetsToolHandler.js} +3 -3
  103. package/src/handlers/test/{GetTestStatusToolHandler.js → TestGetStatusToolHandler.js} +2 -2
  104. package/src/handlers/test/{RunTestsToolHandler.js → TestRunToolHandler.js} +2 -2
  105. package/src/handlers/ui/{ClickUIElementToolHandler.js → UIClickElementToolHandler.js} +2 -2
  106. package/src/handlers/ui/{FindUIElementsToolHandler.js → UIFindElementsToolHandler.js} +2 -2
  107. package/src/handlers/ui/{GetUIElementStateToolHandler.js → UIGetElementStateToolHandler.js} +2 -2
  108. package/src/handlers/ui/{SetUIElementValueToolHandler.js → UISetElementValueToolHandler.js} +2 -2
  109. package/src/handlers/ui/{SimulateUIInputToolHandler.js → UISimulateInputToolHandler.js} +2 -2
  110. package/src/handlers/video/{CaptureVideoForToolHandler.js → VideoCaptureForToolHandler.js} +8 -8
  111. package/src/handlers/video/{CaptureVideoStartToolHandler.js → VideoCaptureStartToolHandler.js} +2 -2
  112. package/src/handlers/video/{CaptureVideoStatusToolHandler.js → VideoCaptureStatusToolHandler.js} +2 -2
  113. package/src/handlers/video/{CaptureVideoStopToolHandler.js → VideoCaptureStopToolHandler.js} +3 -3
  114. package/src/lsp/CSharpLspUtils.js +95 -14
  115. package/src/lsp/LspProcessManager.js +0 -0
  116. package/src/lsp/LspRpcClient.js +14 -0
  117. package/src/tools/analysis/analyzeSceneContents.js +3 -3
  118. package/src/tools/analysis/findByComponent.js +3 -3
  119. package/src/tools/analysis/getAnimatorState.js +6 -6
  120. package/src/tools/analysis/getComponentValues.js +3 -3
  121. package/src/tools/analysis/getGameObjectDetails.js +3 -3
  122. package/src/tools/analysis/getInputActionsState.js +4 -4
  123. package/src/tools/analysis/getObjectReferences.js +3 -3
  124. package/src/tools/input/inputActionsEditor.js +18 -18
  125. package/src/tools/scene/createScene.js +3 -3
  126. package/src/tools/scene/getSceneInfo.js +3 -3
  127. package/src/tools/scene/listScenes.js +3 -3
  128. package/src/tools/scene/loadScene.js +3 -3
  129. package/src/tools/scene/saveScene.js +3 -3
  130. package/src/tools/system/ping.js +5 -5
  131. package/src/tools/video/recordFor.js +2 -2
  132. package/src/tools/video/recordPlayMode.js +0 -0
  133. package/src/utils/csharpParse.js +0 -0
  134. package/src/utils/validators.js +0 -0
  135. package/src/handlers/script/ScriptIndexStatusToolHandler.js +0 -61
@@ -0,0 +1,419 @@
1
+ import { BaseToolHandler } from '../base/BaseToolHandler.js'
2
+
3
+ const VALUE_TYPE_ENUM = [
4
+ 'auto',
5
+ 'bool',
6
+ 'int',
7
+ 'long',
8
+ 'float',
9
+ 'double',
10
+ 'string',
11
+ 'color',
12
+ 'vector2',
13
+ 'vector3',
14
+ 'vector4',
15
+ 'vector2Int',
16
+ 'vector3Int',
17
+ 'quaternion',
18
+ 'rect',
19
+ 'rectInt',
20
+ 'bounds',
21
+ 'boundsInt',
22
+ 'enum',
23
+ 'objectReference',
24
+ 'array',
25
+ 'json',
26
+ 'null'
27
+ ]
28
+
29
+ function resolveScope(params) {
30
+ const hasSceneTarget =
31
+ typeof params.gameObjectPath === 'string' && params.gameObjectPath.length > 0
32
+ const hasPrefabTarget =
33
+ typeof params.prefabAssetPath === 'string' && params.prefabAssetPath.length > 0
34
+ const rawScope = params.scope ?? 'auto'
35
+
36
+ if (rawScope === 'auto') {
37
+ if (hasPrefabTarget && !hasSceneTarget) {
38
+ return 'prefabAsset'
39
+ }
40
+ return hasSceneTarget ? 'scene' : 'auto'
41
+ }
42
+
43
+ return rawScope
44
+ }
45
+
46
+ function normalizeFieldPath(fieldPath) {
47
+ if (!fieldPath || typeof fieldPath !== 'string') {
48
+ return fieldPath
49
+ }
50
+
51
+ let needsNormalization = false
52
+ for (let i = 0; i < fieldPath.length; i += 1) {
53
+ if (fieldPath[i] === '[') {
54
+ needsNormalization = true
55
+ break
56
+ }
57
+ }
58
+
59
+ if (!needsNormalization) {
60
+ return fieldPath
61
+ }
62
+
63
+ let result = ''
64
+ let i = 0
65
+
66
+ while (i < fieldPath.length) {
67
+ const char = fieldPath[i]
68
+ if (char === '[') {
69
+ let indexBuffer = ''
70
+ i += 1
71
+ while (i < fieldPath.length && fieldPath[i] !== ']') {
72
+ indexBuffer += fieldPath[i]
73
+ i += 1
74
+ }
75
+ // Skip closing bracket
76
+ if (i < fieldPath.length && fieldPath[i] === ']') {
77
+ i += 1
78
+ }
79
+
80
+ if (indexBuffer.length > 0) {
81
+ result += `.Array.data[${indexBuffer}]`
82
+ } else {
83
+ result += '.Array.data[0]'
84
+ }
85
+ } else {
86
+ result += char
87
+ i += 1
88
+ }
89
+ }
90
+
91
+ return result
92
+ }
93
+
94
+ function inferValueType(value) {
95
+ if (value === null) {
96
+ return 'null'
97
+ }
98
+
99
+ const valueType = typeof value
100
+ switch (valueType) {
101
+ case 'boolean':
102
+ return 'bool'
103
+ case 'number':
104
+ return Number.isInteger(value) ? 'int' : 'float'
105
+ case 'string':
106
+ return 'string'
107
+ case 'object':
108
+ if (Array.isArray(value)) {
109
+ return 'array'
110
+ }
111
+
112
+ if (['r', 'g', 'b'].every(key => Object.prototype.hasOwnProperty.call(value, key))) {
113
+ return Object.prototype.hasOwnProperty.call(value, 'a') ? 'color' : 'vector3'
114
+ }
115
+
116
+ if (['x', 'y', 'z', 'w'].every(key => Object.prototype.hasOwnProperty.call(value, key))) {
117
+ return 'vector4'
118
+ }
119
+
120
+ if (['x', 'y', 'z'].every(key => Object.prototype.hasOwnProperty.call(value, key))) {
121
+ return 'vector3'
122
+ }
123
+
124
+ if (['x', 'y'].every(key => Object.prototype.hasOwnProperty.call(value, key))) {
125
+ return 'vector2'
126
+ }
127
+
128
+ return 'json'
129
+ default:
130
+ return 'auto'
131
+ }
132
+ }
133
+
134
+ function isPlainObject(value) {
135
+ if (value === null || typeof value !== 'object') {
136
+ return false
137
+ }
138
+ const proto = Object.getPrototypeOf(value)
139
+ return proto === Object.prototype || proto === null
140
+ }
141
+
142
+ export class ComponentFieldSetToolHandler extends BaseToolHandler {
143
+ constructor(unityConnection) {
144
+ super(
145
+ 'component_field_set',
146
+ 'Update a serialized field on a component (scene hierarchy, prefab stage, or prefab asset).',
147
+ {
148
+ type: 'object',
149
+ additionalProperties: false,
150
+ properties: {
151
+ scope: {
152
+ type: 'string',
153
+ enum: ['auto', 'scene', 'prefabStage', 'prefabAsset'],
154
+ description:
155
+ 'Explicit scope for the operation. Use auto (default) to detect automatically.'
156
+ },
157
+ gameObjectPath: {
158
+ type: 'string',
159
+ description:
160
+ 'Absolute path to the target GameObject (e.g., "/Player/Weapon"). Required unless prefabAssetPath is provided.'
161
+ },
162
+ prefabAssetPath: {
163
+ type: 'string',
164
+ description: 'Asset path to the prefab to edit (e.g., "Assets/Prefabs/Enemy.prefab").'
165
+ },
166
+ prefabObjectPath: {
167
+ type: 'string',
168
+ description:
169
+ 'Path to the object inside the prefab asset (defaults to the prefab root when omitted).'
170
+ },
171
+ componentType: {
172
+ type: 'string',
173
+ description: 'Component type to edit (short name or fully qualified name).'
174
+ },
175
+ componentIndex: {
176
+ type: 'integer',
177
+ minimum: 0,
178
+ description:
179
+ 'Component index when multiple components of the same type are present. Default: 0.'
180
+ },
181
+ fieldPath: {
182
+ type: 'string',
183
+ description:
184
+ 'Serialized field path to update. Supports dot and bracket notation (e.g., "settings.speed", "items[0].damage").'
185
+ },
186
+ value: {
187
+ description:
188
+ 'New value for the field. Accepts JSON scalars, objects, or arrays depending on the target type.'
189
+ },
190
+ valueType: {
191
+ type: 'string',
192
+ enum: VALUE_TYPE_ENUM,
193
+ description: 'Type hint for the value. Defaults to auto detection.'
194
+ },
195
+ enumValue: {
196
+ type: 'string',
197
+ description:
198
+ 'Enum member name when setting enum fields (optional when value is already a string).'
199
+ },
200
+ objectReference: {
201
+ type: 'object',
202
+ additionalProperties: false,
203
+ properties: {
204
+ assetPath: {
205
+ type: 'string',
206
+ description: 'AssetDatabase path to load as an object reference.'
207
+ },
208
+ guid: {
209
+ type: 'string',
210
+ description: 'GUID of the asset to reference.'
211
+ }
212
+ },
213
+ description:
214
+ 'Explicit object reference payload. Provide assetPath or guid when setting object references.'
215
+ },
216
+ runtime: {
217
+ type: 'boolean',
218
+ description: 'Allow updates while Unity is in Play Mode (default: false).'
219
+ },
220
+ dryRun: {
221
+ type: 'boolean',
222
+ description: 'Validate target resolution and preview the change without applying it.'
223
+ },
224
+ applyPrefabChanges: {
225
+ type: 'boolean',
226
+ description:
227
+ 'When editing prefab assets, save the modified prefab asset. Defaults to true.'
228
+ },
229
+ createUndo: {
230
+ type: 'boolean',
231
+ description: 'Record an undo entry when modifying scene objects. Defaults to true.'
232
+ },
233
+ markSceneDirty: {
234
+ type: 'boolean',
235
+ description:
236
+ 'Mark the owning scene dirty when modifying scene objects. Defaults to true.'
237
+ }
238
+ },
239
+ required: ['componentType', 'fieldPath']
240
+ }
241
+ )
242
+
243
+ this.unityConnection = unityConnection
244
+ }
245
+
246
+ validate(params) {
247
+ super.validate(params)
248
+
249
+ const scope = resolveScope(params)
250
+ const hasSceneTarget =
251
+ typeof params.gameObjectPath === 'string' && params.gameObjectPath.length > 0
252
+ const hasPrefabTarget =
253
+ typeof params.prefabAssetPath === 'string' && params.prefabAssetPath.length > 0
254
+
255
+ if (!hasSceneTarget && !hasPrefabTarget) {
256
+ throw new Error('Either gameObjectPath or prefabAssetPath must be provided')
257
+ }
258
+
259
+ if (scope === 'prefabAsset' && !hasPrefabTarget) {
260
+ throw new Error('prefabAssetPath is required when scope is set to prefabAsset')
261
+ }
262
+
263
+ if (scope !== 'prefabAsset' && !hasSceneTarget && !params.dryRun) {
264
+ throw new Error('gameObjectPath is required when editing scene or prefab stage objects')
265
+ }
266
+
267
+ if (!params.dryRun && !Object.prototype.hasOwnProperty.call(params, 'value')) {
268
+ throw new Error('value is required unless dryRun is true')
269
+ }
270
+
271
+ if (params.componentIndex !== undefined && !Number.isInteger(params.componentIndex)) {
272
+ throw new Error('componentIndex must be an integer when provided')
273
+ }
274
+
275
+ if (params.objectReference !== undefined) {
276
+ if (!isPlainObject(params.objectReference)) {
277
+ throw new Error('objectReference must be an object when provided')
278
+ }
279
+
280
+ const { assetPath, guid } = params.objectReference
281
+ if (!assetPath && !guid) {
282
+ throw new Error('objectReference requires assetPath or guid')
283
+ }
284
+ }
285
+
286
+ if (params.runtime !== undefined && typeof params.runtime !== 'boolean') {
287
+ throw new Error('runtime must be a boolean when provided')
288
+ }
289
+ }
290
+
291
+ buildCommandParams(params) {
292
+ const command = {}
293
+
294
+ command.scope = resolveScope(params)
295
+
296
+ if (typeof params.gameObjectPath === 'string') {
297
+ command.gameObjectPath = params.gameObjectPath
298
+ }
299
+
300
+ if (typeof params.prefabAssetPath === 'string') {
301
+ command.prefabAssetPath = params.prefabAssetPath
302
+ }
303
+
304
+ if (typeof params.prefabObjectPath === 'string') {
305
+ command.prefabObjectPath = params.prefabObjectPath
306
+ }
307
+
308
+ command.componentType = params.componentType
309
+ command.fieldPath = params.fieldPath
310
+
311
+ const normalizedPath = normalizeFieldPath(params.fieldPath)
312
+ if (normalizedPath && normalizedPath !== params.fieldPath) {
313
+ command.serializedPropertyPath = normalizedPath
314
+ }
315
+
316
+ if (Object.prototype.hasOwnProperty.call(params, 'componentIndex')) {
317
+ command.componentIndex = params.componentIndex
318
+ }
319
+
320
+ if (Object.prototype.hasOwnProperty.call(params, 'value')) {
321
+ command.value = params.value
322
+ }
323
+
324
+ if (params.valueType) {
325
+ command.valueType = params.valueType
326
+ } else if (Object.prototype.hasOwnProperty.call(params, 'value')) {
327
+ command.valueType = inferValueType(params.value)
328
+ } else {
329
+ command.valueType = 'auto'
330
+ }
331
+
332
+ if (typeof params.enumValue === 'string') {
333
+ command.enumValue = params.enumValue
334
+ }
335
+
336
+ if (params.objectReference) {
337
+ command.objectReference = params.objectReference
338
+ }
339
+
340
+ if (params.runtime !== undefined) {
341
+ command.runtime = Boolean(params.runtime)
342
+ }
343
+
344
+ command.dryRun = Boolean(params.dryRun)
345
+
346
+ if (params.applyPrefabChanges !== undefined) {
347
+ command.applyPrefabChanges = Boolean(params.applyPrefabChanges)
348
+ }
349
+
350
+ if (params.createUndo !== undefined) {
351
+ command.createUndo = Boolean(params.createUndo)
352
+ }
353
+
354
+ if (params.markSceneDirty !== undefined) {
355
+ command.markSceneDirty = Boolean(params.markSceneDirty)
356
+ }
357
+
358
+ return command
359
+ }
360
+
361
+ async execute(params) {
362
+ if (!this.unityConnection.isConnected()) {
363
+ await this.unityConnection.connect()
364
+ }
365
+
366
+ const commandParams = this.buildCommandParams(params)
367
+ const response = await this.unityConnection.sendCommand('set_component_field', commandParams)
368
+
369
+ if (!response || typeof response !== 'object') {
370
+ throw new Error('Invalid response from Unity')
371
+ }
372
+
373
+ if (response.error) {
374
+ throw new Error(response.error)
375
+ }
376
+
377
+ return response
378
+ }
379
+
380
+ getExamples() {
381
+ return {
382
+ updatePrivateField: {
383
+ description: 'Update a private [SerializeField] float on a scene object.',
384
+ params: {
385
+ gameObjectPath: '/Player/Weapon',
386
+ componentType: 'WeaponController',
387
+ fieldPath: '_damageMultiplier',
388
+ value: 1.35,
389
+ valueType: 'float'
390
+ }
391
+ },
392
+ updatePrefabStruct: {
393
+ description: 'Modify a nested struct value inside a prefab asset.',
394
+ params: {
395
+ scope: 'prefabAsset',
396
+ prefabAssetPath: 'Assets/Prefabs/Enemy.prefab',
397
+ prefabObjectPath: '/EnemyBoss',
398
+ componentType: 'EnemyAIController',
399
+ fieldPath: 'behaviorSettings.alert.radius',
400
+ value: 12.5,
401
+ valueType: 'float'
402
+ }
403
+ },
404
+ updateArrayElement: {
405
+ description: 'Set the second material slot on a renderer prefab instance.',
406
+ params: {
407
+ gameObjectPath: '/Environment/Bridge',
408
+ componentType: 'MeshRenderer',
409
+ componentIndex: 0,
410
+ fieldPath: 'm_Materials[1]',
411
+ valueType: 'objectReference',
412
+ objectReference: {
413
+ assetPath: 'Assets/Materials/BridgeAccent.mat'
414
+ }
415
+ }
416
+ }
417
+ }
418
+ }
419
+ }
@@ -3,10 +3,10 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
3
3
  /**
4
4
  * Handler for discovering available component types in Unity
5
5
  */
6
- export class GetComponentTypesToolHandler extends BaseToolHandler {
6
+ export class ComponentGetTypesToolHandler extends BaseToolHandler {
7
7
  constructor(unityConnection) {
8
8
  super(
9
- 'get_component_types',
9
+ 'component_get_types',
10
10
  'Get available component types in Unity',
11
11
  {
12
12
  type: 'object',
@@ -3,10 +3,10 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
3
3
  /**
4
4
  * Handler for listing components on GameObjects in Unity
5
5
  */
6
- export class ListComponentsToolHandler extends BaseToolHandler {
6
+ export class ComponentListToolHandler extends BaseToolHandler {
7
7
  constructor(unityConnection) {
8
8
  super(
9
- 'list_components',
9
+ 'component_list',
10
10
  'List all components on a GameObject in Unity (works in both scene and prefab mode)',
11
11
  {
12
12
  type: 'object',
@@ -3,10 +3,10 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
3
3
  /**
4
4
  * Handler for modifying component properties on GameObjects in Unity
5
5
  */
6
- export class ModifyComponentToolHandler extends BaseToolHandler {
6
+ export class ComponentModifyToolHandler extends BaseToolHandler {
7
7
  constructor(unityConnection) {
8
8
  super(
9
- 'modify_component',
9
+ 'component_modify',
10
10
  'Modify properties of a component on a GameObject in Unity (works in both scene and prefab mode)',
11
11
  {
12
12
  type: 'object',
@@ -3,10 +3,10 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
3
3
  /**
4
4
  * Handler for removing components from GameObjects in Unity
5
5
  */
6
- export class RemoveComponentToolHandler extends BaseToolHandler {
6
+ export class ComponentRemoveToolHandler extends BaseToolHandler {
7
7
  constructor(unityConnection) {
8
8
  super(
9
- 'remove_component',
9
+ 'component_remove',
10
10
  'Remove a component from a GameObject (scene or prefab mode) by type/index.',
11
11
  {
12
12
  type: 'object',
@@ -3,10 +3,10 @@ import { BaseToolHandler } from '../base/BaseToolHandler.js';
3
3
  /**
4
4
  * Handler for clearing Unity Editor console logs
5
5
  */
6
- export class ClearConsoleToolHandler extends BaseToolHandler {
6
+ export class ConsoleClearToolHandler extends BaseToolHandler {
7
7
  constructor(unityConnection) {
8
8
  super(
9
- 'clear_console',
9
+ 'console_clear',
10
10
  'Clear Console logs (optionally set auto-clear and preserve levels).',
11
11
  {
12
12
  type: 'object',