@akiojin/unity-mcp-server 2.32.0 → 2.37.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 (26) hide show
  1. package/README.md +30 -5
  2. package/package.json +9 -4
  3. package/src/core/config.js +241 -242
  4. package/src/core/projectInfo.js +15 -0
  5. package/src/core/transports/HybridStdioServerTransport.js +78 -75
  6. package/src/handlers/addressables/AddressablesAnalyzeToolHandler.js +45 -47
  7. package/src/handlers/addressables/AddressablesBuildToolHandler.js +32 -33
  8. package/src/handlers/addressables/AddressablesManageToolHandler.js +74 -75
  9. package/src/handlers/component/ComponentFieldSetToolHandler.js +419 -419
  10. package/src/handlers/index.js +437 -437
  11. package/src/handlers/input/InputGamepadToolHandler.js +162 -0
  12. package/src/handlers/input/InputKeyboardToolHandler.js +127 -0
  13. package/src/handlers/input/InputMouseToolHandler.js +188 -0
  14. package/src/handlers/input/InputSystemControlToolHandler.js +63 -64
  15. package/src/handlers/input/InputTouchToolHandler.js +178 -0
  16. package/src/handlers/playmode/PlaymodePlayToolHandler.js +36 -23
  17. package/src/handlers/playmode/PlaymodeStopToolHandler.js +32 -21
  18. package/src/handlers/test/TestGetStatusToolHandler.js +37 -10
  19. package/src/handlers/test/TestRunToolHandler.js +36 -35
  20. package/src/lsp/LspProcessManager.js +18 -12
  21. package/src/utils/editorState.js +42 -0
  22. package/src/utils/testResultsCache.js +70 -0
  23. package/src/handlers/input/InputGamepadSimulateToolHandler.js +0 -116
  24. package/src/handlers/input/InputKeyboardSimulateToolHandler.js +0 -79
  25. package/src/handlers/input/InputMouseSimulateToolHandler.js +0 -107
  26. package/src/handlers/input/InputTouchSimulateToolHandler.js +0 -142
@@ -1,4 +1,4 @@
1
- import { BaseToolHandler } from '../base/BaseToolHandler.js'
1
+ import { BaseToolHandler } from '../base/BaseToolHandler.js';
2
2
 
