Skip to content

Commit 629a071

Browse files
committed
feat(simulator-runtime): make runtime tools session-aware
Use session-aware factory across simulator runtime tools, consolidate simulatorId defaults, and update docs/tests to match.
1 parent 9b506d1 commit 629a071

14 files changed

Lines changed: 666 additions & 874 deletions

docs/RELOADEROO_FOR_XCODEBUILDMCP.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ npx reloaderoo@latest --help
6060

6161
- **`boot_sim`**: Boots a simulator.
6262
```bash
63-
npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorUuid": "SIMULATOR_UUID"}' -- node build/index.js
63+
npx reloaderoo@latest inspect call-tool boot_sim --params '{"simulatorId": "SIMULATOR_UUID"}' -- node build/index.js
6464
```
6565
- **`build_run_sim`**: Builds and runs an app on a simulator.
6666
```bash
@@ -76,11 +76,11 @@ npx reloaderoo@latest --help
7676
```
7777
- **`install_app_sim`**: Installs an app on a simulator.
7878
```bash
79-
npx reloaderoo@latest inspect call-tool install_app_sim --params '{"simulatorUuid": "SIMULATOR_UUID", "appPath": "/path/to/MyApp.app"}' -- node build/index.js
79+
npx reloaderoo@latest inspect call-tool install_app_sim --params '{"simulatorId": "SIMULATOR_UUID", "appPath": "/path/to/MyApp.app"}' -- node build/index.js
8080
```
8181
- **`launch_app_logs_sim`**: Launches an app on a simulator with log capture.
8282
```bash
83-
npx reloaderoo@latest inspect call-tool launch_app_logs_sim --params '{"simulatorUuid": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -- node build/index.js
83+
npx reloaderoo@latest inspect call-tool launch_app_logs_sim --params '{"simulatorId": "SIMULATOR_UUID", "bundleId": "com.example.MyApp"}' -- node build/index.js
8484
```
8585
- **`launch_app_sim`**: Launches an app on a simulator.
8686
```bash

docs/session-aware-migration-todo.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,12 @@ Reference: `docs/session_management_plan.md`
3333
- [x] `src/mcp/tools/simulator/get_sim_app_path.ts` — session defaults: `projectPath`, `workspacePath`, `scheme`, `simulatorId`, `simulatorName`, `configuration`, `useLatestOS`, `arch`.
3434

3535
## Simulator Runtime Actions
36-
- [ ] `src/mcp/tools/simulator/boot_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
37-
- [ ] `src/mcp/tools/simulator/install_app_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
38-
- [ ] `src/mcp/tools/simulator/launch_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
39-
- [ ] `src/mcp/tools/simulator/launch_app_logs_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
40-
- [ ] `src/mcp/tools/simulator/stop_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
41-
- [ ] `src/mcp/tools/simulator/record_sim_video.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
36+
- [x] `src/mcp/tools/simulator/boot_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
37+
- [x] `src/mcp/tools/simulator/install_app_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
38+
- [x] `src/mcp/tools/simulator/launch_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
39+
- [x] `src/mcp/tools/simulator/launch_app_logs_sim.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
40+
- [x] `src/mcp/tools/simulator/stop_app_sim.ts` — session defaults: `simulatorId`, `simulatorName` (hydrate `simulatorUuid`).
41+
- [x] `src/mcp/tools/simulator/record_sim_video.ts` — session defaults: `simulatorId` (hydrate `simulatorUuid`).
4242

4343
## Simulator Management
4444
- [ ] `src/mcp/tools/simulator-management/erase_sims.ts` — session defaults: `simulatorId` (covers `simulatorUdid`).

src/mcp/tools/simulator/__tests__/boot_sim.test.ts

Lines changed: 37 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,57 +1,54 @@
11
/**
2-
* Tests for boot_sim plugin
3-
* Following CLAUDE.md testing standards with literal validation
4-
* Using dependency injection for deterministic testing
2+
* Tests for boot_sim plugin (session-aware version)
3+
* Follows CLAUDE.md guidance: dependency injection, no vi-mocks, literal validation.
54
*/
65

7-
import { describe, it, expect } from 'vitest';
6+
import { describe, it, expect, beforeEach } from 'vitest';
87
import { z } from 'zod';
9-
import {
10-
createMockExecutor,
11-
createMockFileSystemExecutor,
12-
createNoopExecutor,
13-
} from '../../../../test-utils/mock-executors.ts';
8+
import { createMockExecutor } from '../../../../test-utils/mock-executors.ts';
9+
import { sessionStore } from '../../../../utils/session-store.ts';
1410
import bootSim, { boot_simLogic } from '../boot_sim.ts';
1511

1612
describe('boot_sim tool', () => {
13+
beforeEach(() => {
14+
sessionStore.clear();
15+
});
16+
1717
describe('Export Field Validation (Literal)', () => {
1818
it('should have correct name', () => {
1919
expect(bootSim.name).toBe('boot_sim');
2020
});
2121

22-
it('should have correct description', () => {
23-
expect(bootSim.description).toBe(
24-
"Boots an iOS simulator. After booting, use open_sim() to make the simulator visible. IMPORTANT: You MUST provide the simulatorUuid parameter. Example: boot_sim({ simulatorUuid: 'YOUR_UUID_HERE' })",
25-
);
26-
});
27-
28-
it('should have handler function', () => {
29-
expect(typeof bootSim.handler).toBe('function');
22+
it('should have concise description', () => {
23+
expect(bootSim.description).toBe('Boots an iOS simulator.');
3024
});
3125

32-
it('should have correct schema with simulatorUuid string field', () => {
26+
it('should expose empty public schema', () => {
3327
const schema = z.object(bootSim.schema);
28+
expect(schema.safeParse({}).success).toBe(true);
29+
expect(Object.keys(bootSim.schema)).toHaveLength(0);
30+
});
31+
});
3432

35-
// Valid inputs
36-
expect(schema.safeParse({ simulatorUuid: 'test-uuid-123' }).success).toBe(true);
37-
expect(schema.safeParse({ simulatorUuid: 'ABC123-DEF456' }).success).toBe(true);
33+
describe('Handler Requirements', () => {
34+
it('should require simulatorId when not provided', async () => {
35+
const result = await bootSim.handler({});
3836

39-
// Invalid inputs
40-
expect(schema.safeParse({ simulatorUuid: 123 }).success).toBe(false);
41-
expect(schema.safeParse({ simulatorUuid: null }).success).toBe(false);
42-
expect(schema.safeParse({ simulatorUuid: undefined }).success).toBe(false);
43-
expect(schema.safeParse({}).success).toBe(false);
37+
expect(result.isError).toBe(true);
38+
expect(result.content[0].text).toContain('Missing required session defaults');
39+
expect(result.content[0].text).toContain('simulatorId is required');
40+
expect(result.content[0].text).toContain('session-set-defaults');
4441
});
4542
});
4643

47-
describe('Handler Behavior (Complete Literal Returns)', () => {
44+
describe('Logic Behavior (Literal Results)', () => {
4845
it('should handle successful boot', async () => {
4946
const mockExecutor = createMockExecutor({
5047
success: true,
5148
output: 'Simulator booted successfully',
5249
});
5350

54-
const result = await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
51+
const result = await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);
5552

5653
expect(result).toEqual({
5754
content: [
@@ -61,24 +58,10 @@ describe('boot_sim tool', () => {
6158
6259
Next steps:
6360
1. Open the Simulator app (makes it visible): open_sim()
64-
2. Install an app: install_app_sim({ simulatorUuid: "test-uuid-123", appPath: "PATH_TO_YOUR_APP" })
65-
3. Launch an app: launch_app_sim({ simulatorUuid: "test-uuid-123", bundleId: "YOUR_APP_BUNDLE_ID" })`,
66-
},
67-
],
68-
});
69-
});
70-
71-
it('should handle validation failure via handler', async () => {
72-
const result = await bootSim.handler({ simulatorUuid: undefined });
73-
74-
expect(result).toEqual({
75-
content: [
76-
{
77-
type: 'text',
78-
text: 'Error: Parameter validation failed\nDetails: Invalid parameters:\nsimulatorUuid: Required',
61+
2. Install an app: install_app_sim({ simulatorId: "test-uuid-123", appPath: "PATH_TO_YOUR_APP" })
62+
3. Launch an app: launch_app_sim({ simulatorId: "test-uuid-123", bundleId: "YOUR_APP_BUNDLE_ID" })`,
7963
},
8064
],
81-
isError: true,
8265
});
8366
});
8467

@@ -88,7 +71,7 @@ Next steps:
8871
error: 'Simulator not found',
8972
});
9073

91-
const result = await boot_simLogic({ simulatorUuid: 'invalid-uuid' }, mockExecutor);
74+
const result = await boot_simLogic({ simulatorId: 'invalid-uuid' }, mockExecutor);
9275

9376
expect(result).toEqual({
9477
content: [
@@ -105,7 +88,7 @@ Next steps:
10588
throw new Error('Connection failed');
10689
};
10790

108-
const result = await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
91+
const result = await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);
10992

11093
expect(result).toEqual({
11194
content: [
@@ -122,7 +105,7 @@ Next steps:
122105
throw 'String error';
123106
};
124107

125-
const result = await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
108+
const result = await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);
126109

127110
expect(result).toEqual({
128111
content: [
@@ -135,7 +118,12 @@ Next steps:
135118
});
136119

137120
it('should verify command generation with mock executor', async () => {
138-
const calls: any[] = [];
121+
const calls: Array<{
122+
command: string[];
123+
description: string;
124+
allowStderr: boolean;
125+
timeout?: number;
126+
}> = [];
139127
const mockExecutor = async (
140128
command: string[],
141129
description: string,
@@ -151,7 +139,7 @@ Next steps:
151139
};
152140
};
153141

154-
await boot_simLogic({ simulatorUuid: 'test-uuid-123' }, mockExecutor);
142+
await boot_simLogic({ simulatorId: 'test-uuid-123' }, mockExecutor);
155143

156144
expect(calls).toHaveLength(1);
157145
expect(calls[0]).toEqual({

0 commit comments

Comments
 (0)