import { z } from 'zod';
import { existsSync } from 'node:fs';
import { simctl } from '../executor/simctl.js';
import { resolveDevice } from '../utils/device-resolver.js';
export const installSchema = z.object({
device: z
.string()
.describe('Device UDID, name, or "booted"'),
app_path: z
.string()
.describe('Path to the .app bundle to install'),
});
export type InstallInput = z.infer<typeof installSchema>;
export const installTool = {
name: 'simctl_install',
description: 'Install an app bundle on a simulator',
inputSchema: installSchema,
handler: async (input: InstallInput) => {
if (!existsSync(input.app_path)) {
throw new Error(`App bundle not found: ${input.app_path}`);
}
if (!input.app_path.endsWith('.app')) {
throw new Error(`Invalid app bundle path (must end with .app): ${input.app_path}`);
}
const udid = resolveDevice(input.device);
const result = simctl('install', [udid, input.app_path]);
if (result.exitCode !== 0) {
throw new Error(`Failed to install app: ${result.stderr || result.stdout}`);
}
return {
content: [
{
type: 'text' as const,
text: `Successfully installed ${input.app_path} on device ${input.device}`,
},
],
};
},
};