import { z } from 'zod';
import { simctl } from '../executor/simctl.js';
import { resolveDevice } from '../utils/device-resolver.js';
export const locationSchema = z.object({
device: z
.string()
.describe('Device UDID, name, or "booted"'),
action: z
.enum(['set', 'clear'])
.describe('Action to perform: set a location or clear it'),
latitude: z
.number()
.min(-90)
.max(90)
.optional()
.describe('Latitude coordinate (required when action is "set")'),
longitude: z
.number()
.min(-180)
.max(180)
.optional()
.describe('Longitude coordinate (required when action is "set")'),
});
export type LocationInput = z.infer<typeof locationSchema>;
export const locationTool = {
name: 'simctl_location',
description: 'Set or clear the simulated GPS location on a simulator',
inputSchema: locationSchema,
handler: async (input: LocationInput) => {
const udid = resolveDevice(input.device);
if (input.action === 'set') {
if (input.latitude === undefined || input.longitude === undefined) {
throw new Error('latitude and longitude are required when action is "set"');
}
const coordinates = `${input.latitude},${input.longitude}`;
const result = simctl('location', [udid, 'set', coordinates]);
if (result.exitCode !== 0) {
throw new Error(`Failed to set location: ${result.stderr || result.stdout}`);
}
return {
content: [
{
type: 'text' as const,
text: `Successfully set location to ${input.latitude}, ${input.longitude} on device ${input.device}`,
},
],
};
} else {
const result = simctl('location', [udid, 'clear']);
if (result.exitCode !== 0) {
throw new Error(`Failed to clear location: ${result.stderr || result.stdout}`);
}
return {
content: [
{
type: 'text' as const,
text: `Successfully cleared location on device ${input.device}`,
},
],
};
}
},
};