-
-
Notifications
You must be signed in to change notification settings - Fork 260
Expand file tree
/
Copy pathstop_app_sim.ts
More file actions
116 lines (102 loc) · 3.74 KB
/
stop_app_sim.ts
File metadata and controls
116 lines (102 loc) · 3.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
import * as z from 'zod';
import { log } from '../../../utils/logging/index.ts';
import type { CommandExecutor } from '../../../utils/execution/index.ts';
import { getDefaultCommandExecutor } from '../../../utils/execution/index.ts';
import {
createSessionAwareTool,
getSessionAwareToolSchemaShape,
getHandlerContext,
} from '../../../utils/typed-tool-factory.ts';
import { withErrorHandling } from '../../../utils/tool-error-handling.ts';
import { header, statusLine } from '../../../utils/tool-event-builders.ts';
import { stopSimulatorLaunchOsLogSessionsForApp } from '../../../utils/log-capture/index.ts';
const baseSchemaObject = z.object({
simulatorId: z
.string()
.optional()
.describe(
'UUID of the simulator to use (obtained from list_sims). Provide EITHER this OR simulatorName, not both',
),
simulatorName: z
.string()
.optional()
.describe(
"Name of the simulator (e.g., 'iPhone 17'). Provide EITHER this OR simulatorId, not both",
),
bundleId: z.string().describe('Bundle identifier of the app to stop'),
});
const internalSchemaObject = z.object({
simulatorId: z.string(),
simulatorName: z.string().optional(),
bundleId: z.string(),
});
export type StopAppSimParams = z.infer<typeof internalSchemaObject>;
export async function stop_app_simLogic(
params: StopAppSimParams,
executor: CommandExecutor,
): Promise<void> {
const simulatorId = params.simulatorId;
const simulatorDisplayName = params.simulatorName
? `"${params.simulatorName}" (${simulatorId})`
: simulatorId;
log('info', `Stopping app ${params.bundleId} in simulator ${simulatorId}`);
const headerEvent = header('Stop App', [
{ label: 'Simulator', value: simulatorDisplayName },
{ label: 'Bundle ID', value: params.bundleId },
]);
const ctx = getHandlerContext();
return withErrorHandling(
ctx,
async () => {
const command = ['xcrun', 'simctl', 'terminate', simulatorId, params.bundleId];
const result = await executor(command, 'Stop App in Simulator', false);
const cleanupResult = await stopSimulatorLaunchOsLogSessionsForApp(
simulatorId,
params.bundleId,
1000,
);
if (!result.success || cleanupResult.errorCount > 0) {
const details: string[] = [];
if (!result.success) {
details.push(result.error ?? 'Unknown simulator terminate error');
}
if (cleanupResult.errorCount > 0) {
details.push(`OSLog cleanup failed: ${cleanupResult.errors.join('; ')}`);
}
ctx.emit(headerEvent);
ctx.emit(
statusLine('error', `Stop app in simulator operation failed: ${details.join(' | ')}`),
);
return;
}
ctx.emit(headerEvent);
ctx.emit(statusLine('success', 'App stopped successfully'));
},
{
header: headerEvent,
errorMessage: ({ message }) => `Stop app in simulator operation failed: ${message}`,
logMessage: ({ message }) => `Error stopping app in simulator: ${message}`,
},
);
}
const publicSchemaObject = z.strictObject(
baseSchemaObject.omit({
simulatorId: true,
simulatorName: true,
bundleId: true,
} as const).shape,
);
export const schema = getSessionAwareToolSchemaShape({
sessionAware: publicSchemaObject,
legacy: baseSchemaObject,
});
export const handler = createSessionAwareTool<StopAppSimParams>({
internalSchema: internalSchemaObject as unknown as z.ZodType<StopAppSimParams, unknown>,
logicFunction: stop_app_simLogic,
getExecutor: getDefaultCommandExecutor,
requirements: [
{ oneOf: ['simulatorId', 'simulatorName'], message: 'Provide simulatorId or simulatorName' },
{ allOf: ['bundleId'], message: 'bundleId is required' },
],
exclusivePairs: [['simulatorId', 'simulatorName']],
});