@ebowwa/mcp-ios-devices 1.0.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.
@@ -0,0 +1,109 @@
1
+ /**
2
+ * Process Management Tools
3
+ * List, launch, terminate, and signal processes on iOS devices
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { DeviceCtl } from '@ebowwa/ios-devices';
9
+
10
+ const deviceCtl = new DeviceCtl();
11
+
12
+ registerTool({
13
+ name: 'ios_list_processes',
14
+ description: 'List all running processes on a device',
15
+ inputSchema: z.object({
16
+ deviceId: z.string().describe('Device UDID'),
17
+ }),
18
+ handler: async ({ deviceId }) => {
19
+ return deviceCtl.listProcesses(deviceId);
20
+ },
21
+ });
22
+
23
+ registerTool({
24
+ name: 'ios_launch_app',
25
+ description: 'Launch an app on the device',
26
+ inputSchema: z.object({
27
+ deviceId: z.string().describe('Device UDID'),
28
+ bundleId: z.string().describe('App bundle identifier (e.g., com.apple.MobileSMS)'),
29
+ arguments: z.array(z.string()).optional().describe('Arguments to pass to the app'),
30
+ environment: z.record(z.string()).optional().describe('Environment variables'),
31
+ }),
32
+ handler: async ({ deviceId, bundleId, arguments: args, environment }) => {
33
+ return deviceCtl.launchApp(deviceId, bundleId, { arguments: args, environment });
34
+ },
35
+ });
36
+
37
+ registerTool({
38
+ name: 'ios_terminate_process',
39
+ description: 'Terminate a process by PID or name',
40
+ inputSchema: z.object({
41
+ deviceId: z.string().describe('Device UDID'),
42
+ process: z.union([z.number(), z.string()]).describe('Process PID (number) or name (string)'),
43
+ }),
44
+ handler: async ({ deviceId, process }) => {
45
+ return deviceCtl.terminateProcess(deviceId, process);
46
+ },
47
+ });
48
+
49
+ registerTool({
50
+ name: 'ios_signal_process',
51
+ description: 'Send a signal to a process',
52
+ inputSchema: z.object({
53
+ deviceId: z.string().describe('Device UDID'),
54
+ pid: z.number().describe('Process ID'),
55
+ signal: z.enum(['SIGTERM', 'SIGKILL', 'SIGHUP', 'SIGINT', 'SIGSTOP', 'SIGCONT', 'SIGUSR1', 'SIGUSR2']),
56
+ }),
57
+ handler: async ({ deviceId, pid, signal }) => {
58
+ return deviceCtl.signalProcess(deviceId, pid, signal);
59
+ },
60
+ });
61
+
62
+ registerTool({
63
+ name: 'ios_suspend_process',
64
+ description: 'Suspend a running process',
65
+ inputSchema: z.object({
66
+ deviceId: z.string().describe('Device UDID'),
67
+ pid: z.number().describe('Process ID'),
68
+ }),
69
+ handler: async ({ deviceId, pid }) => {
70
+ return deviceCtl.suspendProcess(deviceId, pid);
71
+ },
72
+ });
73
+
74
+ registerTool({
75
+ name: 'ios_resume_process',
76
+ description: 'Resume a suspended process',
77
+ inputSchema: z.object({
78
+ deviceId: z.string().describe('Device UDID'),
79
+ pid: z.number().describe('Process ID'),
80
+ }),
81
+ handler: async ({ deviceId, pid }) => {
82
+ return deviceCtl.resumeProcess(deviceId, pid);
83
+ },
84
+ });
85
+
86
+ registerTool({
87
+ name: 'ios_send_memory_warning',
88
+ description: 'Send a memory warning to a process',
89
+ inputSchema: z.object({
90
+ deviceId: z.string().describe('Device UDID'),
91
+ pid: z.number().describe('Process ID'),
92
+ }),
93
+ handler: async ({ deviceId, pid }) => {
94
+ return deviceCtl.sendMemoryWarning(deviceId, pid);
95
+ },
96
+ });
97
+
98
+ registerTool({
99
+ name: 'ios_post_notification',
100
+ description: 'Post a Darwin notification to the device',
101
+ inputSchema: z.object({
102
+ deviceId: z.string().describe('Device UDID'),
103
+ name: z.string().describe('Notification name'),
104
+ userInfo: z.record(z.any()).optional().describe('Optional user info dictionary'),
105
+ }),
106
+ handler: async ({ deviceId, name, userInfo }) => {
107
+ return deviceCtl.postNotification(deviceId, name, userInfo);
108
+ },
109
+ });
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Provisioning Profile Tools
3
+ * Manage provisioning profiles on devices
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { LibIMobileDevice } from '@ebowwa/ios-devices';
9
+
10
+ registerTool({
11
+ name: 'ios_list_profiles',
12
+ description: 'List installed provisioning profiles',
13
+ inputSchema: z.object({
14
+ deviceId: z.string().describe('Device UDID'),
15
+ }),
16
+ handler: async ({ deviceId }) => {
17
+ const lib = new LibIMobileDevice({ udid: deviceId });
18
+ return lib.listProfiles();
19
+ },
20
+ });
21
+
22
+ registerTool({
23
+ name: 'ios_install_profile',
24
+ description: 'Install a provisioning profile',
25
+ inputSchema: z.object({
26
+ deviceId: z.string().describe('Device UDID'),
27
+ profilePath: z.string().describe('Path to .mobileprovision file'),
28
+ }),
29
+ handler: async ({ deviceId, profilePath }) => {
30
+ const lib = new LibIMobileDevice({ udid: deviceId });
31
+ return lib.installProfile(profilePath);
32
+ },
33
+ });
34
+
35
+ registerTool({
36
+ name: 'ios_remove_profile',
37
+ description: 'Remove a provisioning profile',
38
+ inputSchema: z.object({
39
+ deviceId: z.string().describe('Device UDID'),
40
+ uuid: z.string().describe('Profile UUID'),
41
+ }),
42
+ handler: async ({ deviceId, uuid }) => {
43
+ const lib = new LibIMobileDevice({ udid: deviceId });
44
+ return lib.removeProfile(uuid);
45
+ },
46
+ });
47
+
48
+ registerTool({
49
+ name: 'ios_list_dev_mode',
50
+ description: 'List developer mode status for devices',
51
+ inputSchema: z.object({}),
52
+ handler: async () => {
53
+ const lib = new LibIMobileDevice();
54
+ return lib.listDevMode();
55
+ },
56
+ });
@@ -0,0 +1,21 @@
1
+ /**
2
+ * Screenshot Tools
3
+ * Capture screenshots from devices
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { LibIMobileDevice } from '@ebowwa/ios-devices';
9
+
10
+ registerTool({
11
+ name: 'ios_screenshot',
12
+ description: 'Take a screenshot of the device screen',
13
+ inputSchema: z.object({
14
+ deviceId: z.string().describe('Device UDID'),
15
+ outputPath: z.string().optional().describe('Output file path (.tiff)'),
16
+ }),
17
+ handler: async ({ deviceId, outputPath }) => {
18
+ const lib = new LibIMobileDevice({ udid: deviceId });
19
+ return lib.takeScreenshot(outputPath);
20
+ },
21
+ });
@@ -0,0 +1,497 @@
1
+ /**
2
+ * Simulator Tools
3
+ * Control iOS Simulator via simctl
4
+ */
5
+
6
+ import { z } from 'zod';
7
+ import { registerTool } from '../registry.js';
8
+ import { SimCtl } from '@ebowwa/ios-devices';
9
+
10
+ const simCtl = new SimCtl();
11
+
12
+ // ============================================================================
13
+ // Device Management
14
+ // ============================================================================
15
+
16
+ registerTool({
17
+ name: 'sim_list',
18
+ description: 'List simulators, device types, or runtimes',
19
+ inputSchema: z.object({
20
+ devices: z.boolean().optional().describe('List devices'),
21
+ deviceTypes: z.boolean().optional().describe('List device types'),
22
+ runtimes: z.boolean().optional().describe('List runtimes'),
23
+ available: z.boolean().optional().describe('Only available'),
24
+ search: z.string().optional().describe('Search term'),
25
+ }),
26
+ handler: async (options) => {
27
+ return simCtl.list(options);
28
+ },
29
+ });
30
+
31
+ registerTool({
32
+ name: 'sim_create',
33
+ description: 'Create a new simulator',
34
+ inputSchema: z.object({
35
+ name: z.string().describe('Simulator name'),
36
+ deviceTypeId: z.string().describe('Device type (e.g., com.apple.CoreSimulator.SimDeviceType.iPhone-16)'),
37
+ runtimeId: z.string().describe('Runtime (e.g., com.apple.CoreSimulator.SimRuntime.iOS-18-1)'),
38
+ }),
39
+ handler: async ({ name, deviceTypeId, runtimeId }) => {
40
+ return simCtl.create(name, deviceTypeId, runtimeId);
41
+ },
42
+ });
43
+
44
+ registerTool({
45
+ name: 'sim_clone',
46
+ description: 'Clone an existing simulator',
47
+ inputSchema: z.object({
48
+ udid: z.string().describe('Source simulator UDID'),
49
+ name: z.string().describe('Name for cloned simulator'),
50
+ }),
51
+ handler: async ({ udid, name }) => {
52
+ return simCtl.clone(udid, name);
53
+ },
54
+ });
55
+
56
+ registerTool({
57
+ name: 'sim_delete',
58
+ description: 'Delete one or more simulators',
59
+ inputSchema: z.object({
60
+ udids: z.union([z.string(), z.array(z.string())]).describe('Simulator UDID(s) to delete'),
61
+ }),
62
+ handler: async ({ udids }) => {
63
+ return simCtl.delete(udids);
64
+ },
65
+ });
66
+
67
+ registerTool({
68
+ name: 'sim_delete_unavailable',
69
+ description: 'Delete all unavailable simulators',
70
+ inputSchema: z.object({}),
71
+ handler: async () => {
72
+ return simCtl.deleteUnavailable();
73
+ },
74
+ });
75
+
76
+ registerTool({
77
+ name: 'sim_erase',
78
+ description: 'Erase a simulator (reset to factory state)',
79
+ inputSchema: z.object({
80
+ udid: z.string().describe('Simulator UDID'),
81
+ }),
82
+ handler: async ({ udid }) => {
83
+ return simCtl.erase(udid);
84
+ },
85
+ });
86
+
87
+ registerTool({
88
+ name: 'sim_rename',
89
+ description: 'Rename a simulator',
90
+ inputSchema: z.object({
91
+ udid: z.string().describe('Simulator UDID'),
92
+ name: z.string().describe('New name'),
93
+ }),
94
+ handler: async ({ udid, name }) => {
95
+ return simCtl.rename(udid, name);
96
+ },
97
+ });
98
+
99
+ // ============================================================================
100
+ // Boot/Shutdown
101
+ // ============================================================================
102
+
103
+ registerTool({
104
+ name: 'sim_boot',
105
+ description: 'Boot a simulator',
106
+ inputSchema: z.object({
107
+ udid: z.string().describe('Simulator UDID (or "booted" for any booted)'),
108
+ }),
109
+ handler: async ({ udid }) => {
110
+ return simCtl.boot(udid);
111
+ },
112
+ });
113
+
114
+ registerTool({
115
+ name: 'sim_shutdown',
116
+ description: 'Shutdown a simulator',
117
+ inputSchema: z.object({
118
+ udid: z.string().describe('Simulator UDID'),
119
+ }),
120
+ handler: async ({ udid }) => {
121
+ return simCtl.shutdown(udid);
122
+ },
123
+ });
124
+
125
+ registerTool({
126
+ name: 'sim_shutdown_all',
127
+ description: 'Shutdown all simulators',
128
+ inputSchema: z.object({}),
129
+ handler: async () => {
130
+ return simCtl.shutdownAll();
131
+ },
132
+ });
133
+
134
+ // ============================================================================
135
+ // App Management
136
+ // ============================================================================
137
+
138
+ registerTool({
139
+ name: 'sim_install',
140
+ description: 'Install an app on a simulator',
141
+ inputSchema: z.object({
142
+ udid: z.string().describe('Simulator UDID'),
143
+ appPath: z.string().describe('Path to .app bundle'),
144
+ }),
145
+ handler: async ({ udid, appPath }) => {
146
+ return simCtl.install(udid, appPath);
147
+ },
148
+ });
149
+
150
+ registerTool({
151
+ name: 'sim_uninstall',
152
+ description: 'Uninstall an app from a simulator',
153
+ inputSchema: z.object({
154
+ udid: z.string().describe('Simulator UDID'),
155
+ bundleId: z.string().describe('App bundle identifier'),
156
+ }),
157
+ handler: async ({ udid, bundleId }) => {
158
+ return simCtl.uninstall(udid, bundleId);
159
+ },
160
+ });
161
+
162
+ registerTool({
163
+ name: 'sim_get_app_container',
164
+ description: 'Get the path to an app container',
165
+ inputSchema: z.object({
166
+ udid: z.string().describe('Simulator UDID'),
167
+ bundleId: z.string().describe('App bundle identifier'),
168
+ containerType: z.string().optional().describe('Container type (app, data, groups, etc.)'),
169
+ }),
170
+ handler: async ({ udid, bundleId, containerType }) => {
171
+ return simCtl.getAppContainer(udid, bundleId, containerType);
172
+ },
173
+ });
174
+
175
+ // ============================================================================
176
+ // App Execution
177
+ // ============================================================================
178
+
179
+ registerTool({
180
+ name: 'sim_launch',
181
+ description: 'Launch an app on a simulator',
182
+ inputSchema: z.object({
183
+ udid: z.string().describe('Simulator UDID'),
184
+ bundleId: z.string().describe('App bundle identifier'),
185
+ waitForDebugger: z.boolean().optional().describe('Wait for debugger to attach'),
186
+ console: z.boolean().optional().describe('Show console output'),
187
+ env: z.record(z.string()).optional().describe('Environment variables'),
188
+ args: z.array(z.string()).optional().describe('Arguments'),
189
+ }),
190
+ handler: async ({ udid, bundleId, waitForDebugger, console, env, args }) => {
191
+ return simCtl.launch(udid, bundleId, { waitForDebugger, console, env, args });
192
+ },
193
+ });
194
+
195
+ registerTool({
196
+ name: 'sim_terminate',
197
+ description: 'Terminate an app on a simulator',
198
+ inputSchema: z.object({
199
+ udid: z.string().describe('Simulator UDID'),
200
+ bundleId: z.string().describe('App bundle identifier'),
201
+ }),
202
+ handler: async ({ udid, bundleId }) => {
203
+ return simCtl.terminate(udid, bundleId);
204
+ },
205
+ });
206
+
207
+ registerTool({
208
+ name: 'sim_spawn',
209
+ description: 'Spawn a process on a simulator',
210
+ inputSchema: z.object({
211
+ udid: z.string().describe('Simulator UDID'),
212
+ executable: z.string().describe('Executable path'),
213
+ args: z.array(z.string()).optional().describe('Arguments'),
214
+ }),
215
+ handler: async ({ udid, executable, args }) => {
216
+ return simCtl.spawn(udid, executable, args);
217
+ },
218
+ });
219
+
220
+ // ============================================================================
221
+ // IO Operations
222
+ // ============================================================================
223
+
224
+ registerTool({
225
+ name: 'sim_screenshot',
226
+ description: 'Take a screenshot of a simulator',
227
+ inputSchema: z.object({
228
+ udid: z.string().describe('Simulator UDID'),
229
+ outputPath: z.string().describe('Output file path'),
230
+ type: z.enum(['png', 'jpeg', 'tiff']).optional().default('png'),
231
+ }),
232
+ handler: async ({ udid, outputPath, type }) => {
233
+ return simCtl.screenshot(udid, outputPath, { type });
234
+ },
235
+ });
236
+
237
+ registerTool({
238
+ name: 'sim_record_video',
239
+ description: 'Record video of a simulator',
240
+ inputSchema: z.object({
241
+ udid: z.string().describe('Simulator UDID'),
242
+ outputPath: z.string().describe('Output file path (.mp4)'),
243
+ codec: z.enum(['h264', 'hevc']).optional(),
244
+ }),
245
+ handler: async ({ udid, outputPath, codec }) => {
246
+ return simCtl.recordVideo(udid, outputPath, { codec });
247
+ },
248
+ });
249
+
250
+ // ============================================================================
251
+ // Location
252
+ // ============================================================================
253
+
254
+ registerTool({
255
+ name: 'sim_set_location',
256
+ description: 'Set simulated location on a simulator',
257
+ inputSchema: z.object({
258
+ udid: z.string().describe('Simulator UDID'),
259
+ latitude: z.number().describe('Latitude'),
260
+ longitude: z.number().describe('Longitude'),
261
+ }),
262
+ handler: async ({ udid, latitude, longitude }) => {
263
+ return simCtl.setLocation(udid, latitude, longitude);
264
+ },
265
+ });
266
+
267
+ registerTool({
268
+ name: 'sim_reset_location',
269
+ description: 'Reset simulated location',
270
+ inputSchema: z.object({
271
+ udid: z.string().describe('Simulator UDID'),
272
+ }),
273
+ handler: async ({ udid }) => {
274
+ return simCtl.resetLocation(udid);
275
+ },
276
+ });
277
+
278
+ // ============================================================================
279
+ // Status Bar
280
+ // ============================================================================
281
+
282
+ registerTool({
283
+ name: 'sim_status_bar_override',
284
+ description: 'Override status bar appearance',
285
+ inputSchema: z.object({
286
+ udid: z.string().describe('Simulator UDID'),
287
+ time: z.string().optional().describe('Time (e.g., "9:41")'),
288
+ dataNetwork: z.string().optional().describe('Data network type'),
289
+ wifiMode: z.enum(['active', 'searching', 'failed']).optional(),
290
+ cellularMode: z.enum(['active', 'searching', 'failed']).optional(),
291
+ batteryLevel: z.number().optional().describe('Battery level (0-100)'),
292
+ batteryState: z.enum(['charging', 'charged', 'discharging']).optional(),
293
+ }),
294
+ handler: async ({ udid, ...overrides }) => {
295
+ return simCtl.statusBar(udid, overrides);
296
+ },
297
+ });
298
+
299
+ registerTool({
300
+ name: 'sim_status_bar_clear',
301
+ description: 'Clear status bar overrides',
302
+ inputSchema: z.object({
303
+ udid: z.string().describe('Simulator UDID'),
304
+ }),
305
+ handler: async ({ udid }) => {
306
+ return simCtl.clearStatusBar(udid);
307
+ },
308
+ });
309
+
310
+ // ============================================================================
311
+ // URL & Notifications
312
+ // ============================================================================
313
+
314
+ registerTool({
315
+ name: 'sim_open_url',
316
+ description: 'Open a URL on a simulator',
317
+ inputSchema: z.object({
318
+ udid: z.string().describe('Simulator UDID'),
319
+ url: z.string().describe('URL to open'),
320
+ }),
321
+ handler: async ({ udid, url }) => {
322
+ return simCtl.openURL(udid, url);
323
+ },
324
+ });
325
+
326
+ registerTool({
327
+ name: 'sim_push_notification',
328
+ description: 'Send a simulated push notification',
329
+ inputSchema: z.object({
330
+ udid: z.string().describe('Simulator UDID'),
331
+ bundleId: z.string().describe('App bundle identifier'),
332
+ payload: z.record(z.any()).describe('Push notification payload'),
333
+ }),
334
+ handler: async ({ udid, bundleId, payload }) => {
335
+ return simCtl.push(udid, bundleId, payload);
336
+ },
337
+ });
338
+
339
+ // ============================================================================
340
+ // Privacy
341
+ // ============================================================================
342
+
343
+ registerTool({
344
+ name: 'sim_grant_privacy',
345
+ description: 'Grant privacy permission to an app',
346
+ inputSchema: z.object({
347
+ udid: z.string().describe('Simulator UDID'),
348
+ bundleId: z.string().describe('App bundle identifier'),
349
+ service: z.string().describe('Service name (e.g., camera, microphone, photos)'),
350
+ }),
351
+ handler: async ({ udid, bundleId, service }) => {
352
+ return simCtl.grantPrivacy(udid, bundleId, service);
353
+ },
354
+ });
355
+
356
+ registerTool({
357
+ name: 'sim_revoke_privacy',
358
+ description: 'Revoke privacy permission from an app',
359
+ inputSchema: z.object({
360
+ udid: z.string().describe('Simulator UDID'),
361
+ bundleId: z.string().describe('App bundle identifier'),
362
+ service: z.string().describe('Service name'),
363
+ }),
364
+ handler: async ({ udid, bundleId, service }) => {
365
+ return simCtl.revokePrivacy(udid, bundleId, service);
366
+ },
367
+ });
368
+
369
+ // ============================================================================
370
+ // Keychain
371
+ // ============================================================================
372
+
373
+ registerTool({
374
+ name: 'sim_keychain_add',
375
+ description: 'Add item to simulator keychain',
376
+ inputSchema: z.object({
377
+ udid: z.string().describe('Simulator UDID'),
378
+ service: z.string().describe('Service name'),
379
+ account: z.string().describe('Account name'),
380
+ password: z.string().describe('Password'),
381
+ }),
382
+ handler: async ({ udid, service, account, password }) => {
383
+ return simCtl.keychainAdd(udid, service, account, password);
384
+ },
385
+ });
386
+
387
+ registerTool({
388
+ name: 'sim_keychain_reset',
389
+ description: 'Reset simulator keychain',
390
+ inputSchema: z.object({
391
+ udid: z.string().describe('Simulator UDID'),
392
+ }),
393
+ handler: async ({ udid }) => {
394
+ return simCtl.keychainReset(udid);
395
+ },
396
+ });
397
+
398
+ // ============================================================================
399
+ // Environment & Diagnostics
400
+ // ============================================================================
401
+
402
+ registerTool({
403
+ name: 'sim_getenv',
404
+ description: 'Get environment variable from simulator',
405
+ inputSchema: z.object({
406
+ udid: z.string().describe('Simulator UDID'),
407
+ variable: z.string().optional().describe('Variable name (omit for all)'),
408
+ }),
409
+ handler: async ({ udid, variable }) => {
410
+ return simCtl.getenv(udid, variable);
411
+ },
412
+ });
413
+
414
+ registerTool({
415
+ name: 'sim_diagnose',
416
+ description: 'Collect simulator diagnostics',
417
+ inputSchema: z.object({
418
+ outputPath: z.string().optional().describe('Output path'),
419
+ }),
420
+ handler: async ({ outputPath }) => {
421
+ return simCtl.diagnose(outputPath);
422
+ },
423
+ });
424
+
425
+ // ============================================================================
426
+ // Media & iCloud
427
+ // ============================================================================
428
+
429
+ registerTool({
430
+ name: 'sim_add_media',
431
+ description: 'Add media (photos/videos) to simulator',
432
+ inputSchema: z.object({
433
+ udid: z.string().describe('Simulator UDID'),
434
+ mediaPaths: z.union([z.string(), z.array(z.string())]).describe('Path(s) to media files'),
435
+ }),
436
+ handler: async ({ udid, mediaPaths }) => {
437
+ return simCtl.addMedia(udid, mediaPaths);
438
+ },
439
+ });
440
+
441
+ registerTool({
442
+ name: 'sim_icloud_sync',
443
+ description: 'Trigger iCloud sync on simulator',
444
+ inputSchema: z.object({
445
+ udid: z.string().describe('Simulator UDID'),
446
+ }),
447
+ handler: async ({ udid }) => {
448
+ return simCtl.icloudSync(udid);
449
+ },
450
+ });
451
+
452
+ // ============================================================================
453
+ // Pasteboard
454
+ // ============================================================================
455
+
456
+ registerTool({
457
+ name: 'sim_pbpaste',
458
+ description: 'Get pasteboard contents from simulator',
459
+ inputSchema: z.object({
460
+ udid: z.string().describe('Simulator UDID'),
461
+ }),
462
+ handler: async ({ udid }) => {
463
+ return simCtl.pbpaste(udid);
464
+ },
465
+ });
466
+
467
+ // ============================================================================
468
+ // UI
469
+ // ============================================================================
470
+
471
+ registerTool({
472
+ name: 'sim_set_appearance',
473
+ description: 'Set simulator appearance (light/dark mode)',
474
+ inputSchema: z.object({
475
+ udid: z.string().describe('Simulator UDID'),
476
+ appearance: z.enum(['light', 'dark']),
477
+ }),
478
+ handler: async ({ udid, appearance }) => {
479
+ return simCtl.setUI(udid, { appearance });
480
+ },
481
+ });
482
+
483
+ // ============================================================================
484
+ // Runtime
485
+ // ============================================================================
486
+
487
+ registerTool({
488
+ name: 'sim_upgrade',
489
+ description: 'Upgrade simulator to a new runtime',
490
+ inputSchema: z.object({
491
+ udid: z.string().describe('Simulator UDID'),
492
+ runtimeId: z.string().describe('Target runtime ID'),
493
+ }),
494
+ handler: async ({ udid, runtimeId }) => {
495
+ return simCtl.upgrade(udid, runtimeId);
496
+ },
497
+ });
package/tsconfig.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "compilerOptions": {
3
+ "target": "ES2022",
4
+ "module": "NodeNext",
5
+ "moduleResolution": "NodeNext",
6
+ "lib": ["ES2022"],
7
+ "outDir": "./dist",
8
+ "rootDir": "./src",
9
+ "strict": true,
10
+ "esModuleInterop": true,
11
+ "skipLibCheck": true,
12
+ "forceConsistentCasingInFileNames": true,
13
+ "declaration": true,
14
+ "declarationMap": true,
15
+ "sourceMap": true,
16
+ "resolveJsonModule": true
17
+ },
18
+ "include": ["src/**/*"],
19
+ "exclude": ["node_modules", "dist"]
20
+ }