3
3
  /**
4
4
  * Addressables Management Tool Handler for Unity MCP
@@ -74,16 +74,16 @@ export default class AddressablesManageToolHandler extends BaseToolHandler {
74
74
  },
75
75
  required: ['action']
76
76
  }
77
- )
78
- this.unityConnection = unityConnection
77
+ );
78
+ this.unityConnection = unityConnection;
79
79
  }
80
80
 
81
81
  validate(params) {
82
82
  const { action, assetPath, address, groupName, label, newAddress, targetGroupName } =
83
- params || {}
83
+ params || {};
84
84
 
85
85
  if (!action) {
86
- throw new Error('action is required')
86
+ throw new Error('action is required');
87
87
  }
88
88
 
89
89
  const validActions = [
@@ -97,65 +97,65 @@ export default class AddressablesManageToolHandler extends BaseToolHandler {
97
97
  'create_group',
98
98
  'remove_group',
99
99
  'move_entry'
100
- ]
100
+ ];
101
101
 
102
102
  if (!validActions.includes(action)) {
103
- throw new Error(`Invalid action: ${action}. Must be one of: ${validActions.join(', ')}`)
103
+ throw new Error(`Invalid action: ${action}. Must be one of: ${validActions.join(', ')}`);
104
104
  }
105
105
 
106
106
  // Action-specific validation
107
107
  switch (action) {
108
108
  case 'add_entry':
109
- if (!assetPath) throw new Error('assetPath is required for add_entry')
110
- if (!address) throw new Error('address is required for add_entry')
111
- if (!groupName) throw new Error('groupName is required for add_entry')
112
- break
109
+ if (!assetPath) throw new Error('assetPath is required for add_entry');
110
+ if (!address) throw new Error('address is required for add_entry');
111
+ if (!groupName) throw new Error('groupName is required for add_entry');
112
+ break;
113
113
  case 'remove_entry':
114
114
  case 'add_label':
115
115
  case 'remove_label':
116
- if (!assetPath) throw new Error(`assetPath is required for ${action}`)
116
+ if (!assetPath) throw new Error(`assetPath is required for ${action}`);
117
117
  if ((action === 'add_label' || action === 'remove_label') && !label) {
118
- throw new Error(`label is required for ${action}`)
118
+ throw new Error(`label is required for ${action}`);
119
119
  }
120
- break
120
+ break;
121
121
  case 'set_address':
122
- if (!assetPath) throw new Error('assetPath is required for set_address')
123
- if (!newAddress) throw new Error('newAddress is required for set_address')
124
- break
122
+ if (!assetPath) throw new Error('assetPath is required for set_address');
123
+ if (!newAddress) throw new Error('newAddress is required for set_address');
124
+ break;
125
125
  case 'create_group':
126
126
  case 'remove_group':
127
- if (!groupName) throw new Error(`groupName is required for ${action}`)
128
- break
127
+ if (!groupName) throw new Error(`groupName is required for ${action}`);
128
+ break;
129
129
  case 'move_entry':
130
- if (!assetPath) throw new Error('assetPath is required for move_entry')
131
- if (!targetGroupName) throw new Error('targetGroupName is required for move_entry')
132
- break
130
+ if (!assetPath) throw new Error('assetPath is required for move_entry');
131
+ if (!targetGroupName) throw new Error('targetGroupName is required for move_entry');
132
+ break;
133
133
  }
134
134
  }
135
135
 
136
136
  async execute(params) {
137
- const { action, ...parameters } = params
137
+ const { action, ...parameters } = params;
138
138
 
139
139
  // Ensure connected
140
140
  if (!this.unityConnection.isConnected()) {
141
- await this.unityConnection.connect()
141
+ await this.unityConnection.connect();
142
142
  }
143
143
 
144
144
  const result = await this.unityConnection.sendCommand('addressables_manage', {
145
145
  action,
146
146
  ...parameters
147
- })
147
+ });
148
148
 
149
- return this.formatResponse(action, result)
149
+ return this.formatResponse(action, result);
150
150
  }
151
151
 
152
152
  formatResponse(action, result) {
153
153
  if (result && result.error) {
154
- throw new Error(result.error.message || result.error)
154
+ throw new Error(result.error.message || result.error);
155
155
  }
156
156
 
157
157
  if (!result || typeof result !== 'object') {
158
- throw new Error('Invalid response from Unity')
158
+ throw new Error('Invalid response from Unity');
159
159
  }
160
160
 
161
161
  // Return formatted response
@@ -166,107 +166,106 @@ export default class AddressablesManageToolHandler extends BaseToolHandler {
166
166
  text: this.formatResultText(action, result)
167
167
  }
168
168
  ]
169
- }
169
+ };
170
170
  }
171
171
 
172
172
  formatResultText(action, result) {
173
- const lines = []
173
+ const lines = [];
174
174
 
175
175
  switch (action) {
176
176
  case 'add_entry':
177
- lines.push('✅ Addressableエントリを追加しました')
177
+ lines.push('✅ Addressableエントリを追加しました');
178
178
  if (result.data) {
179
- lines.push(` 📁 Asset: ${result.data.assetPath}`)
180
- lines.push(` 🏷️ Address: ${result.data.address}`)
181
- lines.push(` 📦 Group: ${result.data.groupName}`)
179
+ lines.push(` 📁 Asset: ${result.data.assetPath}`);
180
+ lines.push(` 🏷️ Address: ${result.data.address}`);
181
+ lines.push(` 📦 Group: ${result.data.groupName}`);
182
182
  if (result.data.labels && result.data.labels.length > 0) {
183
- lines.push(` 🏷️ Labels: ${result.data.labels.join(', ')}`)
183
+ lines.push(` 🏷️ Labels: ${result.data.labels.join(', ')}`);
184
184
  }
185
185
  }
186
- break
186
+ break;
187
187
 
188
188
  case 'remove_entry':
189
- lines.push(`✅ ${result.message}`)
190
- break
189
+ lines.push(`✅ ${result.message}`);
190
+ break;
191
191
 
192
192
  case 'set_address':
193
- lines.push('✅ アドレスを変更しました')
193
+ lines.push('✅ アドレスを変更しました');
194
194
  if (result.data) {
195
- lines.push(` 📁 Asset: ${result.data.assetPath}`)
196
- lines.push(` 🏷️ New Address: ${result.data.address}`)
195
+ lines.push(` 📁 Asset: ${result.data.assetPath}`);
196
+ lines.push(` 🏷️ New Address: ${result.data.address}`);
197
197
  }
198
- break
198
+ break;
199
199
 
200
200
  case 'add_label':
201
201
  case 'remove_label':
202
- lines.push(`✅ ラベルを${action === 'add_label' ? '追加' : '削除'}しました`)
202
+ lines.push(`✅ ラベルを${action === 'add_label' ? '追加' : '削除'}しました`);
203
203
  if (result.data) {
204
- lines.push(` 📁 Asset: ${result.data.assetPath}`)
205
- lines.push(` 🏷️ Labels: ${result.data.labels.join(', ')}`)
204
+ lines.push(` 📁 Asset: ${result.data.assetPath}`);
205
+ lines.push(` 🏷️ Labels: ${result.data.labels.join(', ')}`);
206
206
  }
207
- break
207
+ break;
208
208
 
209
209
  case 'list_entries':
210
- lines.push('📋 Addressableエントリ一覧')
210
+ lines.push('📋 Addressableエントリ一覧');
211
211
  if (result.data && result.data.entries) {
212
- lines.push(` 合計: ${result.pagination.total}件`)
212
+ lines.push(` 合計: ${result.pagination.total}件`);
213
213
  if (result.data.entries.length === 0) {
214
- lines.push(' (エントリがありません)')
214
+ lines.push(' (エントリがありません)');
215
215
  } else {
216
216
  result.data.entries.forEach(entry => {
217
- lines.push(`\n 📁 ${entry.assetPath}`)
218
- lines.push(` Address: ${entry.address}`)
219
- lines.push(` Group: ${entry.groupName}`)
217
+ lines.push(`\n 📁 ${entry.assetPath}`);
218
+ lines.push(` Address: ${entry.address}`);
219
+ lines.push(` Group: ${entry.groupName}`);
220
220
  if (entry.labels && entry.labels.length > 0) {
221
- lines.push(` Labels: ${entry.labels.join(', ')}`)
221
+ lines.push(` Labels: ${entry.labels.join(', ')}`);
222
222
  }
223
- })
223
+ });
224
224
  }
225
225
  if (result.pagination.hasMore) {
226
226
  lines.push(
227
227
  `\n ... さらに${result.pagination.total - result.pagination.offset - result.pagination.pageSize}件あります`
228
- )
228
+ );
229
229
  }
230
230
  }
231
- break
231
+ break;
232
232
 
233
233
  case 'list_groups':
234
- lines.push('📦 Addressablesグループ一覧')
234
+ lines.push('📦 Addressablesグループ一覧');
235
235
  if (result.data && result.data.groups) {
236
236
  if (result.data.groups.length === 0) {
237
- lines.push(' (グループがありません)')
237
+ lines.push(' (グループがありません)');
238
238
  } else {
239
239
  result.data.groups.forEach(group => {
240
- lines.push(`\n 📦 ${group.groupName}`)
241
- lines.push(` Entries: ${group.entriesCount}個`)
242
- if (group.buildPath) lines.push(` Build Path: ${group.buildPath}`)
243
- if (group.loadPath) lines.push(` Load Path: ${group.loadPath}`)
244
- })
240
+ lines.push(`\n 📦 ${group.groupName}`);
241
+ lines.push(` Entries: ${group.entriesCount}個`);
242
+ if (group.buildPath) lines.push(` Build Path: ${group.buildPath}`);
243
+ if (group.loadPath) lines.push(` Load Path: ${group.loadPath}`);
244
+ });
245
245
  }
246
246
  }
247
- break
247
+ break;
248
248
 
249
249
  case 'create_group':
250
- lines.push(`✅ グループを作成しました: ${result.data?.groupName}`)
251
- break
250
+ lines.push(`✅ グループを作成しました: ${result.data?.groupName}`);
251
+ break;
252
252
 
253
253
  case 'remove_group':
254
- lines.push(`✅ ${result.message}`)
255
- break
254
+ lines.push(`✅ ${result.message}`);
255
+ break;
256
256
 
257
257
  case 'move_entry':
258
- lines.push('✅ エントリを移動しました')
258
+ lines.push('✅ エントリを移動しました');
259
259
  if (result.data) {
260
- lines.push(` 📁 Asset: ${result.data.assetPath}`)
261
- lines.push(` 📦 New Group: ${result.data.groupName}`)
260
+ lines.push(` 📁 Asset: ${result.data.assetPath}`);
261
+ lines.push(` 📦 New Group: ${result.data.groupName}`);
262
262
  }
263
- break
263
+ break;
264
264
 
265
265
  default:
266
- lines.push(JSON.stringify(result, null, 2))
266
+ lines.push(JSON.stringify(result, null, 2));
267
267
  }
268
268
 
269
- return lines.join('\n')
269
+ return lines.join('\n');
270
270
  }
271
271
  }
272
-