#
tokens: 48554/50000 35/195 files (page 2/4)
lines: off (toggle) GitHub
raw markdown copy
This is page 2 of 4. Use http://codebase.md/stefan-nitu/mcp-xcode-server?page={x} to view the full context.

# Directory Structure

```
├── .claude
│   └── settings.local.json
├── .github
│   └── workflows
│       └── ci.yml
├── .gitignore
├── .vscode
│   └── settings.json
├── CLAUDE.md
├── CONTRIBUTING.md
├── docs
│   ├── ARCHITECTURE.md
│   ├── ERROR-HANDLING.md
│   └── TESTING-PHILOSOPHY.md
├── examples
│   └── screenshot-demo.js
├── jest.config.cjs
├── jest.e2e.config.cjs
├── LICENSE
├── package-lock.json
├── package.json
├── README.md
├── scripts
│   └── xcode-sync.swift
├── src
│   ├── application
│   │   └── ports
│   │       ├── ArtifactPorts.ts
│   │       ├── BuildPorts.ts
│   │       ├── CommandPorts.ts
│   │       ├── ConfigPorts.ts
│   │       ├── LoggingPorts.ts
│   │       ├── MappingPorts.ts
│   │       ├── OutputFormatterPorts.ts
│   │       ├── OutputParserPorts.ts
│   │       └── SimulatorPorts.ts
│   ├── cli.ts
│   ├── config.ts
│   ├── domain
│   │   ├── errors
│   │   │   └── DomainError.ts
│   │   ├── services
│   │   │   └── PlatformDetector.ts
│   │   ├── shared
│   │   │   └── Result.ts
│   │   └── tests
│   │       └── unit
│   │           └── PlatformDetector.unit.test.ts
│   ├── features
│   │   ├── app-management
│   │   │   ├── controllers
│   │   │   │   └── InstallAppController.ts
│   │   │   ├── domain
│   │   │   │   ├── InstallRequest.ts
│   │   │   │   └── InstallResult.ts
│   │   │   ├── factories
│   │   │   │   └── InstallAppControllerFactory.ts
│   │   │   ├── index.ts
│   │   │   ├── infrastructure
│   │   │   │   └── AppInstallerAdapter.ts
│   │   │   ├── tests
│   │   │   │   ├── e2e
│   │   │   │   │   ├── InstallAppController.e2e.test.ts
│   │   │   │   │   └── InstallAppMCP.e2e.test.ts
│   │   │   │   ├── integration
│   │   │   │   │   └── InstallAppController.integration.test.ts
│   │   │   │   └── unit
│   │   │   │       ├── AppInstallerAdapter.unit.test.ts
│   │   │   │       ├── InstallAppController.unit.test.ts
│   │   │   │       ├── InstallAppUseCase.unit.test.ts
│   │   │   │       ├── InstallRequest.unit.test.ts
│   │   │   │       └── InstallResult.unit.test.ts
│   │   │   └── use-cases
│   │   │       └── InstallAppUseCase.ts
│   │   ├── build
│   │   │   ├── controllers
│   │   │   │   └── BuildXcodeController.ts
│   │   │   ├── domain
│   │   │   │   ├── BuildDestination.ts
│   │   │   │   ├── BuildIssue.ts
│   │   │   │   ├── BuildRequest.ts
│   │   │   │   ├── BuildResult.ts
│   │   │   │   └── PlatformInfo.ts
│   │   │   ├── factories
│   │   │   │   └── BuildXcodeControllerFactory.ts
│   │   │   ├── index.ts
│   │   │   ├── infrastructure
│   │   │   │   ├── BuildArtifactLocatorAdapter.ts
│   │   │   │   ├── BuildDestinationMapperAdapter.ts
│   │   │   │   ├── XcbeautifyFormatterAdapter.ts
│   │   │   │   ├── XcbeautifyOutputParserAdapter.ts
│   │   │   │   └── XcodeBuildCommandAdapter.ts
│   │   │   ├── tests
│   │   │   │   ├── e2e
│   │   │   │   │   ├── BuildXcodeController.e2e.test.ts
│   │   │   │   │   └── BuildXcodeMCP.e2e.test.ts
│   │   │   │   ├── integration
│   │   │   │   │   └── BuildXcodeController.integration.test.ts
│   │   │   │   └── unit
│   │   │   │       ├── BuildArtifactLocatorAdapter.unit.test.ts
│   │   │   │       ├── BuildDestinationMapperAdapter.unit.test.ts
│   │   │   │       ├── BuildIssue.unit.test.ts
│   │   │   │       ├── BuildProjectUseCase.unit.test.ts
│   │   │   │       ├── BuildRequest.unit.test.ts
│   │   │   │       ├── BuildResult.unit.test.ts
│   │   │   │       ├── BuildXcodeController.unit.test.ts
│   │   │   │       ├── BuildXcodePresenter.unit.test.ts
│   │   │   │       ├── PlatformInfo.unit.test.ts
│   │   │   │       ├── XcbeautifyFormatterAdapter.unit.test.ts
│   │   │   │       ├── XcbeautifyOutputParserAdapter.unit.test.ts
│   │   │   │       └── XcodeBuildCommandAdapter.unit.test.ts
│   │   │   └── use-cases
│   │   │       └── BuildProjectUseCase.ts
│   │   └── simulator
│   │       ├── controllers
│   │       │   ├── BootSimulatorController.ts
│   │       │   ├── ListSimulatorsController.ts
│   │       │   └── ShutdownSimulatorController.ts
│   │       ├── domain
│   │       │   ├── BootRequest.ts
│   │       │   ├── BootResult.ts
│   │       │   ├── ListSimulatorsRequest.ts
│   │       │   ├── ListSimulatorsResult.ts
│   │       │   ├── ShutdownRequest.ts
│   │       │   ├── ShutdownResult.ts
│   │       │   └── SimulatorState.ts
│   │       ├── factories
│   │       │   ├── BootSimulatorControllerFactory.ts
│   │       │   ├── ListSimulatorsControllerFactory.ts
│   │       │   └── ShutdownSimulatorControllerFactory.ts
│   │       ├── index.ts
│   │       ├── infrastructure
│   │       │   ├── SimulatorControlAdapter.ts
│   │       │   └── SimulatorLocatorAdapter.ts
│   │       ├── tests
│   │       │   ├── e2e
│   │       │   │   ├── BootSimulatorController.e2e.test.ts
│   │       │   │   ├── BootSimulatorMCP.e2e.test.ts
│   │       │   │   ├── ListSimulatorsController.e2e.test.ts
│   │       │   │   ├── ListSimulatorsMCP.e2e.test.ts
│   │       │   │   ├── ShutdownSimulatorController.e2e.test.ts
│   │       │   │   └── ShutdownSimulatorMCP.e2e.test.ts
│   │       │   ├── integration
│   │       │   │   ├── BootSimulatorController.integration.test.ts
│   │       │   │   ├── ListSimulatorsController.integration.test.ts
│   │       │   │   └── ShutdownSimulatorController.integration.test.ts
│   │       │   └── unit
│   │       │       ├── BootRequest.unit.test.ts
│   │       │       ├── BootResult.unit.test.ts
│   │       │       ├── BootSimulatorController.unit.test.ts
│   │       │       ├── BootSimulatorUseCase.unit.test.ts
│   │       │       ├── ListSimulatorsController.unit.test.ts
│   │       │       ├── ListSimulatorsUseCase.unit.test.ts
│   │       │       ├── ShutdownRequest.unit.test.ts
│   │       │       ├── ShutdownResult.unit.test.ts
│   │       │       ├── ShutdownSimulatorUseCase.unit.test.ts
│   │       │       ├── SimulatorControlAdapter.unit.test.ts
│   │       │       └── SimulatorLocatorAdapter.unit.test.ts
│   │       └── use-cases
│   │           ├── BootSimulatorUseCase.ts
│   │           ├── ListSimulatorsUseCase.ts
│   │           └── ShutdownSimulatorUseCase.ts
│   ├── index.ts
│   ├── infrastructure
│   │   ├── repositories
│   │   │   └── DeviceRepository.ts
│   │   ├── services
│   │   │   └── DependencyChecker.ts
│   │   └── tests
│   │       └── unit
│   │           ├── DependencyChecker.unit.test.ts
│   │           └── DeviceRepository.unit.test.ts
│   ├── logger.ts
│   ├── presentation
│   │   ├── decorators
│   │   │   └── DependencyCheckingDecorator.ts
│   │   ├── formatters
│   │   │   ├── ErrorFormatter.ts
│   │   │   └── strategies
│   │   │       ├── BuildIssuesStrategy.ts
│   │   │       ├── DefaultErrorStrategy.ts
│   │   │       ├── ErrorFormattingStrategy.ts
│   │   │       └── OutputFormatterErrorStrategy.ts
│   │   ├── interfaces
│   │   │   ├── IDependencyChecker.ts
│   │   │   ├── MCPController.ts
│   │   │   └── MCPResponse.ts
│   │   ├── presenters
│   │   │   └── BuildXcodePresenter.ts
│   │   └── tests
│   │       └── unit
│   │           ├── BuildIssuesStrategy.unit.test.ts
│   │           ├── DefaultErrorStrategy.unit.test.ts
│   │           ├── DependencyCheckingDecorator.unit.test.ts
│   │           └── ErrorFormatter.unit.test.ts
│   ├── shared
│   │   ├── domain
│   │   │   ├── AppPath.ts
│   │   │   ├── DeviceId.ts
│   │   │   ├── Platform.ts
│   │   │   └── ProjectPath.ts
│   │   ├── index.ts
│   │   ├── infrastructure
│   │   │   ├── ConfigProviderAdapter.ts
│   │   │   └── ShellCommandExecutorAdapter.ts
│   │   └── tests
│   │       ├── mocks
│   │       │   ├── promisifyExec.ts
│   │       │   ├── selectiveExecMock.ts
│   │       │   └── xcodebuildHelpers.ts
│   │       ├── skipped
│   │       │   ├── cli.e2e.test.skip
│   │       │   ├── hook-e2e.test.skip
│   │       │   ├── hook-path.e2e.test.skip
│   │       │   └── hook.test.skip
│   │       ├── types
│   │       │   └── execTypes.ts
│   │       ├── unit
│   │       │   ├── AppPath.unit.test.ts
│   │       │   ├── ConfigProviderAdapter.unit.test.ts
│   │       │   ├── ProjectPath.unit.test.ts
│   │       │   └── ShellCommandExecutorAdapter.unit.test.ts
│   │       └── utils
│   │           ├── gitResetTestArtifacts.ts
│   │           ├── mockHelpers.ts
│   │           ├── TestEnvironmentCleaner.ts
│   │           ├── TestErrorInjector.ts
│   │           ├── testHelpers.ts
│   │           ├── TestProjectManager.ts
│   │           └── TestSimulatorManager.ts
│   ├── types.ts
│   ├── utils
│   │   ├── devices
│   │   │   ├── Devices.ts
│   │   │   ├── SimulatorApps.ts
│   │   │   ├── SimulatorBoot.ts
│   │   │   ├── SimulatorDevice.ts
│   │   │   ├── SimulatorInfo.ts
│   │   │   ├── SimulatorReset.ts
│   │   │   └── SimulatorUI.ts
│   │   ├── errors
│   │   │   ├── index.ts
│   │   │   └── xcbeautify-parser.ts
│   │   ├── index.ts
│   │   ├── LogManager.ts
│   │   ├── LogManagerInstance.ts
│   │   └── projects
│   │       ├── SwiftBuild.ts
│   │       ├── SwiftPackage.ts
│   │       ├── SwiftPackageInfo.ts
│   │       ├── Xcode.ts
│   │       ├── XcodeArchive.ts
│   │       ├── XcodeBuild.ts
│   │       ├── XcodeErrors.ts
│   │       ├── XcodeInfo.ts
│   │       └── XcodeProject.ts
│   └── utils.ts
├── test_artifacts
│   ├── Test.xcworkspace
│   │   ├── contents.xcworkspacedata
│   │   └── xcuserdata
│   │       └── stefan.xcuserdatad
│   │           └── UserInterfaceState.xcuserstate
│   ├── TestProjectSwiftTesting
│   │   ├── TestProjectSwiftTesting
│   │   │   ├── Assets.xcassets
│   │   │   │   ├── AccentColor.colorset
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── AppIcon.appiconset
│   │   │   │   │   └── Contents.json
│   │   │   │   └── Contents.json
│   │   │   ├── ContentView.swift
│   │   │   ├── Item.swift
│   │   │   ├── TestProjectSwiftTesting.entitlements
│   │   │   └── TestProjectSwiftTestingApp.swift
│   │   ├── TestProjectSwiftTesting.xcodeproj
│   │   │   ├── project.pbxproj
│   │   │   ├── project.xcworkspace
│   │   │   │   ├── contents.xcworkspacedata
│   │   │   │   └── xcuserdata
│   │   │   │       └── stefan.xcuserdatad
│   │   │   │           └── UserInterfaceState.xcuserstate
│   │   │   └── xcuserdata
│   │   │       └── stefan.xcuserdatad
│   │   │           └── xcschemes
│   │   │               └── xcschememanagement.plist
│   │   ├── TestProjectSwiftTestingTests
│   │   │   └── TestProjectSwiftTestingTests.swift
│   │   └── TestProjectSwiftTestingUITests
│   │       ├── TestProjectSwiftTestingUITests.swift
│   │       └── TestProjectSwiftTestingUITestsLaunchTests.swift
│   ├── TestProjectWatchOS
│   │   ├── TestProjectWatchOS
│   │   │   ├── Assets.xcassets
│   │   │   │   ├── AccentColor.colorset
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── AppIcon.appiconset
│   │   │   │   │   └── Contents.json
│   │   │   │   └── Contents.json
│   │   │   ├── ContentView.swift
│   │   │   └── TestProjectWatchOSApp.swift
│   │   ├── TestProjectWatchOS Watch App
│   │   │   ├── Assets.xcassets
│   │   │   │   ├── AccentColor.colorset
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── AppIcon.appiconset
│   │   │   │   │   └── Contents.json
│   │   │   │   └── Contents.json
│   │   │   ├── ContentView.swift
│   │   │   └── TestProjectWatchOSApp.swift
│   │   ├── TestProjectWatchOS Watch AppTests
│   │   │   └── TestProjectWatchOS_Watch_AppTests.swift
│   │   ├── TestProjectWatchOS Watch AppUITests
│   │   │   ├── TestProjectWatchOS_Watch_AppUITests.swift
│   │   │   └── TestProjectWatchOS_Watch_AppUITestsLaunchTests.swift
│   │   ├── TestProjectWatchOS.xcodeproj
│   │   │   ├── project.pbxproj
│   │   │   └── project.xcworkspace
│   │   │       └── contents.xcworkspacedata
│   │   ├── TestProjectWatchOSTests
│   │   │   └── TestProjectWatchOSTests.swift
│   │   └── TestProjectWatchOSUITests
│   │       ├── TestProjectWatchOSUITests.swift
│   │       └── TestProjectWatchOSUITestsLaunchTests.swift
│   ├── TestProjectXCTest
│   │   ├── TestProjectXCTest
│   │   │   ├── Assets.xcassets
│   │   │   │   ├── AccentColor.colorset
│   │   │   │   │   └── Contents.json
│   │   │   │   ├── AppIcon.appiconset
│   │   │   │   │   └── Contents.json
│   │   │   │   └── Contents.json
│   │   │   ├── ContentView.swift
│   │   │   ├── Item.swift
│   │   │   ├── TestProjectXCTest.entitlements
│   │   │   └── TestProjectXCTestApp.swift
│   │   ├── TestProjectXCTest.xcodeproj
│   │   │   ├── project.pbxproj
│   │   │   ├── project.xcworkspace
│   │   │   │   ├── contents.xcworkspacedata
│   │   │   │   └── xcuserdata
│   │   │   │       └── stefan.xcuserdatad
│   │   │   │           └── UserInterfaceState.xcuserstate
│   │   │   └── xcuserdata
│   │   │       └── stefan.xcuserdatad
│   │   │           └── xcschemes
│   │   │               └── xcschememanagement.plist
│   │   ├── TestProjectXCTestTests
│   │   │   └── TestProjectXCTestTests.swift
│   │   └── TestProjectXCTestUITests
│   │       ├── TestProjectXCTestUITests.swift
│   │       └── TestProjectXCTestUITestsLaunchTests.swift
│   ├── TestSwiftPackageSwiftTesting
│   │   ├── .gitignore
│   │   ├── Package.swift
│   │   ├── Sources
│   │   │   ├── TestSwiftPackageSwiftTesting
│   │   │   │   └── TestSwiftPackageSwiftTesting.swift
│   │   │   └── TestSwiftPackageSwiftTestingExecutable
│   │   │       └── main.swift
│   │   └── Tests
│   │       └── TestSwiftPackageSwiftTestingTests
│   │           └── TestSwiftPackageSwiftTestingTests.swift
│   └── TestSwiftPackageXCTest
│       ├── .gitignore
│       ├── Package.swift
│       ├── Sources
│       │   ├── TestSwiftPackageXCTest
│       │   │   └── TestSwiftPackageXCTest.swift
│       │   └── TestSwiftPackageXCTestExecutable
│       │       └── main.swift
│       └── Tests
│           └── TestSwiftPackageXCTestTests
│               └── TestSwiftPackageXCTestTests.swift
├── tsconfig.json
└── XcodeProjectModifier
    ├── Package.resolved
    ├── Package.swift
    └── Sources
        └── XcodeProjectModifier
            └── main.swift
```

# Files

--------------------------------------------------------------------------------
/src/infrastructure/tests/unit/DependencyChecker.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest } from '@jest/globals';
import { DependencyChecker } from '../../services/DependencyChecker.js';
import { ICommandExecutor } from '../../../application/ports/CommandPorts.js';

describe('DependencyChecker', () => {
  function createSUT() {
    const mockExecute = jest.fn<ICommandExecutor['execute']>();
    const mockExecutor: ICommandExecutor = { execute: mockExecute };
    const sut = new DependencyChecker(mockExecutor);
    return { sut, mockExecute };
  }

  describe('check', () => {
    it('should return empty array when all dependencies are installed', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();

      // All which commands succeed
      mockExecute.mockResolvedValue({
        stdout: '/usr/bin/xcodebuild',
        stderr: '',
        exitCode: 0
      });

      // Act
      const result = await sut.check(['xcodebuild', 'xcbeautify']);

      // Assert - behavior: no missing dependencies
      expect(result).toEqual([]);
    });

    it('should return missing dependencies with install commands', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();

      // xcbeautify not found
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: 'xcbeautify not found',
        exitCode: 1
      });

      // Act
      const result = await sut.check(['xcbeautify']);

      // Assert - behavior: returns missing dependency with install command
      expect(result).toEqual([
        {
          name: 'xcbeautify',
          installCommand: 'brew install xcbeautify'
        }
      ]);
    });

    it('should handle mix of installed and missing dependencies', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();

      // xcodebuild found, xcbeautify not found
      mockExecute
        .mockResolvedValueOnce({
          stdout: '/usr/bin/xcodebuild',
          stderr: '',
          exitCode: 0
        })
        .mockResolvedValueOnce({
          stdout: '',
          stderr: 'xcbeautify not found',
          exitCode: 1
        });

      // Act
      const result = await sut.check(['xcodebuild', 'xcbeautify']);

      // Assert - behavior: only missing dependencies returned
      expect(result).toEqual([
        {
          name: 'xcbeautify',
          installCommand: 'brew install xcbeautify'
        }
      ]);
    });

    it('should handle unknown dependencies', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();

      // Unknown tool not found
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: 'unknowntool not found',
        exitCode: 1
      });

      // Act
      const result = await sut.check(['unknowntool']);

      // Assert - behavior: returns missing dependency without install command
      expect(result).toEqual([
        {
          name: 'unknowntool'
        }
      ]);
    });

    it('should provide appropriate install commands for known tools', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();

      // All tools missing
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: 'not found',
        exitCode: 1
      });

      // Act
      const result = await sut.check(['xcodebuild', 'xcrun', 'xcbeautify']);

      // Assert - behavior: each tool has appropriate install command
      expect(result).toContainEqual({
        name: 'xcodebuild',
        installCommand: 'Install Xcode from the App Store'
      });
      expect(result).toContainEqual({
        name: 'xcrun',
        installCommand: 'Install Xcode Command Line Tools: xcode-select --install'
      });
      expect(result).toContainEqual({
        name: 'xcbeautify',
        installCommand: 'brew install xcbeautify'
      });
    });
  });
});
```

--------------------------------------------------------------------------------
/src/features/app-management/tests/e2e/InstallAppMCP.e2e.test.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * E2E Test for Install App through MCP Protocol
 * 
 * Tests critical user journey: Installing an app on simulator through MCP
 * Following testing philosophy: E2E tests for critical paths only (10%)
 * 
 * Focus: MCP protocol interaction, not app installation logic
 * The controller tests already verify installation works with real simulators
 * This test verifies the MCP transport/serialization/protocol works
 * 
 * NO MOCKS - Uses real MCP server, real simulators, real apps
 */

import { describe, it, expect, beforeAll, afterAll, beforeEach, afterEach } from '@jest/globals';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
import { createAndConnectClient, cleanupClientAndTransport, bootAndWaitForSimulator } from '../../../../shared/tests/utils/testHelpers.js';
import { TestProjectManager } from '../../../../shared/tests/utils/TestProjectManager.js';
import { exec } from 'child_process';
import { promisify } from 'util';
import * as fs from 'fs';

const execAsync = promisify(exec);

describe('Install App MCP E2E', () => {
  let client: Client;
  let transport: StdioClientTransport;
  let testManager: TestProjectManager;
  let testDeviceId: string;
  let testAppPath: string;
  
  beforeAll(async () => {
    // Prepare test projects
    testManager = new TestProjectManager();
    await testManager.setup();
    
    // Build the server
    const { execSync } = await import('child_process');
    execSync('npm run build', { stdio: 'inherit' });

    // Build the test app using TestProjectManager
    testAppPath = await testManager.buildApp('xcodeProject');
    
    // Get the latest iOS runtime
    const runtimesResult = await execAsync('xcrun simctl list runtimes --json');
    const runtimes = JSON.parse(runtimesResult.stdout);
    const iosRuntime = runtimes.runtimes.find((r: { platform: string }) => r.platform === 'iOS');
    
    if (!iosRuntime) {
      throw new Error('No iOS runtime found. Please install an iOS simulator runtime.');
    }
    
    // Create and boot a test simulator
    const createResult = await execAsync(
      `xcrun simctl create "TestSimulator-InstallAppMCP" "iPhone 15" "${iosRuntime.identifier}"`
    );
    testDeviceId = createResult.stdout.trim();
    
    // Boot the simulator and wait for it to be ready
    await bootAndWaitForSimulator(testDeviceId, 30);
  });
  
  afterAll(async () => {
    // Clean up simulator
    if (testDeviceId) {
      try {
        await execAsync(`xcrun simctl shutdown "${testDeviceId}"`);
        await execAsync(`xcrun simctl delete "${testDeviceId}"`);
      } catch (error) {
        // Ignore cleanup errors
      }
    }
    
    // Clean up test project
    await testManager.cleanup();
  });
  
  beforeEach(async () => {
    ({ client, transport } = await createAndConnectClient());
  });
  
  afterEach(async () => {
    await cleanupClientAndTransport(client, transport);
  });
  
  it('should complete install workflow through MCP', async () => {
    // This tests the critical user journey:
    // User connects via MCP → calls install_app → receives result
    
    const result = await client.request(
      {
        method: 'tools/call',
        params: {
          name: 'install_app',
          arguments: {
            appPath: testAppPath,
            simulatorId: testDeviceId
          }
        }
      },
      CallToolResultSchema,
      { timeout: 120000 }
    );
    
    expect(result).toBeDefined();
    expect(result.content).toBeInstanceOf(Array);
    
    const textContent = result.content.find((c: any) => c.type === 'text');
    expect(textContent?.text).toContain('Successfully installed');
  });
});
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/e2e/BootSimulatorMCP.e2e.test.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * E2E Test for Boot Simulator through MCP Protocol
 * 
 * Tests critical user journey: Booting a simulator through MCP
 * Following testing philosophy: E2E tests for critical paths only (10%)
 * 
 * Focus: MCP protocol interaction, not simulator boot logic
 * The controller tests already verify boot works with real simulators
 * This test verifies the MCP transport/serialization/protocol works
 * 
 * NO MOCKS - Uses real MCP server, real simulators
 */

import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
import { createAndConnectClient, cleanupClientAndTransport } from '../../../../shared/tests/utils/testHelpers.js';
import { TestSimulatorManager } from '../../../../shared/tests/utils/TestSimulatorManager.js';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

describe('Boot Simulator MCP E2E', () => {
  let client: Client;
  let transport: StdioClientTransport;
  let testSimManager: TestSimulatorManager;
  
  beforeAll(async () => {
    // Build the server
    const { execSync } = await import('child_process');
    execSync('npm run build', { stdio: 'inherit' });

    // Set up test simulator
    testSimManager = new TestSimulatorManager();
    await testSimManager.getOrCreateSimulator('TestSimulator-BootMCP');

    // Connect to MCP server
    ({ client, transport } = await createAndConnectClient());
  });
  
  beforeEach(async () => {
    // Ensure simulator is shutdown before each test
    await testSimManager.shutdownAndWait(5);
  });
  
  afterAll(async () => {
    // Cleanup test simulator
    await testSimManager.cleanup();

    // Cleanup MCP connection
    await cleanupClientAndTransport(client, transport);
  });

  describe('boot simulator through MCP', () => {
    it('should boot simulator via MCP protocol', async () => {
      // Act - Call tool through MCP
      const result = await client.callTool({
        name: 'boot_simulator',
        arguments: {
          deviceId: testSimManager.getSimulatorName()
        }
      });
      
      // Assert - Verify MCP response
      const parsed = CallToolResultSchema.parse(result);
      expect(parsed.content[0].type).toBe('text');
      expect(parsed.content[0].text).toBe(`✅ Successfully booted simulator: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
      
      // Verify simulator is actually booted
      const isBooted = await testSimManager.isBooted();
      expect(isBooted).toBe(true);
    });
    
    it('should handle already booted simulator via MCP', async () => {
      // Arrange - boot the simulator first
      await testSimManager.bootAndWait(5);
      await new Promise(resolve => setTimeout(resolve, 2000)); // Wait for boot
      
      // Act - Call tool through MCP
      const result = await client.callTool({
        name: 'boot_simulator',
        arguments: {
          deviceId: testSimManager.getSimulatorId()
        }
      });
      
      // Assert
      const parsed = CallToolResultSchema.parse(result);
      expect(parsed.content[0].text).toBe(`✅ Simulator already booted: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
    });
  });

  describe('error handling through MCP', () => {
    it('should return error for non-existent simulator', async () => {
      // Act
      const result = await client.callTool({
        name: 'boot_simulator',
        arguments: {
          deviceId: 'NonExistentSimulator-MCP'
        }
      });
      
      // Assert
      const parsed = CallToolResultSchema.parse(result);
      expect(parsed.content[0].text).toBe('❌ Simulator not found: NonExistentSimulator-MCP');
    });
  });
});
```

--------------------------------------------------------------------------------
/src/shared/tests/unit/AppPath.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect } from '@jest/globals';
import { AppPath } from '../../domain/AppPath.js';

describe('AppPath', () => {
  describe('create', () => {
    it('should create valid AppPath with .app extension', () => {
      // Arrange & Act
      const appPath = AppPath.create('/path/to/MyApp.app');
      
      // Assert
      expect(appPath.toString()).toBe('/path/to/MyApp.app');
      expect(appPath.name).toBe('MyApp.app');
    });

    it('should accept paths with spaces', () => {
      // Arrange & Act
      const appPath = AppPath.create('/path/to/My Cool App.app');
      
      // Assert
      expect(appPath.toString()).toBe('/path/to/My Cool App.app');
      expect(appPath.name).toBe('My Cool App.app');
    });

    it('should accept relative paths', () => {
      // Arrange & Act
      const appPath = AppPath.create('./build/Debug/TestApp.app');
      
      // Assert
      expect(appPath.toString()).toBe('./build/Debug/TestApp.app');
      expect(appPath.name).toBe('TestApp.app');
    });

    it('should throw error for empty path', () => {
      // Arrange, Act & Assert
      expect(() => AppPath.create('')).toThrow('App path cannot be empty');
    });

    it('should throw error for path without .app extension', () => {
      // Arrange, Act & Assert
      expect(() => AppPath.create('/path/to/MyApp')).toThrow('App path must end with .app');
      expect(() => AppPath.create('/path/to/MyApp.ipa')).toThrow('App path must end with .app');
      expect(() => AppPath.create('/path/to/binary')).toThrow('App path must end with .app');
    });

    it('should throw error for path with directory traversal', () => {
      // Arrange, Act & Assert
      expect(() => AppPath.create('../../../etc/passwd.app')).toThrow('App path cannot contain directory traversal');
      expect(() => AppPath.create('/path/../../../etc/evil.app')).toThrow('App path cannot contain directory traversal');
      expect(() => AppPath.create('/valid/path/../../sneaky.app')).toThrow('App path cannot contain directory traversal');
    });

    it('should throw error for path with null characters', () => {
      // Arrange, Act & Assert
      expect(() => AppPath.create('/path/to/MyApp.app\0')).toThrow('App path cannot contain null characters');
      expect(() => AppPath.create('/path\0/to/MyApp.app')).toThrow('App path cannot contain null characters');
    });

    it('should handle paths ending with slash after .app', () => {
      // Arrange & Act
      const appPath = AppPath.create('/path/to/MyApp.app/');
      
      // Assert
      expect(appPath.toString()).toBe('/path/to/MyApp.app/');
      expect(appPath.name).toBe('MyApp.app');
    });
  });

  describe('name property', () => {
    it('should extract app name from simple path', () => {
      // Arrange & Act
      const appPath = AppPath.create('/Users/dev/MyApp.app');
      
      // Assert
      expect(appPath.name).toBe('MyApp.app');
    });

    it('should extract app name from Windows-style path', () => {
      // Arrange & Act  
      const appPath = AppPath.create('C:\\Users\\dev\\MyApp.app');
      
      // Assert
      expect(appPath.name).toBe('MyApp.app');
    });

    it('should handle app name with special characters', () => {
      // Arrange & Act
      const appPath = AppPath.create('/path/to/My-App_v1.2.3.app');
      
      // Assert
      expect(appPath.name).toBe('My-App_v1.2.3.app');
    });

    it('should handle just the app name without path', () => {
      // Arrange & Act
      const appPath = AppPath.create('MyApp.app');
      
      // Assert
      expect(appPath.name).toBe('MyApp.app');
    });
  });

  describe('toString', () => {
    it('should return the original path', () => {
      // Arrange
      const originalPath = '/path/to/MyApp.app';
      
      // Act
      const appPath = AppPath.create(originalPath);
      
      // Assert
      expect(appPath.toString()).toBe(originalPath);
    });
  });
});
```

--------------------------------------------------------------------------------
/src/features/app-management/tests/unit/AppInstallerAdapter.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest, beforeEach } from '@jest/globals';
import { AppInstallerAdapter } from '../../infrastructure/AppInstallerAdapter.js';
import { ICommandExecutor } from '../../../../application/ports/CommandPorts.js';

describe('AppInstallerAdapter', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });

  function createSUT() {
    const mockExecute = jest.fn<ICommandExecutor['execute']>();
    const mockExecutor: ICommandExecutor = {
      execute: mockExecute
    };
    const sut = new AppInstallerAdapter(mockExecutor);
    return { sut, mockExecute };
  }

  describe('installApp', () => {
    it('should install app successfully', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: '',
        exitCode: 0
      });

      // Act
      await sut.installApp('/path/to/MyApp.app', 'ABC-123');

      // Assert
      expect(mockExecute).toHaveBeenCalledWith(
        'xcrun simctl install "ABC-123" "/path/to/MyApp.app"'
      );
    });

    it('should handle paths with spaces', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: '',
        exitCode: 0
      });

      // Act
      await sut.installApp('/path/to/My Cool App.app', 'ABC-123');

      // Assert
      expect(mockExecute).toHaveBeenCalledWith(
        'xcrun simctl install "ABC-123" "/path/to/My Cool App.app"'
      );
    });

    it('should throw error for invalid app bundle', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: 'An error was encountered processing the command (domain=NSPOSIXErrorDomain, code=2):\nFailed to install "/path/to/NotAnApp.app"',
        exitCode: 1
      });

      // Act & Assert
      await expect(sut.installApp('/path/to/NotAnApp.app', 'ABC-123'))
        .rejects.toThrow('An error was encountered processing the command');
    });

    it('should throw error when device not found', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: 'Invalid device: NON-EXISTENT',
        exitCode: 164
      });

      // Act & Assert
      await expect(sut.installApp('/path/to/MyApp.app', 'NON-EXISTENT'))
        .rejects.toThrow('Invalid device: NON-EXISTENT');
    });

    it('should throw error when simulator not booted', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: 'Unable to install "/path/to/MyApp.app"\nAn error was encountered processing the command (domain=com.apple.CoreSimulator.SimError, code=405):\nUnable to install applications when the device is not booted.',
        exitCode: 149
      });

      // Act & Assert
      await expect(sut.installApp('/path/to/MyApp.app', 'ABC-123'))
        .rejects.toThrow('Unable to install applications when the device is not booted');
    });

    it('should throw generic error when stderr is empty', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: '',
        exitCode: 1
      });

      // Act & Assert
      await expect(sut.installApp('/path/to/MyApp.app', 'ABC-123'))
        .rejects.toThrow('Failed to install app');
    });

    it('should throw error for app with invalid signature', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockResolvedValue({
        stdout: '',
        stderr: 'The code signature version is no longer supported',
        exitCode: 1
      });

      // Act & Assert
      await expect(sut.installApp('/path/to/MyApp.app', 'ABC-123'))
        .rejects.toThrow('The code signature version is no longer supported');
    });
  });
});
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/unit/ShutdownResult.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect } from '@jest/globals';
import { 
  ShutdownResult, 
  ShutdownOutcome, 
  SimulatorNotFoundError, 
  ShutdownCommandFailedError 
} from '../../domain/ShutdownResult.js';

describe('ShutdownResult', () => {
  describe('shutdown', () => {
    it('should create a successful shutdown result', () => {
      // Arrange
      const simulatorId = 'ABC123';
      const simulatorName = 'iPhone 15';
      
      // Act
      const result = ShutdownResult.shutdown(simulatorId, simulatorName);
      
      // Assert
      expect(result.outcome).toBe(ShutdownOutcome.Shutdown);
      expect(result.diagnostics.simulatorId).toBe('ABC123');
      expect(result.diagnostics.simulatorName).toBe('iPhone 15');
      expect(result.diagnostics.error).toBeUndefined();
    });
  });

  describe('alreadyShutdown', () => {
    it('should create an already shutdown result', () => {
      // Arrange
      const simulatorId = 'ABC123';
      const simulatorName = 'iPhone 15';
      
      // Act
      const result = ShutdownResult.alreadyShutdown(simulatorId, simulatorName);
      
      // Assert
      expect(result.outcome).toBe(ShutdownOutcome.AlreadyShutdown);
      expect(result.diagnostics.simulatorId).toBe('ABC123');
      expect(result.diagnostics.simulatorName).toBe('iPhone 15');
      expect(result.diagnostics.error).toBeUndefined();
    });
  });

  describe('failed', () => {
    it('should create a failed result with SimulatorNotFoundError', () => {
      // Arrange
      const error = new SimulatorNotFoundError('non-existent');
      
      // Act
      const result = ShutdownResult.failed(undefined, undefined, error);
      
      // Assert
      expect(result.outcome).toBe(ShutdownOutcome.Failed);
      expect(result.diagnostics.simulatorId).toBeUndefined();
      expect(result.diagnostics.simulatorName).toBeUndefined();
      expect(result.diagnostics.error).toBe(error);
      expect(result.diagnostics.error).toBeInstanceOf(SimulatorNotFoundError);
    });

    it('should create a failed result with ShutdownCommandFailedError', () => {
      // Arrange
      const error = new ShutdownCommandFailedError('Device is busy');
      const simulatorId = 'ABC123';
      const simulatorName = 'iPhone 15';
      
      // Act
      const result = ShutdownResult.failed(simulatorId, simulatorName, error);
      
      // Assert
      expect(result.outcome).toBe(ShutdownOutcome.Failed);
      expect(result.diagnostics.simulatorId).toBe('ABC123');
      expect(result.diagnostics.simulatorName).toBe('iPhone 15');
      expect(result.diagnostics.error).toBe(error);
      expect(result.diagnostics.error).toBeInstanceOf(ShutdownCommandFailedError);
    });

    it('should handle generic errors', () => {
      // Arrange
      const error = new Error('Unknown error');
      
      // Act
      const result = ShutdownResult.failed('123', 'Test Device', error);
      
      // Assert
      expect(result.outcome).toBe(ShutdownOutcome.Failed);
      expect(result.diagnostics.error).toBe(error);
    });
  });
});

describe('SimulatorNotFoundError', () => {
  it('should store device ID', () => {
    // Arrange & Act
    const error = new SimulatorNotFoundError('iPhone-16');
    
    // Assert
    expect(error.deviceId).toBe('iPhone-16');
    expect(error.name).toBe('SimulatorNotFoundError');
    expect(error.message).toBe('iPhone-16');
  });

  it('should be an instance of Error', () => {
    // Arrange & Act
    const error = new SimulatorNotFoundError('test');
    
    // Assert
    expect(error).toBeInstanceOf(Error);
  });
});

describe('ShutdownCommandFailedError', () => {
  it('should store stderr output', () => {
    // Arrange & Act
    const error = new ShutdownCommandFailedError('Device is locked');
    
    // Assert
    expect(error.stderr).toBe('Device is locked');
    expect(error.name).toBe('ShutdownCommandFailedError');
    expect(error.message).toBe('Device is locked');
  });

  it('should handle empty stderr', () => {
    // Arrange & Act
    const error = new ShutdownCommandFailedError('');
    
    // Assert
    expect(error.stderr).toBe('');
    expect(error.message).toBe('');
  });

  it('should be an instance of Error', () => {
    // Arrange & Act
    const error = new ShutdownCommandFailedError('test');
    
    // Assert
    expect(error).toBeInstanceOf(Error);
  });
});
```

--------------------------------------------------------------------------------
/src/utils/projects/XcodeArchive.ts:
--------------------------------------------------------------------------------

```typescript
import { execAsync } from '../../utils.js';
import { createModuleLogger } from '../../logger.js';
import { Platform } from '../../types.js';
import { PlatformInfo } from '../../features/build/domain/PlatformInfo.js';
import path from 'path';

const logger = createModuleLogger('XcodeArchive');

export interface ArchiveOptions {
  scheme: string;
  configuration?: string;
  platform?: Platform;
  archivePath?: string;
}

export interface ExportOptions {
  exportMethod?: 'app-store' | 'ad-hoc' | 'enterprise' | 'development';
  exportPath?: string;
}

/**
 * Handles archiving and exporting for Xcode projects
 */
export class XcodeArchive {
  /**
   * Archive an Xcode project
   */
  async archive(
    projectPath: string,
    isWorkspace: boolean,
    options: ArchiveOptions
  ): Promise<{ success: boolean; archivePath: string }> {
    const {
      scheme,
      configuration = 'Release',
      platform = Platform.iOS,
      archivePath
    } = options;
    
    // Generate archive path if not provided
    const finalArchivePath = archivePath || 
      `./build/${scheme}-${new Date().toISOString().split('T')[0]}.xcarchive`;
    
    const projectFlag = isWorkspace ? '-workspace' : '-project';
    let command = `xcodebuild archive ${projectFlag} "${projectPath}"`;
    command += ` -scheme "${scheme}"`;
    command += ` -configuration "${configuration}"`;
    command += ` -archivePath "${finalArchivePath}"`;
    
    // Add platform-specific destination
    const platformInfo = PlatformInfo.fromPlatform(platform);
    const destination = platformInfo.generateGenericDestination();
    command += ` -destination "${destination}"`;
    
    logger.debug({ command }, 'Archive command');
    
    try {
      const { stdout } = await execAsync(command, { 
        maxBuffer: 50 * 1024 * 1024 
      });
      
      logger.info({ 
        projectPath, 
        scheme, 
        archivePath: finalArchivePath 
      }, 'Archive succeeded');
      
      return {
        success: true,
        archivePath: finalArchivePath
      };
    } catch (error: any) {
      logger.error({ error: error.message, projectPath }, 'Archive failed');
      throw new Error(`Archive failed: ${error.message}`);
    }
  }
  
  /**
   * Export an IPA from an archive
   */
  async exportIPA(
    archivePath: string,
    options: ExportOptions = {}
  ): Promise<{ success: boolean; ipaPath: string }> {
    const {
      exportMethod = 'development',
      exportPath = './build'
    } = options;
    
    // Create export options plist
    const exportPlist = `<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
    <key>method</key>
    <string>${exportMethod}</string>
    <key>compileBitcode</key>
    <false/>
</dict>
</plist>`;
    
    // Write plist to temp file
    const tempPlistPath = path.join(exportPath, 'ExportOptions.plist');
    const { writeFile, mkdir } = await import('fs/promises');
    await mkdir(exportPath, { recursive: true });
    await writeFile(tempPlistPath, exportPlist);
    
    const command = `xcodebuild -exportArchive -archivePath "${archivePath}" -exportPath "${exportPath}" -exportOptionsPlist "${tempPlistPath}"`;
    
    logger.debug({ command }, 'Export command');
    
    try {
      const { stdout } = await execAsync(command, { 
        maxBuffer: 10 * 1024 * 1024 
      });
      
      // Find the IPA file in the export directory
      const { readdir } = await import('fs/promises');
      const files = await readdir(exportPath);
      const ipaFile = files.find(f => f.endsWith('.ipa'));
      
      if (!ipaFile) {
        throw new Error('IPA file not found in export directory');
      }
      
      const ipaPath = path.join(exportPath, ipaFile);
      
      // Clean up temp plist
      const { unlink } = await import('fs/promises');
      await unlink(tempPlistPath).catch(() => {});
      
      logger.info({ 
        archivePath, 
        ipaPath,
        exportMethod 
      }, 'IPA export succeeded');
      
      return {
        success: true,
        ipaPath
      };
    } catch (error: any) {
      logger.error({ error: error.message, archivePath }, 'Export failed');
      
      // Clean up temp plist
      const { unlink } = await import('fs/promises');
      await unlink(tempPlistPath).catch(() => {});
      
      throw new Error(`Export failed: ${error.message}`);
    }
  }
}
```

--------------------------------------------------------------------------------
/src/features/app-management/tests/unit/InstallAppController.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, beforeEach, jest } from '@jest/globals';
import { InstallAppController } from '../../controllers/InstallAppController.js';
import { InstallAppUseCase } from '../../use-cases/InstallAppUseCase.js';
import { InstallRequest } from '../../domain/InstallRequest.js';
import { InstallResult } from '../../domain/InstallResult.js';
import { AppPath } from '../../../../shared/domain/AppPath.js';
import { DeviceId } from '../../../../shared/domain/DeviceId.js';

describe('InstallAppController', () => {
  function createSUT() {
    const mockExecute = jest.fn<(request: InstallRequest) => Promise<InstallResult>>();
    const mockUseCase: Partial<InstallAppUseCase> = {
      execute: mockExecute
    };
    const sut = new InstallAppController(mockUseCase as InstallAppUseCase);
    return { sut, mockExecute };
  }

  describe('MCP tool interface', () => {
    it('should define correct tool metadata', () => {
      const { sut } = createSUT();
      
      const definition = sut.getToolDefinition();
      
      expect(definition.name).toBe('install_app');
      expect(definition.description).toBe('Install an app on the simulator');
      expect(definition.inputSchema).toBeDefined();
    });

    it('should define correct input schema', () => {
      const { sut } = createSUT();
      
      const schema = sut.inputSchema;
      
      expect(schema.type).toBe('object');
      expect(schema.properties.appPath).toBeDefined();
      expect(schema.properties.simulatorId).toBeDefined();
      expect(schema.required).toEqual(['appPath']);
    });
  });

  describe('execute', () => {
    it('should install app on specified simulator', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const mockResult = InstallResult.succeeded(
        'com.example.app',
        DeviceId.create('iPhone-15-Simulator'),
        'iPhone 15',
        AppPath.create('/path/to/app.app')
      );
      mockExecute.mockResolvedValue(mockResult);
      
      // Act
      const result = await sut.execute({
        appPath: '/path/to/app.app',
        simulatorId: 'iPhone-15-Simulator'
      });

      // Assert
      expect(result.content[0].text).toBe('✅ Successfully installed com.example.app on iPhone 15 (iPhone-15-Simulator)');
    });

    it('should install app on booted simulator when no ID specified', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const mockResult = InstallResult.succeeded(
        'com.example.app',
        DeviceId.create('Booted-iPhone-15'),
        'iPhone 15',
        AppPath.create('/path/to/app.app')
      );
      mockExecute.mockResolvedValue(mockResult);
      
      // Act
      const result = await sut.execute({
        appPath: '/path/to/app.app'
      });

      // Assert
      expect(result.content[0].text).toBe('✅ Successfully installed com.example.app on iPhone 15 (Booted-iPhone-15)');
    });

    it('should handle validation errors', async () => {
      // Arrange
      const { sut } = createSUT();
      
      // Act
      const result = await sut.execute({
        // Missing required appPath
        simulatorId: 'test-sim'
      });
      
      // Assert
      expect(result.content[0].text).toBe('❌ App path is required');
    });

    it('should handle use case errors', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockRejectedValue(new Error('Simulator not found'));
      
      // Act
      const result = await sut.execute({
        appPath: '/path/to/app.app',
        simulatorId: 'non-existent'
      });
      
      // Assert
      expect(result.content[0].text).toBe('❌ Simulator not found');
    });

    it('should validate app path format', async () => {
      // Arrange
      const { sut } = createSUT();

      // Act
      const result = await sut.execute({
        appPath: '../../../etc/passwd' // Path traversal attempt
      });

      // Assert
      expect(result.content[0].text).toBe('❌ App path cannot contain directory traversal');
    });

    it('should handle app not found errors', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      mockExecute.mockRejectedValue(new Error('App bundle not found at path'));
      
      // Act
      const result = await sut.execute({
        appPath: '/non/existent/app.app'
      });
      
      // Assert
      expect(result.content[0].text).toBe('❌ App bundle not found at path');
    });
  });

});
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/unit/BootSimulatorController.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest } from '@jest/globals';
import { BootSimulatorController } from '../../controllers/BootSimulatorController.js';
import { BootSimulatorUseCase } from '../../use-cases/BootSimulatorUseCase.js';
import { BootRequest } from '../../domain/BootRequest.js';
import { BootResult, BootOutcome, BootCommandFailedError } from '../../domain/BootResult.js';

describe('BootSimulatorController', () => {
  function createSUT() {
    const mockExecute = jest.fn<(request: BootRequest) => Promise<BootResult>>();
    const mockUseCase: Partial<BootSimulatorUseCase> = {
      execute: mockExecute
    };
    const sut = new BootSimulatorController(mockUseCase as BootSimulatorUseCase);
    return { sut, mockExecute };
  }

  describe('MCP tool interface', () => {
    it('should define correct tool metadata', () => {
      // Arrange
      const { sut } = createSUT();
      
      // Act
      const definition = sut.getToolDefinition();
      
      // Assert
      expect(definition.name).toBe('boot_simulator');
      expect(definition.description).toBe('Boot a simulator');
      expect(definition.inputSchema).toBeDefined();
    });

    it('should define correct input schema', () => {
      // Arrange
      const { sut } = createSUT();
      
      // Act
      const schema = sut.inputSchema;
      
      // Assert
      expect(schema.type).toBe('object');
      expect(schema.properties.deviceId).toBeDefined();
      expect(schema.properties.deviceId.type).toBe('string');
      expect(schema.required).toEqual(['deviceId']);
    });
  });

  describe('execute', () => {
    it('should boot simulator successfully', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const mockResult = BootResult.booted('ABC123', 'iPhone 15', {
        platform: 'iOS',
        runtime: 'iOS-17.0'
      });
      mockExecute.mockResolvedValue(mockResult);
      
      // Act
      const result = await sut.execute({
        deviceId: 'iPhone-15'
      });

      // Assert
      expect(result.content[0].text).toBe('✅ Successfully booted simulator: iPhone 15 (ABC123)');
    });

    it('should handle already booted simulator', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const mockResult = BootResult.alreadyBooted('ABC123', 'iPhone 15');
      mockExecute.mockResolvedValue(mockResult);
      
      // Act
      const result = await sut.execute({
        deviceId: 'iPhone-15'
      });
      
      // Assert
      expect(result.content[0].text).toBe('✅ Simulator already booted: iPhone 15 (ABC123)');
    });

    it('should handle boot failure', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const mockResult = BootResult.failed(
        'ABC123', 
        'iPhone 15', 
        new BootCommandFailedError('Device is locked')
      );
      mockExecute.mockResolvedValue(mockResult);
      
      // Act
      const result = await sut.execute({
        deviceId: 'iPhone-15'
      });
      
      // Assert - Error with ❌ emoji prefix and simulator context
      expect(result.content[0].text).toBe('❌ iPhone 15 (ABC123) - Device is locked');
    });

    it('should validate required deviceId', async () => {
      // Arrange
      const { sut } = createSUT();
      
      // Act
      const result = await sut.execute({} as any);
      
      // Assert
      expect(result.content[0].text).toBe('❌ Device ID is required');
    });

    it('should validate empty deviceId', async () => {
      // Arrange
      const { sut } = createSUT();
      
      // Act
      const result = await sut.execute({ deviceId: '' });
      
      // Assert
      expect(result.content[0].text).toBe('❌ Device ID cannot be empty');
    });

    it('should validate whitespace-only deviceId', async () => {
      // Arrange
      const { sut } = createSUT();
      
      // Act
      const result = await sut.execute({ deviceId: '   ' });
      
      // Assert
      expect(result.content[0].text).toBe('❌ Device ID cannot be whitespace only');
    });

    it('should pass UUID directly to use case', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const uuid = '838C707D-5703-4AEE-AF43-4798E0BA1B05';
      const mockResult = BootResult.booted(uuid, 'iPhone 15');
      mockExecute.mockResolvedValue(mockResult);
      
      // Act
      await sut.execute({ deviceId: uuid });
      
      // Assert
      const calledWith = mockExecute.mock.calls[0][0];
      expect(calledWith.deviceId).toBe(uuid);
    });
  });
});
```

--------------------------------------------------------------------------------
/src/shared/tests/utils/TestEnvironmentCleaner.ts:
--------------------------------------------------------------------------------

```typescript
import { execSync } from 'child_process';
import { createModuleLogger } from '../../../logger';

const logger = createModuleLogger('TestEnvironmentCleaner');

/**
 * Utility class for cleaning up test environment (simulators, processes, etc.)
 * Separate from TestProjectManager to maintain single responsibility
 */
export class TestEnvironmentCleaner {
  /**
   * Shutdown all running simulators
   * Faster than erasing simulators, just powers them off
   */
  static shutdownAllSimulators(): void {
    try {
      execSync('xcrun simctl shutdown all', { stdio: 'ignore' });
    } catch (error) {
      logger.debug('No simulators to shutdown or shutdown failed (normal)');
    }
  }

  /**
   * Kill a running macOS app by name
   * @param appName Name of the app process to kill
   */
  static killMacOSApp(appName: string): void {
    try {
      execSync(`pkill -f ${appName}`, { stdio: 'ignore' });
    } catch (error) {
      // Ignore errors - app might not be running
    }
  }

  /**
   * Kill the test project app if it's running on macOS
   */
  static killTestProjectApp(): void {
    this.killMacOSApp('TestProjectXCTest');
  }

  /**
   * Clean DerivedData and SPM build artifacts for test projects
   */
  static cleanDerivedData(): void {
    try {
      // Clean MCP-Xcode DerivedData location (where our tests actually write)
      // This includes Logs/Test/*.xcresult files
      execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/MCP-Xcode/TestProjectSwiftTesting', { 
        shell: '/bin/bash',
        stdio: 'ignore' 
      });
      
      execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/MCP-Xcode/TestProjectXCTest', { 
        shell: '/bin/bash',
        stdio: 'ignore' 
      });
      
      execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/MCP-Xcode/TestSwiftPackage*', { 
        shell: '/bin/bash',
        stdio: 'ignore' 
      });
      
      // Also clean standard Xcode DerivedData locations (in case xcodebuild uses them directly)
      execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/TestProjectSwiftTesting-*', { 
        shell: '/bin/bash',
        stdio: 'ignore' 
      });
      
      execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/TestProjectXCTest-*', { 
        shell: '/bin/bash',
        stdio: 'ignore' 
      });
      
      execSync('rm -rf ~/Library/Developer/Xcode/DerivedData/TestSwiftPackage-*', { 
        shell: '/bin/bash',
        stdio: 'ignore' 
      });
      
      // Clean SPM .build directories in test artifacts
      const testArtifactsDir = process.cwd() + '/test_artifacts';
      execSync(`find ${testArtifactsDir} -name .build -type d -exec rm -rf {} + 2>/dev/null || true`, {
        shell: '/bin/bash',
        stdio: 'ignore'
      });
      
      // Clean .swiftpm directories
      execSync(`find ${testArtifactsDir} -name .swiftpm -type d -exec rm -rf {} + 2>/dev/null || true`, {
        shell: '/bin/bash',
        stdio: 'ignore'
      });
      
    } catch (error) {
      logger.debug('DerivedData cleanup failed or nothing to clean (normal)');
    }
  }

  /**
   * Full cleanup of test environment
   * Shuts down simulators, kills test apps, and cleans DerivedData
   */
  static cleanupTestEnvironment(): void {
    // Shutdown all simulators
    this.shutdownAllSimulators();
    
    // Kill any running test apps
    this.killTestProjectApp();
    
    // Clean DerivedData for test projects
    this.cleanDerivedData();
  }

  /**
   * Reset a specific simulator by erasing its contents
   * @param deviceId The simulator device ID to reset
   */
  static resetSimulator(deviceId: string): void {
    try {
      execSync(`xcrun simctl erase "${deviceId}"`);
    } catch (error: any) {
      // Log the actual error message for debugging
      logger.warn({ deviceId, error: error.message, stderr: error.stderr?.toString() }, 'Failed to erase simulator');
    }
  }

  /**
   * Boot a specific simulator
   * @param deviceId The simulator device ID to boot
   */
  static bootSimulator(deviceId: string): void {
    try {
      execSync(`xcrun simctl boot "${deviceId}"`, { stdio: 'ignore' });
    } catch (error) {
      logger.warn({ deviceId }, 'Simulator already booted or boot failed');
    }
  }

  /**
   * Shutdown a specific simulator
   * @param deviceId The simulator device ID to boot
   */
  static shutdownSimulator(deviceId: string): void {
    try {
      execSync(`xcrun simctl shutdown "${deviceId}"`, { stdio: 'ignore' });
    } catch (error) {
      logger.warn({ deviceId }, 'Simulator already booted or boot failed');
    }
  }
}
```

--------------------------------------------------------------------------------
/src/utils/projects/XcodeProject.ts:
--------------------------------------------------------------------------------

```typescript
import { XcodeBuild, BuildOptions, TestOptions } from './XcodeBuild.js';
import { XcodeArchive, ArchiveOptions, ExportOptions } from './XcodeArchive.js';
import { XcodeInfo } from './XcodeInfo.js';
import { Issue } from '../errors/index.js';
import { createModuleLogger } from '../../logger.js';
import * as pathModule from 'path';
import { Platform } from '../../types.js';

const logger = createModuleLogger('XcodeProject');

/**
 * Represents an Xcode project (.xcodeproj) or workspace (.xcworkspace)
 */
export class XcodeProject {
  public readonly name: string;
  private build: XcodeBuild;
  private archive: XcodeArchive;
  private info: XcodeInfo;
  
  constructor(
    public readonly path: string,
    public readonly type: 'project' | 'workspace',
    components?: {
      build?: XcodeBuild;
      archive?: XcodeArchive;
      info?: XcodeInfo;
    }
  ) {
    // Extract name from path
    const ext = type === 'workspace' ? '.xcworkspace' : '.xcodeproj';
    this.name = pathModule.basename(this.path, ext);
    
    // Initialize components
    this.build = components?.build || new XcodeBuild();
    this.archive = components?.archive || new XcodeArchive();
    this.info = components?.info || new XcodeInfo();
    
    logger.debug({ path: this.path, type, name: this.name }, 'XcodeProject created');
  }
  
  /**
   * Build the project
   */
  async buildProject(options: BuildOptions = {}): Promise<{
    success: boolean;
    output: string;
    appPath?: string;
    logPath?: string;
    errors?: Issue[];
  }> {
    logger.info({ path: this.path, options }, 'Building Xcode project');
    
    const isWorkspace = this.type === 'workspace';
    return await this.build.build(this.path, isWorkspace, options);
  }
  
  /**
   * Run tests for the project
   */
  async test(options: TestOptions = {}): Promise<{
    success: boolean;
    output: string;
    passed: number;
    failed: number;
    failingTests?: Array<{ identifier: string; reason: string }>;
    compileErrors?: Issue[];
    compileWarnings?: Issue[];
    buildErrors?: Issue[];
    logPath: string;
  }> {
    logger.info({ path: this.path, options }, 'Testing Xcode project');
    
    const isWorkspace = this.type === 'workspace';
    return await this.build.test(this.path, isWorkspace, options);
  }
  
  /**
   * Archive the project for distribution
   */
  async archiveProject(options: ArchiveOptions): Promise<{
    success: boolean;
    archivePath: string;
  }> {
    logger.info({ path: this.path, options }, 'Archiving Xcode project');
    
    const isWorkspace = this.type === 'workspace';
    return await this.archive.archive(this.path, isWorkspace, options);
  }
  
  /**
   * Export an IPA from an archive
   */
  async exportIPA(
    archivePath: string,
    options: ExportOptions = {}
  ): Promise<{
    success: boolean;
    ipaPath: string;
  }> {
    logger.info({ archivePath, options }, 'Exporting IPA');
    
    return await this.archive.exportIPA(archivePath, options);
  }
  
  /**
   * Clean build artifacts
   */
  async clean(options: {
    scheme?: string;
    configuration?: string;
  } = {}): Promise<void> {
    logger.info({ path: this.path, options }, 'Cleaning Xcode project');
    
    const isWorkspace = this.type === 'workspace';
    await this.build.clean(this.path, isWorkspace, options);
  }
  
  /**
   * Get list of schemes
   */
  async getSchemes(): Promise<string[]> {
    const isWorkspace = this.type === 'workspace';
    return await this.info.getSchemes(this.path, isWorkspace);
  }
  
  /**
   * Get list of targets
   */
  async getTargets(): Promise<string[]> {
    const isWorkspace = this.type === 'workspace';
    return await this.info.getTargets(this.path, isWorkspace);
  }
  
  /**
   * Get build settings for a scheme
   */
  async getBuildSettings(
    scheme: string,
    configuration?: string,
    platform?: Platform
  ): Promise<any> {
    const isWorkspace = this.type === 'workspace';
    return await this.info.getBuildSettings(
      this.path,
      isWorkspace,
      scheme,
      configuration,
      platform
    );
  }
  
  /**
   * Get comprehensive project information
   */
  async getProjectInfo(): Promise<{
    name: string;
    schemes: string[];
    targets: string[];
    configurations: string[];
  }> {
    const isWorkspace = this.type === 'workspace';
    return await this.info.getProjectInfo(this.path, isWorkspace);
  }
  
  /**
   * Check if this is a workspace
   */
  isWorkspace(): boolean {
    return this.type === 'workspace';
  }
  
  /**
   * Get the project directory
   */
  getDirectory(): string {
    return pathModule.dirname(this.path);
  }
}
```

--------------------------------------------------------------------------------
/src/utils/projects/SwiftPackage.ts:
--------------------------------------------------------------------------------

```typescript
import { SwiftBuild, SwiftBuildOptions, SwiftRunOptions, SwiftTestOptions } from './SwiftBuild.js';
import { SwiftPackageInfo, Dependency, Product } from './SwiftPackageInfo.js';
import { Issue } from '../errors/index.js';
import { createModuleLogger } from '../../logger.js';
import * as pathModule from 'path';
import { existsSync } from 'fs';

const logger = createModuleLogger('SwiftPackage');

/**
 * Represents a Swift package (Package.swift)
 */
export class SwiftPackage {
  public readonly name: string;
  private build: SwiftBuild;
  private info: SwiftPackageInfo;
  
  constructor(
    public readonly path: string,
    components?: {
      build?: SwiftBuild;
      info?: SwiftPackageInfo;
    }
  ) {
    // Validate that Package.swift exists
    const packageSwiftPath = pathModule.join(this.path, 'Package.swift');
    if (!existsSync(packageSwiftPath)) {
      throw new Error(`No Package.swift found at: ${this.path}`);
    }
    
    // Extract name from directory
    this.name = pathModule.basename(this.path);
    
    // Initialize components
    this.build = components?.build || new SwiftBuild();
    this.info = components?.info || new SwiftPackageInfo();
    
    logger.debug({ path: this.path, name: this.name }, 'SwiftPackage created');
  }
  
  /**
   * Build the package
   */
  async buildPackage(options: SwiftBuildOptions = {}): Promise<{
    success: boolean;
    output: string;
    logPath?: string;
    compileErrors?: Issue[];
    buildErrors?: Issue[];
  }> {
    logger.info({ path: this.path, options }, 'Building Swift package');
    
    return await this.build.build(this.path, options);
  }
  
  /**
   * Run an executable from the package
   */
  async run(options: SwiftRunOptions = {}): Promise<{
    success: boolean;
    output: string;
    logPath?: string;
    compileErrors?: Issue[];
    buildErrors?: Issue[];
  }> {
    logger.info({ path: this.path, options }, 'Running Swift package');
    
    return await this.build.run(this.path, options);
  }
  
  /**
   * Test the package
   */
  async test(options: SwiftTestOptions = {}): Promise<{
    success: boolean;
    output: string;
    passed: number;
    failed: number;
    failingTests?: Array<{ identifier: string; reason: string }>;
    compileErrors?: Issue[];
    buildErrors?: Issue[];
    logPath: string;
  }> {
    logger.info({ path: this.path, options }, 'Testing Swift package');
    
    return await this.build.test(this.path, options);
  }
  
  /**
   * Clean build artifacts
   */
  async clean(): Promise<void> {
    logger.info({ path: this.path }, 'Cleaning Swift package');
    
    await this.build.clean(this.path);
  }
  
  /**
   * Get list of products (executables and libraries)
   */
  async getProducts(): Promise<Product[]> {
    return await this.info.getProducts(this.path);
  }
  
  /**
   * Get list of targets
   */
  async getTargets(): Promise<string[]> {
    return await this.info.getTargets(this.path);
  }
  
  /**
   * Get list of dependencies
   */
  async getDependencies(): Promise<Dependency[]> {
    return await this.info.getDependencies(this.path);
  }
  
  /**
   * Add a dependency
   */
  async addDependency(
    url: string,
    options: {
      version?: string;
      branch?: string;
      exact?: boolean;
      from?: string;
      upToNextMajor?: string;
    } = {}
  ): Promise<void> {
    logger.info({ path: this.path, url, options }, 'Adding dependency');
    
    await this.info.addDependency(this.path, url, options);
  }
  
  /**
   * Remove a dependency
   */
  async removeDependency(name: string): Promise<void> {
    logger.info({ path: this.path, name }, 'Removing dependency');
    
    await this.info.removeDependency(this.path, name);
  }
  
  /**
   * Update all dependencies
   */
  async updateDependencies(): Promise<void> {
    logger.info({ path: this.path }, 'Updating dependencies');
    
    await this.info.updateDependencies(this.path);
  }
  
  /**
   * Resolve dependencies
   */
  async resolveDependencies(): Promise<void> {
    logger.info({ path: this.path }, 'Resolving dependencies');
    
    await this.info.resolveDependencies(this.path);
  }
  
  /**
   * Get the package directory
   */
  getDirectory(): string {
    return this.path;
  }
  
  /**
   * Check if this is an executable package
   */
  async isExecutable(): Promise<boolean> {
    const products = await this.getProducts();
    return products.some(p => p.type === 'executable');
  }
  
  /**
   * Get executable products
   */
  async getExecutables(): Promise<string[]> {
    const products = await this.getProducts();
    return products
      .filter(p => p.type === 'executable')
      .map(p => p.name);
  }
}
```

--------------------------------------------------------------------------------
/src/utils/LogManager.ts:
--------------------------------------------------------------------------------

```typescript
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';

/**
 * Manages persistent logs for MCP server debugging
 * Stores logs in ~/.mcp-xcode-server/logs/ with daily rotation
 */
export class LogManager {
  private static readonly LOG_DIR = path.join(os.homedir(), '.mcp-xcode-server', 'logs');
  private static readonly MAX_AGE_DAYS = 7;
  
  /**
   * Initialize log directory structure
   */
  private init(): void {
    if (!fs.existsSync(LogManager.LOG_DIR)) {
      fs.mkdirSync(LogManager.LOG_DIR, { recursive: true });
    }
    
    // Clean up old logs on startup
    this.cleanupOldLogs();
  }
  
  /**
   * Get the log directory for today
   */
  private getTodayLogDir(): string {
    const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
    const dir = path.join(LogManager.LOG_DIR, today);
    
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    
    return dir;
  }
  
  /**
   * Generate a log filename with timestamp
   */
  private getLogFilename(operation: string, projectName?: string): string {
    const timestamp = new Date().toISOString()
      .replace(/:/g, '-')
      .replace(/\./g, '-')
      .split('T')[1]
      .slice(0, 8); // HH-MM-SS
    
    const name = projectName ? `${operation}-${projectName}` : operation;
    return `${timestamp}-${name}.log`;
  }
  
  /**
   * Save log content to a file
   * Returns the full path to the log file
   */
  saveLog(
    operation: 'build' | 'test' | 'run' | 'archive' | 'clean',
    content: string,
    projectName?: string,
    metadata?: Record<string, any>
  ): string {
    const dir = this.getTodayLogDir();
    const filename = this.getLogFilename(operation, projectName);
    const filepath = path.join(dir, filename);
    
    // Add metadata header if provided
    let fullContent = '';
    if (metadata) {
      fullContent += '=== Log Metadata ===\n';
      fullContent += JSON.stringify(metadata, null, 2) + '\n';
      fullContent += '=== End Metadata ===\n\n';
    }
    fullContent += content;
    
    fs.writeFileSync(filepath, fullContent, 'utf8');
    
    // Also create/update a symlink to latest log
    const latestLink = path.join(LogManager.LOG_DIR, `latest-${operation}.log`);
    if (fs.existsSync(latestLink)) {
      fs.unlinkSync(latestLink);
    }
    
    // Create relative symlink for portability
    const relativePath = `./${new Date().toISOString().split('T')[0]}/${filename}`;
    try {
      // Use execSync to create symlink as fs.symlinkSync has issues on some systems
      const { execSync } = require('child_process');
      execSync(`ln -sf "${relativePath}" "${latestLink}"`, { cwd: LogManager.LOG_DIR });
    } catch {
      // Symlink creation failed, not critical
    }
    
    return filepath;
  }
  
  /**
   * Save debug data (like parsed xcresult) for analysis
   */
  saveDebugData(
    operation: string,
    data: any,
    projectName?: string
  ): string {
    const dir = this.getTodayLogDir();
    const timestamp = new Date().toISOString()
      .replace(/:/g, '-')
      .replace(/\./g, '-')
      .split('T')[1]
      .slice(0, 8);
    
    const name = projectName ? `${operation}-${projectName}` : operation;
    const filename = `${timestamp}-${name}-debug.json`;
    const filepath = path.join(dir, filename);
    
    fs.writeFileSync(filepath, JSON.stringify(data, null, 2), 'utf8');
    
    return filepath;
  }
  
  /**
   * Clean up logs older than MAX_AGE_DAYS
   */
  cleanupOldLogs(): void {
    if (!fs.existsSync(LogManager.LOG_DIR)) {
      return;
    }
    
    const now = Date.now();
    const maxAge = LogManager.MAX_AGE_DAYS * 24 * 60 * 60 * 1000;
    
    try {
      const entries = fs.readdirSync(LogManager.LOG_DIR);
      
      for (const entry of entries) {
        const fullPath = path.join(LogManager.LOG_DIR, entry);
        
        // Skip symlinks
        const stat = fs.statSync(fullPath);
        if (stat.isSymbolicLink()) {
          continue;
        }
        
        // Check if it's a date directory (YYYY-MM-DD format)
        if (stat.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(entry)) {
          const dirDate = new Date(entry).getTime();
          
          if (now - dirDate > maxAge) {
            fs.rmSync(fullPath, { recursive: true, force: true });
          }
        }
      }
    } catch (error) {
      // Cleanup failed, not critical
    }
  }
  
  /**
   * Get the user-friendly log path for display
   */
  getDisplayPath(fullPath: string): string {
    // Replace home directory with ~
    const home = os.homedir();
    return fullPath.replace(home, '~');
  }
  
  /**
   * Get the log directory path
   */
  getLogDirectory(): string {
    return LogManager.LOG_DIR;
  }
}
```

--------------------------------------------------------------------------------
/src/features/app-management/tests/unit/InstallResult.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect } from '@jest/globals';
import {
  InstallResult,
  InstallOutcome,
  InstallCommandFailedError,
  SimulatorNotFoundError
} from '../../domain/InstallResult.js';
import { DeviceId } from '../../../../shared/domain/DeviceId.js';
import { AppPath } from '../../../../shared/domain/AppPath.js';

describe('InstallResult', () => {
  describe('succeeded', () => {
    it('should create successful install result', () => {
      // Arrange & Act
      const simulatorId = DeviceId.create('iPhone-15-Simulator');
      const appPath = AppPath.create('/path/to/app.app');
      const result = InstallResult.succeeded(
        'com.example.app',
        simulatorId,
        'iPhone 15',
        appPath
      );
      
      // Assert
      expect(result.outcome).toBe(InstallOutcome.Succeeded);
      expect(result.diagnostics.bundleId).toBe('com.example.app');
      expect(result.diagnostics.simulatorId?.toString()).toBe('iPhone-15-Simulator');
      expect(result.diagnostics.simulatorName).toBe('iPhone 15');
      expect(result.diagnostics.appPath.toString()).toBe('/path/to/app.app');
      expect(result.diagnostics.error).toBeUndefined();
    });

    it('should include install timestamp', () => {
      // Arrange & Act
      const before = Date.now();
      const simulatorId = DeviceId.create('test-sim');
      const appPath = AppPath.create('/path/to/app.app');
      const result = InstallResult.succeeded(
        'com.example.app',
        simulatorId,
        'Test Simulator',
        appPath
      );
      const after = Date.now();
      
      // Assert
      expect(result.diagnostics.installedAt.getTime()).toBeGreaterThanOrEqual(before);
      expect(result.diagnostics.installedAt.getTime()).toBeLessThanOrEqual(after);
    });
  });

  describe('failed', () => {
    it('should create failed install result with SimulatorNotFoundError', () => {
      // Arrange
      const simulatorId = DeviceId.create('non-existent-sim');
      const error = new SimulatorNotFoundError(simulatorId);
      
      // Act
      const appPath = AppPath.create('/path/to/app.app');
      const result = InstallResult.failed(
        error,
        appPath,
        simulatorId,
        'Unknown Simulator'
      );
      
      // Assert
      expect(result.outcome).toBe(InstallOutcome.Failed);
      expect(result.diagnostics.error).toBe(error);
      expect(result.diagnostics.appPath.toString()).toBe('/path/to/app.app');
      expect(result.diagnostics.simulatorId?.toString()).toBe('non-existent-sim');
      expect(result.diagnostics.bundleId).toBeUndefined();
    });

    it('should handle failure without simulator ID', () => {
      // Arrange
      const simulatorId = DeviceId.create('booted');
      const error = new SimulatorNotFoundError(simulatorId);
      
      // Act
      const appPath = AppPath.create('/path/to/app.app');
      const result = InstallResult.failed(
        error,
        appPath
      );
      
      // Assert
      expect(result.outcome).toBe(InstallOutcome.Failed);
      expect(result.diagnostics.error).toBe(error);
      expect(result.diagnostics.appPath.toString()).toBe('/path/to/app.app');
      expect(result.diagnostics.simulatorId).toBeUndefined();
    });

    it('should create failed install result with InstallCommandFailedError', () => {
      // Arrange
      const error = new InstallCommandFailedError('App bundle not found');
      
      // Act
      const appPath = AppPath.create('/path/to/app.app');
      const simulatorId = DeviceId.create('test-sim');
      const result = InstallResult.failed(
        error,
        appPath,
        simulatorId,
        'Test Simulator'
      );
      
      // Assert
      expect(result.outcome).toBe(InstallOutcome.Failed);
      expect(result.diagnostics.error).toBe(error);
      expect((result.diagnostics.error as InstallCommandFailedError).stderr).toBe('App bundle not found');
    });
  });

  describe('outcome checking', () => {
    it('should identify successful installation', () => {
      // Arrange & Act
      const simulatorId = DeviceId.create('sim-id');
      const appPath = AppPath.create('/app.app');
      const result = InstallResult.succeeded(
        'com.example.app',
        simulatorId,
        'Simulator',
        appPath
      );
      
      // Assert
      expect(result.outcome).toBe(InstallOutcome.Succeeded);
    });

    it('should identify failed installation', () => {
      // Arrange
      const error = new InstallCommandFailedError('Installation failed');
      
      // Act
      const appPath = AppPath.create('/app.app');
      const result = InstallResult.failed(
        error,
        appPath
      );
      
      // Assert
      expect(result.outcome).toBe(InstallOutcome.Failed);
    });
  });
});
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/e2e/BootSimulatorController.e2e.test.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * E2E Test for BootSimulatorController
 * 
 * Tests the controller with REAL simulators and REAL system commands
 * Following testing philosophy: E2E tests for critical paths only (10%)
 * 
 * NO MOCKS - Uses real xcrun simctl commands with actual simulators
 */

import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
import { MCPController } from '../../../../presentation/interfaces/MCPController.js';
import { BootSimulatorControllerFactory } from '../../factories/BootSimulatorControllerFactory.js';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

describe('BootSimulatorController E2E', () => {
  let controller: MCPController;
  let testDeviceId: string;
  let testSimulatorName: string;
  
  beforeAll(async () => {
    // Create controller with REAL components
    controller = BootSimulatorControllerFactory.create();
    
    // Find or create a test simulator
    const listResult = await execAsync('xcrun simctl list devices --json');
    const devices = JSON.parse(listResult.stdout);
    
    // Look for an existing test simulator
    for (const runtime of Object.values(devices.devices) as any[]) {
      const testSim = runtime.find((d: any) => d.name.includes('TestSimulator-Boot'));
      if (testSim) {
        testDeviceId = testSim.udid;
        testSimulatorName = testSim.name;
        break;
      }
    }
    
    // Create one if not found
    if (!testDeviceId) {
      // Get available runtime
      const runtimesResult = await execAsync('xcrun simctl list runtimes --json');
      const runtimes = JSON.parse(runtimesResult.stdout);
      const iosRuntime = runtimes.runtimes.find((r: any) => r.platform === 'iOS');
      
      if (!iosRuntime) {
        throw new Error('No iOS runtime available. Please install Xcode with iOS simulator support.');
      }
      
      const createResult = await execAsync(
        `xcrun simctl create "TestSimulator-Boot" "com.apple.CoreSimulator.SimDeviceType.iPhone-15" "${iosRuntime.identifier}"`
      );
      testDeviceId = createResult.stdout.trim();
      testSimulatorName = 'TestSimulator-Boot';
    }
  });
  
  beforeEach(async () => {
    // Ensure simulator is shutdown before each test
    try {
      await execAsync(`xcrun simctl shutdown "${testDeviceId}"`);
    } catch {
      // Ignore if already shutdown
    }
    // Wait for shutdown to complete
    await new Promise(resolve => setTimeout(resolve, 1000));
  });
  
  afterAll(async () => {
    // Shutdown the test simulator
    try {
      await execAsync(`xcrun simctl shutdown "${testDeviceId}"`);
    } catch {
      // Ignore if already shutdown
    }
  });

  describe('boot real simulators', () => {
    it('should boot a shutdown simulator', async () => {
      // Act
      const result = await controller.execute({
        deviceId: testSimulatorName
      });
      
      // Assert
      expect(result.content[0].text).toBe(`✅ Successfully booted simulator: ${testSimulatorName} (${testDeviceId})`);
      
      // Verify simulator is actually booted
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);
      let found = false;
      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === testDeviceId);
        if (device) {
          expect(device.state).toBe('Booted');
          found = true;
          break;
        }
      }
      expect(found).toBe(true);
    });
    
    it('should handle already booted simulator', async () => {
      // Arrange - boot the simulator first
      await execAsync(`xcrun simctl boot "${testDeviceId}"`);
      await new Promise(resolve => setTimeout(resolve, 2000)); // Wait for boot
      
      // Act
      const result = await controller.execute({
        deviceId: testDeviceId
      });
      
      // Assert
      expect(result.content[0].text).toBe(`✅ Simulator already booted: ${testSimulatorName} (${testDeviceId})`);
    });
    
    it('should boot simulator by UUID', async () => {
      // Act - use UUID directly
      const result = await controller.execute({
        deviceId: testDeviceId
      });
      
      // Assert
      expect(result.content[0].text).toBe(`✅ Successfully booted simulator: ${testSimulatorName} (${testDeviceId})`);
    });
  });

  describe('error handling with real simulators', () => {
    it('should fail when simulator does not exist', async () => {
      // Act
      const result = await controller.execute({
        deviceId: 'NonExistentSimulator-12345'
      });
      
      // Assert
      expect(result.content[0].text).toBe('❌ Simulator not found: NonExistentSimulator-12345');
    });
  });
});
```

--------------------------------------------------------------------------------
/src/presentation/tests/unit/DependencyCheckingDecorator.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest } from '@jest/globals';
import { DependencyCheckingDecorator } from '../../decorators/DependencyCheckingDecorator.js';
import { MCPController } from '../../interfaces/MCPController.js';
import { MCPResponse } from '../../interfaces/MCPResponse.js';
import { IDependencyChecker, MissingDependency } from '../../interfaces/IDependencyChecker.js';

describe('DependencyCheckingDecorator', () => {
  function createSUT(missingDeps: MissingDependency[] = []) {
    // Create mock controller
    const mockExecute = jest.fn<(args: unknown) => Promise<MCPResponse>>();
    const mockController: MCPController = {
      name: 'test_tool',
      description: 'Test tool',
      inputSchema: {},
      execute: mockExecute,
      getToolDefinition: () => ({
        name: 'test_tool',
        description: 'Test tool',
        inputSchema: {}
      })
    };

    // Create mock dependency checker
    const mockCheck = jest.fn<IDependencyChecker['check']>();
    mockCheck.mockResolvedValue(missingDeps);
    const mockChecker: IDependencyChecker = {
      check: mockCheck
    };

    // Create decorator
    const sut = new DependencyCheckingDecorator(
      mockController,
      ['xcodebuild', 'xcbeautify'],
      mockChecker
    );

    return { sut, mockExecute, mockCheck };
  }

  describe('execute', () => {
    it('should execute controller when all dependencies are available', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT([]); // No missing dependencies
      const args = { someArg: 'value' };
      const expectedResponse = {
        content: [{ type: 'text', text: 'Success' }]
      };
      mockExecute.mockResolvedValue(expectedResponse);

      // Act
      const result = await sut.execute(args);

      // Assert - behavior: delegates to controller
      expect(result).toBe(expectedResponse);
      expect(mockExecute).toHaveBeenCalledWith(args);
    });

    it('should return error when dependencies are missing', async () => {
      // Arrange
      const missingDeps: MissingDependency[] = [
        { name: 'xcbeautify', installCommand: 'brew install xcbeautify' }
      ];
      const { sut, mockExecute } = createSUT(missingDeps);

      // Act
      const result = await sut.execute({});

      // Assert - behavior: returns error, doesn't execute controller
      expect(result.content[0].text).toContain('Missing required dependencies');
      expect(result.content[0].text).toContain('xcbeautify');
      expect(result.content[0].text).toContain('brew install xcbeautify');
      expect(mockExecute).not.toHaveBeenCalled();
    });

    it('should format multiple missing dependencies clearly', async () => {
      // Arrange
      const missingDeps: MissingDependency[] = [
        { name: 'xcodebuild', installCommand: 'Install Xcode from the App Store' },
        { name: 'xcbeautify', installCommand: 'brew install xcbeautify' }
      ];
      const { sut, mockExecute } = createSUT(missingDeps);

      // Act
      const result = await sut.execute({});

      // Assert - behavior: shows all missing dependencies
      expect(result.content[0].text).toContain('xcodebuild');
      expect(result.content[0].text).toContain('Install Xcode from the App Store');
      expect(result.content[0].text).toContain('xcbeautify');
      expect(result.content[0].text).toContain('brew install xcbeautify');
      expect(mockExecute).not.toHaveBeenCalled();
    });

    it('should handle dependencies without install commands', async () => {
      // Arrange
      const missingDeps: MissingDependency[] = [
        { name: 'customtool' } // No install command
      ];
      const { sut, mockExecute } = createSUT(missingDeps);

      // Act
      const result = await sut.execute({});

      // Assert - behavior: shows tool name without install command
      expect(result.content[0].text).toContain('customtool');
      expect(result.content[0].text).not.toContain('undefined');
      expect(mockExecute).not.toHaveBeenCalled();
    });
  });

  describe('getToolDefinition', () => {
    it('should delegate to decoratee', () => {
      // Arrange
      const { sut } = createSUT();

      // Act
      const definition = sut.getToolDefinition();

      // Assert - behavior: returns controller's definition
      expect(definition).toEqual({
        name: 'test_tool',
        description: 'Test tool',
        inputSchema: {}
      });
    });
  });

  describe('properties', () => {
    it('should delegate properties to decoratee', () => {
      // Arrange
      const { sut } = createSUT();

      // Act & Assert - behavior: properties match controller
      expect(sut.name).toBe('test_tool');
      expect(sut.description).toBe('Test tool');
      expect(sut.inputSchema).toEqual({});
    });
  });
});
```

--------------------------------------------------------------------------------
/src/utils/LogManagerInstance.ts:
--------------------------------------------------------------------------------

```typescript
import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import { ILogManager } from '../application/ports/LoggingPorts.js';

/**
 * Instance-based log manager for dependency injection
 * Manages persistent logs for MCP server debugging
 */
export class LogManagerInstance implements ILogManager {
  private readonly LOG_DIR: string;
  private readonly MAX_AGE_DAYS = 7;
  
  constructor(logDir?: string) {
    this.LOG_DIR = logDir || path.join(os.homedir(), '.mcp-xcode-server', 'logs');
    this.init();
  }
  
  /**
   * Initialize log directory structure
   */
  private init(): void {
    if (!fs.existsSync(this.LOG_DIR)) {
      fs.mkdirSync(this.LOG_DIR, { recursive: true });
    }
    
    // Clean up old logs on startup
    this.cleanupOldLogs();
  }
  
  /**
   * Get the log directory for today
   */
  private getTodayLogDir(): string {
    const today = new Date().toISOString().split('T')[0]; // YYYY-MM-DD
    const dir = path.join(this.LOG_DIR, today);
    
    if (!fs.existsSync(dir)) {
      fs.mkdirSync(dir, { recursive: true });
    }
    
    return dir;
  }
  
  /**
   * Generate a log filename with timestamp
   */
  private getLogFilename(operation: string, projectName?: string): string {
    const timestamp = new Date().toISOString()
      .replace(/:/g, '-')
      .replace(/\./g, '-')
      .split('T')[1]
      .slice(0, 8); // HH-MM-SS
    
    const name = projectName ? `${operation}-${projectName}` : operation;
    return `${timestamp}-${name}.log`;
  }
  
  /**
   * Save log content to a file
   * Returns the full path to the log file
   */
  saveLog(
    operation: 'build' | 'test' | 'run' | 'archive' | 'clean',
    content: string,
    projectName?: string,
    metadata?: Record<string, any>
  ): string {
    const dir = this.getTodayLogDir();
    const filename = this.getLogFilename(operation, projectName);
    const filepath = path.join(dir, filename);
    
    // Add metadata header if provided
    let fullContent = '';
    if (metadata) {
      fullContent += '=== Log Metadata ===\n';
      fullContent += JSON.stringify(metadata, null, 2) + '\n';
      fullContent += '=== End Metadata ===\n\n';
    }
    fullContent += content;
    
    fs.writeFileSync(filepath, fullContent, 'utf8');
    
    // Also create/update a symlink to latest log
    const latestLink = path.join(this.LOG_DIR, `latest-${operation}.log`);
    if (fs.existsSync(latestLink)) {
      fs.unlinkSync(latestLink);
    }
    
    // Create relative symlink for portability
    const relativePath = `./${new Date().toISOString().split('T')[0]}/${filename}`;
    try {
      // Use execSync to create symlink as fs.symlinkSync has issues on some systems
      const { execSync } = require('child_process');
      execSync(`ln -sf "${relativePath}" "${latestLink}"`, { cwd: this.LOG_DIR });
    } catch {
      // Symlink creation failed, not critical
    }
    
    return filepath;
  }
  
  /**
   * Save debug data (like parsed xcresult) for analysis
   */
  saveDebugData(
    operation: string,
    data: any,
    projectName?: string
  ): string {
    const dir = this.getTodayLogDir();
    const timestamp = new Date().toISOString()
      .replace(/:/g, '-')
      .replace(/\./g, '-')
      .split('T')[1]
      .slice(0, 8);
    
    const name = projectName ? `${operation}-${projectName}` : operation;
    const filename = `${timestamp}-${name}-debug.json`;
    const filepath = path.join(dir, filename);
    
    fs.writeFileSync(filepath, JSON.stringify(data, null, 2), 'utf8');
    
    return filepath;
  }
  
  /**
   * Clean up logs older than MAX_AGE_DAYS
   */
  cleanupOldLogs(): void {
    if (!fs.existsSync(this.LOG_DIR)) {
      return;
    }
    
    const now = Date.now();
    const maxAge = this.MAX_AGE_DAYS * 24 * 60 * 60 * 1000;
    
    try {
      const entries = fs.readdirSync(this.LOG_DIR);
      
      for (const entry of entries) {
        const fullPath = path.join(this.LOG_DIR, entry);
        
        // Skip symlinks
        const stat = fs.statSync(fullPath);
        if (stat.isSymbolicLink()) {
          continue;
        }
        
        // Check if it's a date directory (YYYY-MM-DD format)
        if (stat.isDirectory() && /^\d{4}-\d{2}-\d{2}$/.test(entry)) {
          const dirDate = new Date(entry).getTime();
          
          if (now - dirDate > maxAge) {
            fs.rmSync(fullPath, { recursive: true, force: true });
          }
        }
      }
    } catch (error) {
      // Cleanup failed, not critical
    }
  }
  
  /**
   * Get the user-friendly log path for display
   */
  getDisplayPath(fullPath: string): string {
    // Replace home directory with ~
    const home = os.homedir();
    return fullPath.replace(home, '~');
  }
  
  /**
   * Get the log directory path
   */
  getLogDirectory(): string {
    return this.LOG_DIR;
  }
}
```

--------------------------------------------------------------------------------
/src/presentation/presenters/BuildXcodePresenter.ts:
--------------------------------------------------------------------------------

```typescript
import { BuildResult, BuildOutcome, OutputFormatterError } from '../../features/build/domain/BuildResult.js';
import { Platform } from '../../shared/domain/Platform.js';
import { ErrorFormatter } from '../formatters/ErrorFormatter.js';
import { MCPResponse } from '../interfaces/MCPResponse.js';

/**
 * Presenter for build results
 * 
 * Single Responsibility: Format BuildResult for MCP display
 * - Success formatting
 * - Failure formatting with errors/warnings
 * - Log path information
 */

export class BuildXcodePresenter {
  private readonly maxErrorsToShow = 50;
  private readonly maxWarningsToShow = 20;
  
  present(result: BuildResult, metadata: {
    scheme: string;
    platform: Platform;
    configuration: string;
    showWarningDetails?: boolean;
  }): MCPResponse {
    if (result.outcome === BuildOutcome.Succeeded) {
      return this.presentSuccess(result, metadata);
    }
    return this.presentFailure(result, metadata);
  }
  
  private presentSuccess(
    result: BuildResult,
    metadata: { scheme: string; platform: Platform; configuration: string; showWarningDetails?: boolean }
  ): MCPResponse {
    const warnings = BuildResult.getWarnings(result);
    
    let text = `✅ Build succeeded: ${metadata.scheme}

Platform: ${metadata.platform}
Configuration: ${metadata.configuration}`;

    // Show warning count if there are any
    if (warnings.length > 0) {
      text += `\nWarnings: ${warnings.length}`;
      
      // Show warning details if requested
      if (metadata.showWarningDetails) {
        text += '\n\n⚠️  Warnings:';
        const warningsToShow = Math.min(warnings.length, this.maxWarningsToShow);
        warnings.slice(0, warningsToShow).forEach(warning => {
          text += `\n  • ${this.formatIssue(warning)}`;
        });
        if (warnings.length > this.maxWarningsToShow) {
          text += `\n  ... and ${warnings.length - this.maxWarningsToShow} more warnings`;
        }
      }
    }

    text += `\nApp path: ${result.diagnostics.appPath || 'N/A'}${result.diagnostics.logPath ? `

📁 Full logs saved to: ${result.diagnostics.logPath}` : ''}`;
    
    return {
      content: [{ type: 'text', text }]
    };
  }
  
  private presentFailure(
    result: BuildResult,
    metadata: { scheme: string; platform: Platform; configuration: string; showWarningDetails?: boolean }
  ): MCPResponse {
    // Check if this is a dependency/tool error (not an actual build failure)
    if (result.diagnostics.error && result.diagnostics.error instanceof OutputFormatterError) {
      // Tool dependency missing - show only that error
      const text = `❌ ${ErrorFormatter.format(result.diagnostics.error)}`;
      return {
        content: [{ type: 'text', text }]
      };
    }
    
    const errors = BuildResult.getErrors(result);
    const warnings = BuildResult.getWarnings(result);
    
    let text = `❌ Build failed: ${metadata.scheme}\n`;
    text += `Platform: ${metadata.platform}\n`;
    text += `Configuration: ${metadata.configuration}\n`;
    
    // Check for other errors in diagnostics
    if (result.diagnostics.error) {
      text += `\n❌ ${ErrorFormatter.format(result.diagnostics.error)}\n`;
    }
    
    if (errors.length > 0) {
      text += `\n❌ Errors (${errors.length}):\n`;
      // Show up to maxErrorsToShow errors
      const errorsToShow = Math.min(errors.length, this.maxErrorsToShow);
      errors.slice(0, errorsToShow).forEach(error => {
        text += `  • ${this.formatIssue(error)}\n`;
      });
      if (errors.length > this.maxErrorsToShow) {
        text += `  ... and ${errors.length - this.maxErrorsToShow} more errors\n`;
      }
    }
    
    // Always show warning count if there are warnings
    if (warnings.length > 0) {
      if (metadata.showWarningDetails) {
        // Show detailed warnings
        text += `\n⚠️ Warnings (${warnings.length}):\n`;
        const warningsToShow = Math.min(warnings.length, this.maxWarningsToShow);
        warnings.slice(0, warningsToShow).forEach(warning => {
          text += `  • ${this.formatIssue(warning)}\n`;
        });
        if (warnings.length > this.maxWarningsToShow) {
          text += `  ... and ${warnings.length - this.maxWarningsToShow} more warnings\n`;
        }
      } else {
        // Just show count
        text += `\n⚠️ Warnings: ${warnings.length}\n`;
      }
    }
    
    if (result.diagnostics.logPath) {
      text += `\n📁 Full logs saved to: ${result.diagnostics.logPath}\n`;
    }
    
    return {
      content: [{ type: 'text', text }]
    };
  }
  
  private formatIssue(issue: any): string {
    if (issue.file && issue.line) {
      if (issue.column) {
        return `${issue.file}:${issue.line}:${issue.column}: ${issue.message}`;
      }
      return `${issue.file}:${issue.line}: ${issue.message}`;
    }
    return issue.message;
  }
  
  presentError(error: Error): MCPResponse {
    const message = ErrorFormatter.format(error);
    return {
      content: [{ 
        type: 'text', 
        text: `❌ ${message}` 
      }]
    };
  }
}
```

--------------------------------------------------------------------------------
/src/utils/projects/XcodeInfo.ts:
--------------------------------------------------------------------------------

```typescript
import { execAsync } from '../../utils.js';
import { createModuleLogger } from '../../logger.js';
import { Platform } from '../../types.js';
import path from 'path';

const logger = createModuleLogger('XcodeInfo');

/**
 * Queries information about Xcode projects
 */
export class XcodeInfo {
  /**
   * Get list of schemes in a project
   */
  async getSchemes(
    projectPath: string,
    isWorkspace: boolean
  ): Promise<string[]> {
    const projectFlag = isWorkspace ? '-workspace' : '-project';
    const command = `xcodebuild -list -json ${projectFlag} "${projectPath}"`;
    
    logger.debug({ command }, 'List schemes command');
    
    try {
      const { stdout } = await execAsync(command);
      const data = JSON.parse(stdout);
      
      // Get schemes from the appropriate property
      let schemes: string[] = [];
      if (isWorkspace && data.workspace?.schemes) {
        schemes = data.workspace.schemes;
      } else if (!isWorkspace && data.project?.schemes) {
        schemes = data.project.schemes;
      }
      
      logger.debug({ projectPath, schemes }, 'Found schemes');
      return schemes;
    } catch (error: any) {
      logger.error({ error: error.message, projectPath }, 'Failed to get schemes');
      throw new Error(`Failed to get schemes: ${error.message}`);
    }
  }
  
  /**
   * Get list of targets in a project
   */
  async getTargets(
    projectPath: string,
    isWorkspace: boolean
  ): Promise<string[]> {
    const projectFlag = isWorkspace ? '-workspace' : '-project';
    const command = `xcodebuild -list -json ${projectFlag} "${projectPath}"`;
    
    logger.debug({ command }, 'List targets command');
    
    try {
      const { stdout } = await execAsync(command);
      const data = JSON.parse(stdout);
      
      // Get targets from the project (even for workspaces, targets come from projects)
      const targets = data.project?.targets || [];
      
      logger.debug({ projectPath, targets }, 'Found targets');
      return targets;
    } catch (error: any) {
      logger.error({ error: error.message, projectPath }, 'Failed to get targets');
      throw new Error(`Failed to get targets: ${error.message}`);
    }
  }
  
  /**
   * Get build settings for a scheme
   */
  async getBuildSettings(
    projectPath: string,
    isWorkspace: boolean,
    scheme: string,
    configuration?: string,
    platform?: Platform
  ): Promise<any> {
    const projectFlag = isWorkspace ? '-workspace' : '-project';
    let command = `xcodebuild -showBuildSettings ${projectFlag} "${projectPath}"`;
    command += ` -scheme "${scheme}"`;
    
    if (configuration) {
      command += ` -configuration "${configuration}"`;
    }
    
    if (platform) {
      // Add a generic destination for the platform to get appropriate settings
      const { PlatformInfo } = await import('../../features/build/domain/PlatformInfo.js');
      const platformInfo = PlatformInfo.fromPlatform(platform);
      const destination = platformInfo.generateGenericDestination();
      command += ` -destination '${destination}'`;
    }
    
    command += ' -json';
    
    logger.debug({ command }, 'Get build settings command');
    
    try {
      const { stdout } = await execAsync(command, {
        maxBuffer: 10 * 1024 * 1024
      });
      
      const settings = JSON.parse(stdout);
      logger.debug({ projectPath, scheme }, 'Got build settings');
      
      return settings;
    } catch (error: any) {
      logger.error({ error: error.message, projectPath, scheme }, 'Failed to get build settings');
      throw new Error(`Failed to get build settings: ${error.message}`);
    }
  }
  
  /**
   * Get comprehensive project information
   */
  async getProjectInfo(
    projectPath: string,
    isWorkspace: boolean
  ): Promise<{
    name: string;
    schemes: string[];
    targets: string[];
    configurations: string[];
  }> {
    const projectFlag = isWorkspace ? '-workspace' : '-project';
    const command = `xcodebuild -list -json ${projectFlag} "${projectPath}"`;
    
    logger.debug({ command }, 'Get project info command');
    
    try {
      const { stdout } = await execAsync(command);
      const data = JSON.parse(stdout);
      
      // Extract info based on project type
      let info;
      if (isWorkspace) {
        info = {
          name: data.workspace?.name || path.basename(projectPath, '.xcworkspace'),
          schemes: data.workspace?.schemes || [],
          targets: data.project?.targets || [],
          configurations: data.project?.configurations || []
        };
      } else {
        info = {
          name: data.project?.name || path.basename(projectPath, '.xcodeproj'),
          schemes: data.project?.schemes || [],
          targets: data.project?.targets || [],
          configurations: data.project?.configurations || []
        };
      }
      
      logger.debug({ projectPath, info }, 'Got project info');
      return info;
    } catch (error: any) {
      logger.error({ error: error.message, projectPath }, 'Failed to get project info');
      throw new Error(`Failed to get project info: ${error.message}`);
    }
  }
}
```

--------------------------------------------------------------------------------
/src/utils/devices/SimulatorDevice.ts:
--------------------------------------------------------------------------------

```typescript
import { SimulatorBoot } from './SimulatorBoot.js';
import { SimulatorApps } from './SimulatorApps.js';
import { SimulatorUI } from './SimulatorUI.js';
import { SimulatorInfo } from './SimulatorInfo.js';
import { SimulatorReset } from './SimulatorReset.js';
import { createModuleLogger } from '../../logger.js';

const logger = createModuleLogger('SimulatorDevice');

/**
 * Represents a specific simulator device instance.
 * Provides a complete interface for simulator operations while
 * delegating to specialized components internally.
 */
export class SimulatorDevice {
  private boot: SimulatorBoot;
  private apps: SimulatorApps;
  private ui: SimulatorUI;
  private info: SimulatorInfo;
  private reset: SimulatorReset;

  constructor(
    public readonly id: string,
    public readonly name: string,
    public readonly platform: string,
    public readonly runtime: string,
    components?: {
      boot?: SimulatorBoot;
      apps?: SimulatorApps;
      ui?: SimulatorUI;
      info?: SimulatorInfo;
      reset?: SimulatorReset;
    }
  ) {
    this.boot = components?.boot || new SimulatorBoot();
    this.apps = components?.apps || new SimulatorApps();
    this.ui = components?.ui || new SimulatorUI();
    this.info = components?.info || new SimulatorInfo();
    this.reset = components?.reset || new SimulatorReset();
  }

  /**
   * Boot this simulator device
   */
  async bootDevice(): Promise<void> {
    logger.debug({ deviceId: this.id, name: this.name }, 'Booting device');
    await this.boot.boot(this.id);
  }

  /**
   * Shutdown this simulator device
   */
  async shutdown(): Promise<void> {
    logger.debug({ deviceId: this.id, name: this.name }, 'Shutting down device');
    await this.boot.shutdown(this.id);
  }

  /**
   * Install an app on this device
   */
  async install(appPath: string): Promise<void> {
    logger.debug({ deviceId: this.id, appPath }, 'Installing app on device');
    await this.apps.install(appPath, this.id);
  }

  /**
   * Uninstall an app from this device
   */
  async uninstall(bundleId: string): Promise<void> {
    logger.debug({ deviceId: this.id, bundleId }, 'Uninstalling app from device');
    await this.apps.uninstall(bundleId, this.id);
  }

  /**
   * Launch an app on this device
   */
  async launch(bundleId: string): Promise<string> {
    logger.debug({ deviceId: this.id, bundleId }, 'Launching app on device');
    return await this.apps.launch(bundleId, this.id);
  }

  /**
   * Get bundle ID from an app path
   */
  async getBundleId(appPath: string): Promise<string> {
    return await this.apps.getBundleId(appPath);
  }

  /**
   * Take a screenshot of this device
   */
  async screenshot(outputPath: string): Promise<void> {
    logger.debug({ deviceId: this.id, outputPath }, 'Taking screenshot');
    await this.ui.screenshot(outputPath, this.id);
  }

  /**
   * Get screenshot data as base64
   */
  async screenshotData(): Promise<{ base64: string; mimeType: string }> {
    logger.debug({ deviceId: this.id }, 'Getting screenshot data');
    return await this.ui.screenshotData(this.id);
  }

  /**
   * Set appearance mode (light/dark)
   */
  async setAppearance(appearance: 'light' | 'dark'): Promise<void> {
    logger.debug({ deviceId: this.id, appearance }, 'Setting appearance');
    await this.ui.setAppearance(appearance, this.id);
  }

  /**
   * Open the Simulator app UI
   */
  async open(): Promise<void> {
    await this.ui.open();
  }

  /**
   * Get device logs
   */
  async logs(predicate?: string, last?: string): Promise<string> {
    logger.debug({ deviceId: this.id, predicate, last }, 'Getting device logs');
    return await this.info.logs(this.id, predicate, last);
  }

  /**
   * Get current device state
   */
  async getState(): Promise<string> {
    return await this.info.getDeviceState(this.id);
  }

  /**
   * Check if device is available
   */
  async checkAvailability(): Promise<boolean> {
    return await this.info.isAvailable(this.id);
  }

  /**
   * Reset this device to clean state
   */
  async resetDevice(): Promise<void> {
    logger.debug({ deviceId: this.id, name: this.name }, 'Resetting device');
    await this.reset.reset(this.id);
  }

  /**
   * Check if device is currently booted
   * Checks actual current state, not cached value
   */
  async isBooted(): Promise<boolean> {
    const currentState = await this.getState();
    return currentState === 'Booted';
  }

  /**
   * Ensure this device is booted, boot if necessary
   */
  async ensureBooted(): Promise<void> {
    // Check if device is available before trying to boot
    const available = await this.checkAvailability();
    if (!available) {
      throw new Error(
        `Device "${this.name}" (${this.id}) is not available. ` +
        `The runtime "${this.runtime}" may be missing or corrupted. ` +
        `Try downloading the runtime in Xcode or use a different simulator.`
      );
    }
    
    // Use the async isBooted() method to check actual state
    if (!(await this.isBooted())) {
      await this.bootDevice();
    } else {
      logger.debug({ deviceId: this.id, name: this.name }, 'Device already booted');
    }
  }
}
```

--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------

```typescript
#!/usr/bin/env node

/**
 * MCP Xcode Server
 * Provides tools for building, running, and testing Apple platform projects
 */

import { Server } from '@modelcontextprotocol/sdk/server/index.js';
import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
import {
  CallToolRequestSchema,
  ListToolsRequestSchema,
} from '@modelcontextprotocol/sdk/types.js';
import { logger, logToolExecution, logError } from './logger.js';

// Import all tool classes
// import {
//   ListSimulatorsTool,
//   BootSimulatorTool,
//   ShutdownSimulatorTool,
//   ViewSimulatorScreenTool,
//   BuildSwiftPackageTool,
//   RunSwiftPackageTool,
//   RunXcodeTool,
//   TestXcodeTool,
//   TestSwiftPackageTool,
//   CleanBuildTool,
//   ArchiveProjectTool,
//   ExportIPATool,
//   ListSchemesTool,
//   GetBuildSettingsTool,
//   GetProjectInfoTool,
//   ListTargetsTool,
//   InstallAppTool,
//   UninstallAppTool,
//   GetDeviceLogsTool,
//   ManageDependenciesTool
// } from './tools/index.js';

// Import factories for Clean Architecture controllers
import {
  BootSimulatorControllerFactory,
  ShutdownSimulatorControllerFactory,
  ListSimulatorsControllerFactory
} from './features/simulator/index.js';
import { BuildXcodeControllerFactory } from './features/build/index.js';
import { InstallAppControllerFactory } from './features/app-management/index.js';

type Tool = {
  execute(args: any): Promise<any>;
  getToolDefinition(): any;
};

class XcodeServer {
  private server: Server;
  private tools: Map<string, Tool>;

  constructor() {
    this.server = new Server(
      {
        name: 'mcp-xcode-server',
        version: '2.4.0',
      },
      {
        capabilities: {
          tools: {},
        },
      }
    );

    // Initialize all tools
    this.tools = new Map<string, Tool>();
    this.registerTools();
    this.setupHandlers();
  }

  private registerTools() {
    // Create instances of all tools
    const toolInstances = [
      // Simulator management
      ListSimulatorsControllerFactory.create(),
      BootSimulatorControllerFactory.create(),
      ShutdownSimulatorControllerFactory.create(),
      // new ViewSimulatorScreenTool(),
      // Build and test
      // new BuildSwiftPackageTool(),
      // new RunSwiftPackageTool(),
      BuildXcodeControllerFactory.create(),
      InstallAppControllerFactory.create(),
      // new RunXcodeTool(),
      // new TestXcodeTool(),
      // new TestSwiftPackageTool(),
      // new CleanBuildTool(),
      // Archive and export
      // new ArchiveProjectTool(),
      // new ExportIPATool(),
      // Project info and schemes
      // new ListSchemesTool(),
      // new GetBuildSettingsTool(),
      // new GetProjectInfoTool(),
      // new ListTargetsTool(),
      // App management
      // new InstallAppTool(),
      // new UninstallAppTool(),
      // Device logs
      // new GetDeviceLogsTool(),
      // Advanced project management
      // new ManageDependenciesTool()
    ];

    // Register each tool by its name
    for (const tool of toolInstances) {
      const definition = tool.getToolDefinition();
      this.tools.set(definition.name, tool);
    }

    logger.info({ toolCount: this.tools.size }, 'Tools registered');
  }

  private setupHandlers() {
    // Handle listing all available tools
    this.server.setRequestHandler(ListToolsRequestSchema, async () => {
      const tools = Array.from(this.tools.values()).map(tool => tool.getToolDefinition());
      return { tools };
    });

    // Handle tool execution
    this.server.setRequestHandler(CallToolRequestSchema, async (request) => {
      const { name, arguments: args } = request.params;
      const startTime = Date.now();

      logger.debug({ tool: name, args }, 'Tool request received');

      try {
        const tool = this.tools.get(name);
        if (!tool) {
          throw new Error(`Unknown tool: ${name}`);
        }

        const result = await tool.execute(args);
        
        // Log successful execution
        logToolExecution(name, args, Date.now() - startTime);
        return result;
      } catch (error: any) {
        
        logError(error as Error, { tool: name, args });
        return {
          content: [
            {
              type: 'text',
              text: `Error: ${error instanceof Error ? error.message : String(error)}`
            }
          ]
        };
      }
    });
  }

  async run() {
    const transport = new StdioServerTransport();
    await this.server.connect(transport);
    logger.info({ transport: 'stdio' }, 'MCP Xcode server started');
  }
}

const server = new XcodeServer();

// Handle graceful shutdown
process.on('SIGTERM', async () => {
  logger.info('Received SIGTERM, shutting down gracefully');
  // Give logger time to flush
  await new Promise(resolve => setTimeout(resolve, 100));
  process.exit(0);
});

process.on('SIGINT', async () => {
  logger.info('Received SIGINT, shutting down gracefully');
  // Give logger time to flush
  await new Promise(resolve => setTimeout(resolve, 100));
  process.exit(0);
});

server.run().catch((error) => {
  logger.fatal({ error }, 'Failed to start MCP server');
  process.exit(1);
});
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/e2e/ListSimulatorsMCP.e2e.test.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * E2E Test for List Simulators through MCP Protocol
 *
 * Tests critical user journey: Listing simulators through MCP
 * Following testing philosophy: E2E tests for critical paths only (10%)
 *
 * NO MOCKS - Uses real MCP server, real simulators
 */

import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
import { createAndConnectClient, cleanupClientAndTransport } from '../../../../shared/tests/utils/testHelpers.js';

describe('List Simulators MCP E2E', () => {
  let client: Client;
  let transport: StdioClientTransport;

  beforeAll(async () => {
    // Build the server
    const { execSync } = await import('child_process');
    execSync('npm run build', { stdio: 'inherit' });
  });

  beforeEach(async () => {
    ({ client, transport } = await createAndConnectClient());
  });

  afterEach(async () => {
    await cleanupClientAndTransport(client, transport);
  });

  it('should list simulators through MCP', async () => {
    // This tests the critical user journey:
    // User connects via MCP → calls list_simulators → receives result

    const result = await client.request(
      {
        method: 'tools/call',
        params: {
          name: 'list_simulators',
          arguments: {}
        }
      },
      CallToolResultSchema,
      { timeout: 30000 }
    );

    expect(result).toBeDefined();
    expect(result.content).toBeInstanceOf(Array);

    const textContent = result.content.find((c: any) => c.type === 'text') as { type: string; text: string } | undefined;
    expect(textContent).toBeDefined();

    const text = textContent?.text || '';
    if (text.includes('No simulators found')) {
      expect(text).toBe('🔍 No simulators found');
    } else {
      expect(text).toMatch(/Found \d+ simulator/);
    }
  });

  it('should filter simulators by platform through MCP', async () => {
    const result = await client.request(
      {
        method: 'tools/call',
        params: {
          name: 'list_simulators',
          arguments: {
            platform: 'iOS'
          }
        }
      },
      CallToolResultSchema,
      { timeout: 30000 }
    );

    expect(result).toBeDefined();
    expect(result.content).toBeInstanceOf(Array);

    const textContent = result.content.find((c: any) => c.type === 'text') as { type: string; text: string } | undefined;
    const text = textContent?.text || '';

    // Should find iOS simulators
    expect(text).toMatch(/Found \d+ simulator/);

    const lines = text.split('\n');
    const deviceLines = lines.filter((line: string) =>
      line.includes('(') && line.includes(')') && line.includes('-')
    );

    expect(deviceLines.length).toBeGreaterThan(0);
    for (const line of deviceLines) {
      // All devices should show iOS runtime since we filtered by iOS platform
      expect(line).toContain(' - iOS ');
      // Should not contain other platform devices
      expect(line).not.toMatch(/Apple TV|Apple Watch/);
    }
  });

  it('should filter simulators by state through MCP', async () => {
    const result = await client.request(
      {
        method: 'tools/call',
        params: {
          name: 'list_simulators',
          arguments: {
            state: 'Shutdown'
          }
        }
      },
      CallToolResultSchema,
      { timeout: 30000 }
    );

    expect(result).toBeDefined();
    expect(result.content).toBeInstanceOf(Array);

    const textContent = result.content.find((c: any) => c.type === 'text') as { type: string; text: string } | undefined;
    const text = textContent?.text || '';

    // Should find simulators in shutdown state
    expect(text).toMatch(/Found \d+ simulator/);

    const lines = text.split('\n');
    const deviceLines = lines.filter(line =>
      line.includes('(') && line.includes(')') && line.includes('-')
    );

    expect(deviceLines.length).toBeGreaterThan(0);
    for (const line of deviceLines) {
      expect(line).toContain('Shutdown');
    }
  });

  it('should handle combined filters through MCP', async () => {
    const result = await client.request(
      {
        method: 'tools/call',
        params: {
          name: 'list_simulators',
          arguments: {
            platform: 'iOS',
            state: 'Booted'
          }
        }
      },
      CallToolResultSchema,
      { timeout: 30000 }
    );

    expect(result).toBeDefined();
    expect(result.content).toBeInstanceOf(Array);

    const textContent = result.content.find((c: any) => c.type === 'text') as { type: string; text: string } | undefined;
    const text = textContent?.text || '';

    // The combined filter might not find any booted iOS simulators
    // but the test should still assert the behavior
    if (text.includes('No simulators found')) {
      expect(text).toBe('🔍 No simulators found');
    } else {
      expect(text).toMatch(/Found \d+ simulator/);

      const lines = text.split('\n');
      const deviceLines = lines.filter(line =>
        line.includes('(') && line.includes(')') && line.includes('-')
      );

      for (const line of deviceLines) {
        expect(line).toContain(' - iOS ');
        expect(line).toContain('Booted');
      }
    }
  });
});
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/e2e/ShutdownSimulatorMCP.e2e.test.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * E2E Test for Shutdown Simulator through MCP Protocol
 * 
 * Tests critical user journey: Shutting down a simulator through MCP
 * Following testing philosophy: E2E tests for critical paths only (10%)
 * 
 * Focus: MCP protocol interaction, not simulator shutdown logic
 * The controller tests already verify shutdown works with real simulators
 * This test verifies the MCP transport/serialization/protocol works
 * 
 * NO MOCKS - Uses real MCP server, real simulators
 */

import { describe, it, expect, beforeAll, afterAll } from '@jest/globals';
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio.js';
import { CallToolResultSchema } from '@modelcontextprotocol/sdk/types.js';
import { createAndConnectClient, cleanupClientAndTransport } from '../../../../shared/tests/utils/testHelpers.js';
import { TestSimulatorManager } from '../../../../shared/tests/utils/TestSimulatorManager.js';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

describe('Shutdown Simulator MCP E2E', () => {
  let client: Client;
  let transport: StdioClientTransport;
  let testSimManager: TestSimulatorManager;
  
  beforeAll(async () => {
    // Build the server
    const { execSync } = await import('child_process');
    execSync('npm run build', { stdio: 'inherit' });

    // Set up test simulator
    testSimManager = new TestSimulatorManager();
    await testSimManager.getOrCreateSimulator('TestSimulator-ShutdownMCP');

    // Connect to MCP server
    ({ client, transport } = await createAndConnectClient());
  });
  
  afterAll(async () => {
    // Cleanup test simulator
    await testSimManager.cleanup();

    // Cleanup MCP connection
    await cleanupClientAndTransport(client, transport);
  });

  describe('shutdown simulator through MCP', () => {
    it('should shutdown simulator via MCP protocol', async () => {
      // Arrange - Boot the simulator first
      await testSimManager.bootAndWait(30);

      // Act - Call tool through MCP
      const result = await client.callTool({
        name: 'shutdown_simulator',
        arguments: {
          deviceId: testSimManager.getSimulatorName()
        }
      });
      
      // Assert - Verify MCP response
      const parsed = CallToolResultSchema.parse(result);
      expect(parsed.content[0].type).toBe('text');
      expect(parsed.content[0].text).toBe(`✅ Successfully shutdown simulator: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
      
      // Verify simulator is actually shutdown
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);
      let found = false;
      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === testSimManager.getSimulatorId());
        if (device) {
          expect(device.state).toBe('Shutdown');
          found = true;
          break;
        }
      }
      expect(found).toBe(true);
    });
    
    it('should handle already shutdown simulator via MCP', async () => {
      // Arrange - ensure simulator is shutdown
      await testSimManager.shutdownAndWait();
      
      // Act - Call tool through MCP
      const result = await client.callTool({
        name: 'shutdown_simulator',
        arguments: {
          deviceId: testSimManager.getSimulatorId()
        }
      });
      
      // Assert
      const parsed = CallToolResultSchema.parse(result);
      expect(parsed.content[0].text).toBe(`✅ Simulator already shutdown: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
    });
    
    it('should shutdown simulator by UUID via MCP', async () => {
      // Arrange - Boot the simulator first
      await testSimManager.bootAndWait(30);

      // Act - Call tool with UUID
      const result = await client.callTool({
        name: 'shutdown_simulator',
        arguments: {
          deviceId: testSimManager.getSimulatorId()
        }
      });
      
      // Assert
      const parsed = CallToolResultSchema.parse(result);
      expect(parsed.content[0].text).toBe(`✅ Successfully shutdown simulator: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
      
      // Verify simulator is actually shutdown
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);
      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === testSimManager.getSimulatorId());
        if (device) {
          expect(device.state).toBe('Shutdown');
          break;
        }
      }
    });
  });

  describe('error handling through MCP', () => {
    it('should return error for non-existent simulator', async () => {
      // Act
      const result = await client.callTool({
        name: 'shutdown_simulator',
        arguments: {
          deviceId: 'NonExistentSimulator-MCP'
        }
      });
      
      // Assert
      const parsed = CallToolResultSchema.parse(result);
      expect(parsed.content[0].text).toBe('❌ Simulator not found: NonExistentSimulator-MCP');
    });
  });
});
```

--------------------------------------------------------------------------------
/src/shared/tests/utils/testHelpers.ts:
--------------------------------------------------------------------------------

```typescript
import { Client } from '@modelcontextprotocol/sdk/client/index';
import { StdioClientTransport } from '@modelcontextprotocol/sdk/client/stdio';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

/**
 * Cleanup MCP client and transport connections
 */
export async function cleanupClientAndTransport(
  client: Client | null | undefined,
  transport: StdioClientTransport | null | undefined
): Promise<void> {
  if (client) {
    await client.close();
  }
  
  if (transport) {
    const transportProcess = (transport as any)._process;
    await transport.close();
    
    if (transportProcess) {
      if (transportProcess.stdin && !transportProcess.stdin.destroyed) {
        transportProcess.stdin.end();
        transportProcess.stdin.destroy();
      }
      if (transportProcess.stdout && !transportProcess.stdout.destroyed) {
        transportProcess.stdout.destroy();
      }
      if (transportProcess.stderr && !transportProcess.stderr.destroyed) {
        transportProcess.stderr.destroy();
      }
      transportProcess.unref();
      if (!transportProcess.killed) {
        transportProcess.kill('SIGTERM');
        await new Promise(resolve => {
          const timeout = setTimeout(resolve, 100);
          transportProcess.once('exit', () => {
            clearTimeout(timeout);
            resolve(undefined);
          });
        });
      }
    }
  }
}

/**
 * Create and connect a new MCP client and transport
 */
export async function createAndConnectClient(): Promise<{
  client: Client;
  transport: StdioClientTransport;
}> {
  const transport = new StdioClientTransport({
    command: 'node',
    args: ['dist/index.js'],
    cwd: process.cwd(),
  });
  
  const client = new Client({
    name: 'test-client',
    version: '1.0.0',
  }, {
    capabilities: {}
  });
  
  await client.connect(transport);
  
  return { client, transport };
}

/**
 * Wait for a simulator to reach the Booted state
 * @param simulatorId The simulator UUID to wait for
 * @param maxSeconds Maximum seconds to wait (default 30)
 * @returns Promise that resolves when booted or rejects on timeout
 */
export async function waitForSimulatorBoot(
  simulatorId: string,
  maxSeconds: number = 30
): Promise<void> {
  for (let i = 0; i < maxSeconds; i++) {
    const listResult = await execAsync('xcrun simctl list devices --json');
    const devices = JSON.parse(listResult.stdout);

    for (const runtime of Object.values(devices.devices) as any[]) {
      const device = runtime.find((d: any) => d.udid === simulatorId);
      if (device && device.state === 'Booted') {
        return; // Successfully booted
      }
    }

    // Wait 1 second before trying again
    await new Promise(resolve => setTimeout(resolve, 1000));
  }

  throw new Error(`Failed to boot simulator ${simulatorId} after ${maxSeconds} seconds`);
}

/**
 * Boot a simulator and wait for it to be ready
 * @param simulatorId The simulator UUID to boot
 * @param maxSeconds Maximum seconds to wait (default 30)
 */
export async function bootAndWaitForSimulator(
  simulatorId: string,
  maxSeconds: number = 30
): Promise<void> {
  try {
    await execAsync(`xcrun simctl boot "${simulatorId}"`);
  } catch {
    // Ignore if already booted
  }

  await waitForSimulatorBoot(simulatorId, maxSeconds);
}

/**
 * Wait for a simulator to reach the Shutdown state
 * @param simulatorId The simulator UUID to wait for
 * @param maxSeconds Maximum seconds to wait (default 30)
 * @returns Promise that resolves when shutdown or rejects on timeout
 */
export async function waitForSimulatorShutdown(
  simulatorId: string,
  maxSeconds: number = 30
): Promise<void> {
  for (let i = 0; i < maxSeconds; i++) {
    const listResult = await execAsync('xcrun simctl list devices --json');
    const devices = JSON.parse(listResult.stdout);

    for (const runtime of Object.values(devices.devices) as any[]) {
      const device = runtime.find((d: any) => d.udid === simulatorId);
      if (device && device.state === 'Shutdown') {
        return; // Successfully shutdown
      }
    }

    // Wait 1 second before trying again
    await new Promise(resolve => setTimeout(resolve, 1000));
  }

  throw new Error(`Failed to shutdown simulator ${simulatorId} after ${maxSeconds} seconds`);
}

/**
 * Shutdown a simulator and wait for it to be shutdown
 * @param simulatorId The simulator UUID to shutdown
 * @param maxSeconds Maximum seconds to wait (default 30)
 */
export async function shutdownAndWaitForSimulator(
  simulatorId: string,
  maxSeconds: number = 30
): Promise<void> {
  try {
    await execAsync(`xcrun simctl shutdown "${simulatorId}"`);
  } catch {
    // Ignore if already shutdown
  }

  await waitForSimulatorShutdown(simulatorId, maxSeconds);
}

/**
 * Cleanup a test simulator by shutting it down and deleting it
 * @param simulatorId The simulator UUID to cleanup
 */
export async function cleanupTestSimulator(simulatorId: string | undefined): Promise<void> {
  if (!simulatorId) return;

  try {
    await execAsync(`xcrun simctl shutdown "${simulatorId}"`);
  } catch {
    // Ignore shutdown errors - simulator might already be shutdown
  }

  try {
    await execAsync(`xcrun simctl delete "${simulatorId}"`);
  } catch {
    // Ignore delete errors - simulator might already be deleted
  }
}


```

--------------------------------------------------------------------------------
/src/features/simulator/tests/e2e/ShutdownSimulatorController.e2e.test.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * E2E Test for ShutdownSimulatorController
 * 
 * Tests the controller with REAL simulators and REAL system commands
 * Following testing philosophy: E2E tests for critical paths only (10%)
 * 
 * NO MOCKS - Uses real xcrun simctl commands with actual simulators
 */

import { describe, it, expect, beforeAll, afterAll, beforeEach } from '@jest/globals';
import { MCPController } from '../../../../presentation/interfaces/MCPController.js';
import { ShutdownSimulatorControllerFactory } from '../../factories/ShutdownSimulatorControllerFactory.js';
import { exec } from 'child_process';
import { promisify } from 'util';
import { TestSimulatorManager } from '../../../../shared/tests/utils/TestSimulatorManager.js';

const execAsync = promisify(exec);

describe('ShutdownSimulatorController E2E', () => {
  let controller: MCPController;
  let testSimManager: TestSimulatorManager;
  
  beforeAll(async () => {
    // Create controller with REAL components
    controller = ShutdownSimulatorControllerFactory.create();

    // Set up test simulator
    testSimManager = new TestSimulatorManager();
    await testSimManager.getOrCreateSimulator('TestSimulator-Shutdown');
  });
  
  beforeEach(async () => {
    // Boot simulator before each test (to ensure we can shut it down)
    await testSimManager.bootAndWait(30);
  });
  
  afterAll(async () => {
    // Cleanup test simulator
    await testSimManager.cleanup();
  });

  describe('shutdown real simulators', () => {
    it('should shutdown a booted simulator', async () => {
      // Act
      const result = await controller.execute({
        deviceId: testSimManager.getSimulatorName()
      });
      
      // Assert
      expect(result.content[0].text).toBe(`✅ Successfully shutdown simulator: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
      
      // Verify simulator is actually shutdown
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);
      let found = false;
      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === testSimManager.getSimulatorId());
        if (device) {
          expect(device.state).toBe('Shutdown');
          found = true;
          break;
        }
      }
      expect(found).toBe(true);
    });

    it('should handle already shutdown simulator', async () => {
      // Arrange - shutdown simulator first
      await testSimManager.shutdownAndWait(5);
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      // Act
      const result = await controller.execute({
        deviceId: testSimManager.getSimulatorName()
      });
      
      // Assert
      expect(result.content[0].text).toBe(`✅ Simulator already shutdown: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
    });

    it('should shutdown simulator by UUID', async () => {
      // Act
      const result = await controller.execute({
        deviceId: testSimManager.getSimulatorId()
      });
      
      // Assert
      expect(result.content[0].text).toBe(`✅ Successfully shutdown simulator: ${testSimManager.getSimulatorName()} (${testSimManager.getSimulatorId()})`);
      
      // Verify simulator is actually shutdown
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);
      let found = false;
      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === testSimManager.getSimulatorId());
        if (device) {
          expect(device.state).toBe('Shutdown');
          found = true;
          break;
        }
      }
      expect(found).toBe(true);
    });
  });

  describe('error handling', () => {
    it('should handle non-existent simulator', async () => {
      // Act
      const result = await controller.execute({
        deviceId: 'NonExistent-Simulator-That-Does-Not-Exist'
      });
      
      // Assert
      expect(result.content[0].text).toBe('❌ Simulator not found: NonExistent-Simulator-That-Does-Not-Exist');
    });
  });

  describe('complex scenarios', () => {
    it('should shutdown simulator that was booting', async () => {
      // Arrange - boot and immediately try to shutdown
      const bootPromise = testSimManager.bootAndWait(30);
      
      // Act - shutdown while booting
      const result = await controller.execute({
        deviceId: testSimManager.getSimulatorName()
      });
      
      // Assert
      expect(result.content[0].text).toContain('✅');
      expect(result.content[0].text).toContain(testSimManager.getSimulatorName());
      
      // Wait for operations to complete
      try {
        await bootPromise;
      } catch {
        // Boot might fail if shutdown interrupted it, that's OK
      }
      
      // Verify final state is shutdown
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);
      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === testSimManager.getSimulatorId());
        if (device) {
          expect(device.state).toBe('Shutdown');
          break;
        }
      }
    });
  });
});
```

--------------------------------------------------------------------------------
/src/utils/projects/SwiftPackageInfo.ts:
--------------------------------------------------------------------------------

```typescript
import { execAsync } from '../../utils.js';
import { createModuleLogger } from '../../logger.js';

const logger = createModuleLogger('SwiftPackageInfo');

export interface Dependency {
  name: string;
  url: string;
  version?: string;
  branch?: string;
  revision?: string;
}

export interface Product {
  name: string;
  type: 'executable' | 'library';
  targets: string[];
}

/**
 * Queries information about Swift packages
 */
export class SwiftPackageInfo {
  /**
   * Get list of products in a package
   */
  async getProducts(packagePath: string): Promise<Product[]> {
    const command = `swift package --package-path "${packagePath}" describe --type json`;
    
    logger.debug({ command }, 'Describe package command');
    
    try {
      const { stdout } = await execAsync(command);
      const packageInfo = JSON.parse(stdout);
      
      const products: Product[] = packageInfo.products?.map((p: any) => ({
        name: p.name,
        type: p.type?.executable ? 'executable' : 'library',
        targets: p.targets || []
      })) || [];
      
      logger.debug({ packagePath, products }, 'Found products');
      return products;
    } catch (error: any) {
      logger.error({ error: error.message, packagePath }, 'Failed to get products');
      throw new Error(`Failed to get products: ${error.message}`);
    }
  }
  
  /**
   * Get list of targets in a package
   */
  async getTargets(packagePath: string): Promise<string[]> {
    const command = `swift package --package-path "${packagePath}" describe --type json`;
    
    logger.debug({ command }, 'Describe package command');
    
    try {
      const { stdout } = await execAsync(command);
      const packageInfo = JSON.parse(stdout);
      
      const targets = packageInfo.targets?.map((t: any) => t.name) || [];
      
      logger.debug({ packagePath, targets }, 'Found targets');
      return targets;
    } catch (error: any) {
      logger.error({ error: error.message, packagePath }, 'Failed to get targets');
      throw new Error(`Failed to get targets: ${error.message}`);
    }
  }
  
  /**
   * Get list of dependencies
   */
  async getDependencies(packagePath: string): Promise<Dependency[]> {
    const command = `swift package --package-path "${packagePath}" show-dependencies --format json`;
    
    logger.debug({ command }, 'Show dependencies command');
    
    try {
      const { stdout } = await execAsync(command);
      const depTree = JSON.parse(stdout);
      
      // Extract direct dependencies from the tree
      const dependencies: Dependency[] = depTree.dependencies?.map((d: any) => ({
        name: d.name,
        url: d.url,
        version: d.version,
        branch: d.branch,
        revision: d.revision
      })) || [];
      
      logger.debug({ packagePath, dependencies }, 'Found dependencies');
      return dependencies;
    } catch (error: any) {
      logger.error({ error: error.message, packagePath }, 'Failed to get dependencies');
      throw new Error(`Failed to get dependencies: ${error.message}`);
    }
  }
  
  /**
   * Add a dependency to the package
   */
  async addDependency(
    packagePath: string,
    url: string,
    options: {
      version?: string;
      branch?: string;
      exact?: boolean;
      from?: string;
      upToNextMajor?: string;
    } = {}
  ): Promise<void> {
    let command = `swift package --package-path "${packagePath}" add-dependency "${url}"`;
    
    if (options.branch) {
      command += ` --branch "${options.branch}"`;
    } else if (options.exact) {
      command += ` --exact "${options.version}"`;
    } else if (options.from) {
      command += ` --from "${options.from}"`;
    } else if (options.upToNextMajor) {
      command += ` --up-to-next-major-from "${options.upToNextMajor}"`;
    }
    
    logger.debug({ command }, 'Add dependency command');
    
    try {
      await execAsync(command);
      logger.info({ packagePath, url }, 'Dependency added');
    } catch (error: any) {
      logger.error({ error: error.message, packagePath, url }, 'Failed to add dependency');
      throw new Error(`Failed to add dependency: ${error.message}`);
    }
  }
  
  /**
   * Remove a dependency from the package
   */
  async removeDependency(packagePath: string, name: string): Promise<void> {
    const command = `swift package --package-path "${packagePath}" remove-dependency "${name}"`;
    
    logger.debug({ command }, 'Remove dependency command');
    
    try {
      await execAsync(command);
      logger.info({ packagePath, name }, 'Dependency removed');
    } catch (error: any) {
      logger.error({ error: error.message, packagePath, name }, 'Failed to remove dependency');
      throw new Error(`Failed to remove dependency: ${error.message}`);
    }
  }
  
  /**
   * Update package dependencies
   */
  async updateDependencies(packagePath: string): Promise<void> {
    const command = `swift package --package-path "${packagePath}" update`;
    
    logger.debug({ command }, 'Update dependencies command');
    
    try {
      await execAsync(command);
      logger.info({ packagePath }, 'Dependencies updated');
    } catch (error: any) {
      logger.error({ error: error.message, packagePath }, 'Failed to update dependencies');
      throw new Error(`Failed to update dependencies: ${error.message}`);
    }
  }
  
  /**
   * Resolve package dependencies
   */
  async resolveDependencies(packagePath: string): Promise<void> {
    const command = `swift package --package-path "${packagePath}" resolve`;
    
    logger.debug({ command }, 'Resolve dependencies command');
    
    try {
      await execAsync(command);
      logger.info({ packagePath }, 'Dependencies resolved');
    } catch (error: any) {
      logger.error({ error: error.message, packagePath }, 'Failed to resolve dependencies');
      throw new Error(`Failed to resolve dependencies: ${error.message}`);
    }
  }
}
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/unit/ListSimulatorsController.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest } from '@jest/globals';
import { ListSimulatorsController } from '../../controllers/ListSimulatorsController.js';
import { ListSimulatorsUseCase } from '../../use-cases/ListSimulatorsUseCase.js';
import { ListSimulatorsRequest } from '../../domain/ListSimulatorsRequest.js';
import { ListSimulatorsResult, SimulatorInfo } from '../../domain/ListSimulatorsResult.js';
import { SimulatorState } from '../../domain/SimulatorState.js';

describe('ListSimulatorsController', () => {
  function createSUT() {
    const mockExecute = jest.fn<(request: ListSimulatorsRequest) => Promise<ListSimulatorsResult>>();
    const mockUseCase: Partial<ListSimulatorsUseCase> = {
      execute: mockExecute
    };
    const sut = new ListSimulatorsController(mockUseCase as ListSimulatorsUseCase);
    return { sut, mockExecute };
  }

  describe('MCP tool interface', () => {
    it('should define correct tool metadata', () => {
      // Arrange
      const { sut } = createSUT();

      // Act
      const definition = sut.getToolDefinition();

      // Assert
      expect(definition.name).toBe('list_simulators');
      expect(definition.description).toBe('List available iOS simulators');
      expect(definition.inputSchema).toBeDefined();
    });

    it('should define correct input schema with optional filters', () => {
      // Arrange
      const { sut } = createSUT();

      // Act
      const schema = sut.inputSchema;

      // Assert
      expect(schema.type).toBe('object');
      expect(schema.properties.platform).toBeDefined();
      expect(schema.properties.platform.type).toBe('string');
      expect(schema.properties.platform.enum).toEqual(['iOS', 'tvOS', 'watchOS', 'visionOS']);
      expect(schema.properties.state).toBeDefined();
      expect(schema.properties.state.type).toBe('string');
      expect(schema.properties.state.enum).toEqual(['Booted', 'Shutdown']);
      expect(schema.properties.name).toBeDefined();
      expect(schema.properties.name.type).toBe('string');
      expect(schema.properties.name.description).toBe('Filter by device name (partial match, case-insensitive)');
      expect(schema.required).toEqual([]);
    });
  });

  describe('execute', () => {
    it('should list all simulators without filters', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const simulators: SimulatorInfo[] = [
        {
          udid: 'ABC123',
          name: 'iPhone 15',
          state: SimulatorState.Booted,
          platform: 'iOS',
          runtime: 'iOS 17.0'
        },
        {
          udid: 'DEF456',
          name: 'iPad Pro',
          state: SimulatorState.Shutdown,
          platform: 'iOS',
          runtime: 'iOS 17.0'
        }
      ];
      const mockResult = ListSimulatorsResult.success(simulators);
      mockExecute.mockResolvedValue(mockResult);

      // Act
      const result = await sut.execute({});

      // Assert
      expect(result.content[0].text).toContain('Found 2 simulators');
      expect(result.content[0].text).toContain('iPhone 15 (ABC123) - Booted');
      expect(result.content[0].text).toContain('iPad Pro (DEF456) - Shutdown');
    });

    it('should filter by platform', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const simulators: SimulatorInfo[] = [
        {
          udid: 'ABC123',
          name: 'iPhone 15',
          state: SimulatorState.Booted,
          platform: 'iOS',
          runtime: 'iOS 17.0'
        }
      ];
      const mockResult = ListSimulatorsResult.success(simulators);
      mockExecute.mockResolvedValue(mockResult);

      // Act
      const result = await sut.execute({ platform: 'iOS' });

      // Assert
      expect(result.content[0].text).toContain('Found 1 simulator');
    });

    it('should filter by state', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const simulators: SimulatorInfo[] = [
        {
          udid: 'ABC123',
          name: 'iPhone 15',
          state: SimulatorState.Booted,
          platform: 'iOS',
          runtime: 'iOS 17.0'
        }
      ];
      const mockResult = ListSimulatorsResult.success(simulators);
      mockExecute.mockResolvedValue(mockResult);

      // Act
      const result = await sut.execute({ state: 'Booted' });

      // Assert
      expect(result.content[0].text).toContain('✅');
    });

    it('should handle no simulators found', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const mockResult = ListSimulatorsResult.success([]);
      mockExecute.mockResolvedValue(mockResult);

      // Act
      const result = await sut.execute({});

      // Assert
      expect(result.content[0].text).toBe('🔍 No simulators found');
    });

    it('should handle errors gracefully', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const mockResult = ListSimulatorsResult.failed(new Error('Failed to list devices'));
      mockExecute.mockResolvedValue(mockResult);

      // Act
      const result = await sut.execute({});

      // Assert
      expect(result.content[0].text).toContain('❌');
      expect(result.content[0].text).toContain('Failed to list devices');
    });

    it('should format simulators with runtime info', async () => {
      // Arrange
      const { sut, mockExecute } = createSUT();
      const simulators: SimulatorInfo[] = [
        {
          udid: 'ABC123',
          name: 'iPhone 15 Pro Max',
          state: SimulatorState.Booted,
          platform: 'iOS',
          runtime: 'iOS 17.2'
        }
      ];
      const mockResult = ListSimulatorsResult.success(simulators);
      mockExecute.mockResolvedValue(mockResult);

      // Act
      const result = await sut.execute({});

      // Assert
      expect(result.content[0].text).toContain('iOS 17.2');
    });

    it('should return validation error for invalid input', async () => {
      // Arrange
      const { sut } = createSUT();

      // Act
      const result = await sut.execute({
        platform: 'invalid'
      });

      // Assert
      expect(result.content[0].text).toBe('❌ Invalid platform: invalid. Valid values are: iOS, macOS, tvOS, watchOS, visionOS');
    });

  });
});
```

--------------------------------------------------------------------------------
/src/shared/tests/unit/ConfigProviderAdapter.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { ConfigProviderAdapter } from '../../infrastructure/ConfigProviderAdapter.js';
import { IConfigProvider } from '../../../application/ports/ConfigPorts.js';
import { homedir } from 'os';
import path from 'path';

describe('ConfigProvider', () => {
  // Save original env
  const originalEnv = process.env;
  
  beforeEach(() => {
    // Reset env before each test
    process.env = { ...originalEnv };
  });
  
  afterAll(() => {
    // Restore original env
    process.env = originalEnv;
  });
  
  // Factory method for creating the SUT
  function createSUT(): IConfigProvider {
    return new ConfigProviderAdapter();
  }
  
  describe('getDerivedDataPath', () => {
    it('should use default path when no env var is set', () => {
      // Arrange
      delete process.env.MCP_XCODE_DERIVED_DATA_PATH;
      const sut = createSUT();
      const expectedPath = path.join(homedir(), 'Library', 'Developer', 'Xcode', 'DerivedData', 'MCP-Xcode');
      
      // Act
      const result = sut.getDerivedDataPath();
      
      // Assert
      expect(result).toBe(expectedPath);
    });
    
    it('should use env var when set', () => {
      // Arrange
      process.env.MCP_XCODE_DERIVED_DATA_PATH = '/custom/path';
      const sut = createSUT();
      
      // Act
      const result = sut.getDerivedDataPath();
      
      // Assert
      expect(result).toBe('/custom/path');
    });
    
    it('should return project-specific path when project path is provided', () => {
      // Arrange
      process.env.MCP_XCODE_DERIVED_DATA_PATH = '/base/path';
      const sut = createSUT();
      
      // Act
      const result = sut.getDerivedDataPath('/Users/dev/MyApp.xcodeproj');
      
      // Assert
      expect(result).toBe('/base/path/MyApp');
    });
    
    it('should handle workspace paths correctly', () => {
      // Arrange
      process.env.MCP_XCODE_DERIVED_DATA_PATH = '/base/path';
      const sut = createSUT();
      
      // Act
      const result = sut.getDerivedDataPath('/Users/dev/MyWorkspace.xcworkspace');
      
      // Assert
      expect(result).toBe('/base/path/MyWorkspace');
    });
    
    it('should handle paths with spaces', () => {
      // Arrange
      process.env.MCP_XCODE_DERIVED_DATA_PATH = '/base/path';
      const sut = createSUT();
      
      // Act
      const result = sut.getDerivedDataPath('/Users/dev/My App.xcodeproj');
      
      // Assert
      expect(result).toBe('/base/path/My App');
    });
  });
  
  describe('getBuildTimeout', () => {
    it('should return default timeout when no env var is set', () => {
      // Arrange
      delete process.env.MCP_XCODE_BUILD_TIMEOUT;
      const sut = createSUT();
      
      // Act
      const result = sut.getBuildTimeout();
      
      // Assert
      expect(result).toBe(600000); // 10 minutes
    });
    
    it('should use env var when set', () => {
      // Arrange
      process.env.MCP_XCODE_BUILD_TIMEOUT = '300000';
      const sut = createSUT();
      
      // Act
      const result = sut.getBuildTimeout();
      
      // Assert
      expect(result).toBe(300000);
    });
    
    it('should handle invalid timeout value', () => {
      // Arrange
      process.env.MCP_XCODE_BUILD_TIMEOUT = 'invalid';
      const sut = createSUT();
      
      // Act
      const result = sut.getBuildTimeout();
      
      // Assert
      expect(result).toBeNaN(); // parseInt returns NaN for invalid strings
    });
  });
  
  describe('isXcbeautifyEnabled', () => {
    it('should return true by default', () => {
      // Arrange
      delete process.env.MCP_XCODE_XCBEAUTIFY_ENABLED;
      const sut = createSUT();
      
      // Act
      const result = sut.isXcbeautifyEnabled();
      
      // Assert
      expect(result).toBe(true);
    });
    
    it('should return true when env var is "true"', () => {
      // Arrange
      process.env.MCP_XCODE_XCBEAUTIFY_ENABLED = 'true';
      const sut = createSUT();
      
      // Act
      const result = sut.isXcbeautifyEnabled();
      
      // Assert
      expect(result).toBe(true);
    });
    
    it('should return false when env var is "false"', () => {
      // Arrange
      process.env.MCP_XCODE_XCBEAUTIFY_ENABLED = 'false';
      const sut = createSUT();
      
      // Act
      const result = sut.isXcbeautifyEnabled();
      
      // Assert
      expect(result).toBe(false);
    });
    
    it('should handle case insensitive true value', () => {
      // Arrange
      process.env.MCP_XCODE_XCBEAUTIFY_ENABLED = 'TRUE';
      const sut = createSUT();
      
      // Act
      const result = sut.isXcbeautifyEnabled();
      
      // Assert
      expect(result).toBe(true);
    });
    
    it('should return false for any non-true value', () => {
      // Arrange
      process.env.MCP_XCODE_XCBEAUTIFY_ENABLED = 'yes';
      const sut = createSUT();
      
      // Act
      const result = sut.isXcbeautifyEnabled();
      
      // Assert
      expect(result).toBe(false);
    });
  });
  
  describe('getCustomBuildSettings', () => {
    it('should return empty object by default', () => {
      // Arrange
      delete process.env.MCP_XCODE_CUSTOM_BUILD_SETTINGS;
      const sut = createSUT();
      
      // Act
      const result = sut.getCustomBuildSettings();
      
      // Assert
      expect(result).toEqual({});
    });
    
    it('should parse valid JSON from env var', () => {
      // Arrange
      const settings = { 'SWIFT_VERSION': '5.9', 'DEBUG': 'true' };
      process.env.MCP_XCODE_CUSTOM_BUILD_SETTINGS = JSON.stringify(settings);
      const sut = createSUT();
      
      // Act
      const result = sut.getCustomBuildSettings();
      
      // Assert
      expect(result).toEqual(settings);
    });
    
    it('should return empty object for invalid JSON', () => {
      // Arrange
      process.env.MCP_XCODE_CUSTOM_BUILD_SETTINGS = 'not valid json';
      const sut = createSUT();
      
      // Act
      const result = sut.getCustomBuildSettings();
      
      // Assert
      expect(result).toEqual({});
    });
    
    it('should handle empty JSON object', () => {
      // Arrange
      process.env.MCP_XCODE_CUSTOM_BUILD_SETTINGS = '{}';
      const sut = createSUT();
      
      // Act
      const result = sut.getCustomBuildSettings();
      
      // Assert
      expect(result).toEqual({});
    });
  });
});
```

--------------------------------------------------------------------------------
/src/shared/tests/utils/TestSimulatorManager.ts:
--------------------------------------------------------------------------------

```typescript
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

/**
 * Manages test simulator lifecycle for E2E tests
 * Handles creation, booting, shutdown, and cleanup of test simulators
 */
export class TestSimulatorManager {
  private simulatorId?: string;
  private simulatorName?: string;

  /**
   * Create or reuse a test simulator
   * @param namePrefix Prefix for the simulator name (e.g., "TestSimulator-Boot")
   * @param deviceType Device type (defaults to iPhone 15)
   * @returns The simulator ID
   */
  async getOrCreateSimulator(
    namePrefix: string,
    deviceType: string = 'iPhone 15'
  ): Promise<string> {
    // Check if simulator already exists
    const devicesResult = await execAsync('xcrun simctl list devices --json');
    const devices = JSON.parse(devicesResult.stdout);

    // Look for existing test simulator
    for (const runtime of Object.values(devices.devices) as any[]) {
      const existingSim = runtime.find((d: any) => d.name.includes(namePrefix));
      if (existingSim) {
        this.simulatorId = existingSim.udid;
        this.simulatorName = existingSim.name;
        return existingSim.udid;
      }
    }

    // Create new simulator if none exists
    const runtimesResult = await execAsync('xcrun simctl list runtimes --json');
    const runtimes = JSON.parse(runtimesResult.stdout);
    const iosRuntime = runtimes.runtimes.find((r: { platform: string }) => r.platform === 'iOS');

    if (!iosRuntime) {
      throw new Error('No iOS runtime found. Please install an iOS simulator runtime.');
    }

    const createResult = await execAsync(
      `xcrun simctl create "${namePrefix}" "${deviceType}" "${iosRuntime.identifier}"`
    );
    this.simulatorId = createResult.stdout.trim();
    this.simulatorName = namePrefix;

    return this.simulatorId;
  }

  /**
   * Boot the simulator and wait for it to be ready
   * @param maxSeconds Maximum seconds to wait (default 30)
   */
  async bootAndWait(maxSeconds: number = 30): Promise<void> {
    if (!this.simulatorId) {
      throw new Error('No simulator to boot. Call getOrCreateSimulator first.');
    }

    try {
      await execAsync(`xcrun simctl boot "${this.simulatorId}"`);
    } catch {
      // Ignore if already booted
    }

    await this.waitForBoot(maxSeconds);
  }

  /**
   * Shutdown the simulator and wait for completion
   * @param maxSeconds Maximum seconds to wait (default 30)
   */
  async shutdownAndWait(maxSeconds: number = 30): Promise<void> {
    if (!this.simulatorId) return;

    try {
      await execAsync(`xcrun simctl shutdown "${this.simulatorId}"`);
    } catch {
      // Ignore if already shutdown
    }

    await this.waitForShutdown(maxSeconds);
  }

  /**
   * Cleanup the test simulator (shutdown and delete)
   */
  async cleanup(): Promise<void> {
    if (!this.simulatorId) return;

    try {
      await execAsync(`xcrun simctl shutdown "${this.simulatorId}"`);
    } catch {
      // Ignore shutdown errors
    }

    try {
      await execAsync(`xcrun simctl delete "${this.simulatorId}"`);
    } catch {
      // Ignore delete errors
    }

    this.simulatorId = undefined;
    this.simulatorName = undefined;
  }

  /**
   * Get the current simulator ID
   */
  getSimulatorId(): string | undefined {
    return this.simulatorId;
  }

  /**
   * Get the current simulator name
   */
  getSimulatorName(): string | undefined {
    return this.simulatorName;
  }

  /**
   * Check if the simulator is booted
   */
  async isBooted(): Promise<boolean> {
    if (!this.simulatorId) return false;

    const listResult = await execAsync('xcrun simctl list devices --json');
    const devices = JSON.parse(listResult.stdout);

    for (const runtime of Object.values(devices.devices) as any[]) {
      const device = runtime.find((d: any) => d.udid === this.simulatorId);
      if (device) {
        return device.state === 'Booted';
      }
    }
    return false;
  }

  /**
   * Check if the simulator is shutdown
   */
  async isShutdown(): Promise<boolean> {
    if (!this.simulatorId) return true;

    const listResult = await execAsync('xcrun simctl list devices --json');
    const devices = JSON.parse(listResult.stdout);

    for (const runtime of Object.values(devices.devices) as any[]) {
      const device = runtime.find((d: any) => d.udid === this.simulatorId);
      if (device) {
        return device.state === 'Shutdown';
      }
    }
    return true;
  }

  private async waitForBoot(maxSeconds: number): Promise<void> {
    for (let i = 0; i < maxSeconds; i++) {
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);

      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === this.simulatorId);
        if (device && device.state === 'Booted') {
          // Wait a bit more for services to be ready
          await new Promise(resolve => setTimeout(resolve, 2000));
          return;
        }
      }

      await new Promise(resolve => setTimeout(resolve, 1000));
    }

    throw new Error(`Failed to boot simulator ${this.simulatorId} after ${maxSeconds} seconds`);
  }

  private async waitForShutdown(maxSeconds: number): Promise<void> {
    for (let i = 0; i < maxSeconds; i++) {
      const listResult = await execAsync('xcrun simctl list devices --json');
      const devices = JSON.parse(listResult.stdout);

      for (const runtime of Object.values(devices.devices) as any[]) {
        const device = runtime.find((d: any) => d.udid === this.simulatorId);
        if (device && device.state === 'Shutdown') {
          return;
        }
      }

      await new Promise(resolve => setTimeout(resolve, 1000));
    }

    throw new Error(`Failed to shutdown simulator ${this.simulatorId} after ${maxSeconds} seconds`);
  }

  /**
   * Shutdown all other booted simulators except this one
   */
  async shutdownOtherSimulators(): Promise<void> {
    const devicesResult = await execAsync('xcrun simctl list devices --json');
    const devices = JSON.parse(devicesResult.stdout);

    for (const runtime of Object.values(devices.devices) as any[][]) {
      for (const device of runtime) {
        if (device.state === 'Booted' && device.udid !== this.simulatorId) {
          try {
            await execAsync(`xcrun simctl shutdown "${device.udid}"`);
          } catch {
            // Ignore errors
          }
        }
      }
    }
  }
}
```

--------------------------------------------------------------------------------
/src/shared/tests/unit/ProjectPath.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest, beforeEach, afterEach } from '@jest/globals';
import { ProjectPath } from '../../domain/ProjectPath.js';
import { existsSync } from 'fs';

// Mock fs module
jest.mock('fs', () => ({
  existsSync: jest.fn<(path: string) => boolean>()
}));
const mockExistsSync = existsSync as jest.MockedFunction<typeof existsSync>;

describe('ProjectPath', () => {
  // Reset mocks between tests for isolation
  beforeEach(() => {
    jest.clearAllMocks();
  });
  
  afterEach(() => {
    jest.restoreAllMocks();
  });
  
  describe('when creating a project path', () => {
    it('should accept valid .xcodeproj path that exists', () => {
      // Setup - all visible in test
      const projectPath = '/Users/dev/MyApp.xcodeproj';
      mockExistsSync.mockReturnValue(true);
      
      // Act
      const result = ProjectPath.create(projectPath);
      
      // Assert
      expect(result.toString()).toBe(projectPath);
      expect(mockExistsSync).toHaveBeenCalledWith(projectPath);
    });
    
    it('should accept valid .xcworkspace path that exists', () => {
      const workspacePath = '/Users/dev/MyApp.xcworkspace';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(workspacePath);
      
      expect(result.toString()).toBe(workspacePath);
      expect(mockExistsSync).toHaveBeenCalledWith(workspacePath);
    });
    
    it('should accept paths with spaces', () => {
      const pathWithSpaces = '/Users/dev/My Cool App.xcodeproj';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(pathWithSpaces);
      
      expect(result.toString()).toBe(pathWithSpaces);
    });
    
    it('should accept paths with special characters', () => {
      const specialPath = '/Users/dev/App-2024_v1.0.xcworkspace';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(specialPath);
      
      expect(result.toString()).toBe(specialPath);
    });
  });
  
  describe('when validating input', () => {
    it('should reject empty path', () => {
      expect(() => ProjectPath.create('')).toThrow('Project path cannot be empty');
      expect(mockExistsSync).not.toHaveBeenCalled();
    });
    
    it('should reject null path', () => {
      expect(() => ProjectPath.create(null as any))
        .toThrow('Project path is required');
      expect(mockExistsSync).not.toHaveBeenCalled();
    });
    
    it('should reject undefined path', () => {
      expect(() => ProjectPath.create(undefined as any))
        .toThrow('Project path is required');
      expect(mockExistsSync).not.toHaveBeenCalled();
    });
    
    it('should reject non-existent path', () => {
      const nonExistentPath = '/Users/dev/DoesNotExist.xcodeproj';
      mockExistsSync.mockReturnValue(false);
      
      expect(() => ProjectPath.create(nonExistentPath))
        .toThrow(`Project path does not exist: ${nonExistentPath}`);
      expect(mockExistsSync).toHaveBeenCalledWith(nonExistentPath);
    });
    
    it('should reject non-Xcode project files', () => {
      mockExistsSync.mockReturnValue(true);
      
      const invalidFiles = [
        '/Users/dev/MyApp.swift',
        '/Users/dev/MyApp.txt',
        '/Users/dev/MyApp.app',
        '/Users/dev/MyApp.framework',
        '/Users/dev/MyApp',  // No extension
        '/Users/dev/MyApp.xcode',  // Wrong extension
      ];
      
      invalidFiles.forEach(file => {
        expect(() => ProjectPath.create(file))
          .toThrow('Project path must be an .xcodeproj or .xcworkspace file');
      });
    });
    
    it('should reject directories without proper extension', () => {
      const directory = '/Users/dev/MyProject';
      mockExistsSync.mockReturnValue(true);
      
      expect(() => ProjectPath.create(directory))
        .toThrow('Project path must be an .xcodeproj or .xcworkspace file');
    });
  });
  
  describe('when getting project name', () => {
    it('should extract name from .xcodeproj path', () => {
      const projectPath = '/Users/dev/MyAwesomeApp.xcodeproj';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(projectPath);
      
      expect(result.name).toBe('MyAwesomeApp');
    });
    
    it('should extract name from .xcworkspace path', () => {
      const workspacePath = '/Users/dev/CoolWorkspace.xcworkspace';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(workspacePath);
      
      expect(result.name).toBe('CoolWorkspace');
    });
    
    it('should handle names with dots', () => {
      const pathWithDots = '/Users/dev/App.v2.0.xcodeproj';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(pathWithDots);
      
      expect(result.name).toBe('App.v2.0');
    });
    
    it('should handle names with spaces', () => {
      const pathWithSpaces = '/Users/dev/My Cool App.xcworkspace';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(pathWithSpaces);
      
      expect(result.name).toBe('My Cool App');
    });
  });
  
  describe('when checking project type', () => {
    it('should identify workspace files', () => {
      const workspacePath = '/Users/dev/MyApp.xcworkspace';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(workspacePath);
      
      expect(result.isWorkspace).toBe(true);
    });
    
    it('should identify non-workspace files as projects', () => {
      const projectPath = '/Users/dev/MyApp.xcodeproj';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(projectPath);
      
      expect(result.isWorkspace).toBe(false);
    });
  });
  
  describe('when converting to string', () => {
    it('should return the original path', () => {
      const originalPath = '/Users/dev/path/to/MyApp.xcodeproj';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(originalPath);
      
      expect(result.toString()).toBe(originalPath);
      expect(`${result}`).toBe(originalPath); // Implicit string conversion
    });
  });
  
  describe('when path validation is called multiple times', () => {
    it('should check existence only once during creation', () => {
      const projectPath = '/Users/dev/MyApp.xcodeproj';
      mockExistsSync.mockReturnValue(true);
      
      const result = ProjectPath.create(projectPath);
      
      // Access properties multiple times
      result.name;
      result.isWorkspace;
      result.toString();
      
      // Should only check existence once during creation
      expect(mockExistsSync).toHaveBeenCalledTimes(1);
    });
  });
});
```

--------------------------------------------------------------------------------
/src/shared/tests/unit/ShellCommandExecutorAdapter.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest, beforeEach } from '@jest/globals';
import { ExecOptions } from 'child_process';
import { ShellCommandExecutorAdapter } from '../../infrastructure/ShellCommandExecutorAdapter.js';

/**
 * Unit tests for ShellCommandExecutor
 * 
 * Following testing philosophy:
 * - Test behavior, not implementation
 * - Use dependency injection for clean testing
 */
describe('ShellCommandExecutor', () => {
  beforeEach(() => {
    jest.clearAllMocks();
  });
  
  // Factory method for creating the SUT with mocked exec function
  function createSUT() {
    const mockExecAsync = jest.fn<(command: string, options: ExecOptions) => Promise<{ stdout: string; stderr: string }>>();
    const sut = new ShellCommandExecutorAdapter(mockExecAsync);
    return { sut, mockExecAsync };
  }
  
  describe('execute', () => {
    describe('when executing successful commands', () => {
      it('should return stdout and stderr with exitCode 0', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'echo "hello world"';
        mockExecAsync.mockResolvedValue({ 
          stdout: 'hello world\n', 
          stderr: '' 
        });
        
        // Act
        const result = await sut.execute(command);
        
        // Assert
        expect(result).toEqual({
          stdout: 'hello world\n',
          stderr: '',
          exitCode: 0
        });
        expect(mockExecAsync).toHaveBeenCalledWith(command, expect.objectContaining({
          maxBuffer: 50 * 1024 * 1024,
          timeout: 300000,
          shell: '/bin/bash'
        }));
      });
      
      it('should handle large output', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'cat large_file.txt';
        const largeOutput = 'x'.repeat(10 * 1024 * 1024); // 10MB
        mockExecAsync.mockResolvedValue({ 
          stdout: largeOutput, 
          stderr: '' 
        });
        
        // Act
        const result = await sut.execute(command);
        
        // Assert
        expect(result.stdout).toHaveLength(10 * 1024 * 1024);
        expect(result.exitCode).toBe(0);
      });
      
      it('should handle both stdout and stderr', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'some-command';
        mockExecAsync.mockResolvedValue({ 
          stdout: 'standard output', 
          stderr: 'warning: something happened' 
        });
        
        // Act
        const result = await sut.execute(command);
        
        // Assert
        expect(result.stdout).toBe('standard output');
        expect(result.stderr).toBe('warning: something happened');
        expect(result.exitCode).toBe(0);
      });
    });
    
    describe('when executing failing commands', () => {
      it('should return output with non-zero exit code', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'false';
        const error: any = new Error('Command failed');
        error.code = 1;
        error.stdout = '';
        error.stderr = 'command failed';
        mockExecAsync.mockRejectedValue(error);
        
        // Act
        const result = await sut.execute(command);
        
        // Assert
        expect(result).toEqual({
          stdout: '',
          stderr: 'command failed',
          exitCode: 1
        });
      });
      
      it('should capture output even on failure', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'build-command';
        const error: any = new Error('Build failed');
        error.code = 65;
        error.stdout = 'Compiling...\nError at line 42';
        error.stderr = 'error: undefined symbol';
        mockExecAsync.mockRejectedValue(error);
        
        // Act
        const result = await sut.execute(command);
        
        // Assert
        expect(result.stdout).toContain('Compiling');
        expect(result.stderr).toContain('undefined symbol');
        expect(result.exitCode).toBe(65);
      });
      
      it('should handle missing error code', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'unknown-command';
        const error: any = new Error('Command not found');
        // No error.code set
        error.stdout = '';
        error.stderr = 'command not found';
        mockExecAsync.mockRejectedValue(error);
        
        // Act
        const result = await sut.execute(command);
        
        // Assert
        expect(result.exitCode).toBe(1); // Default to 1 when no code
      });
    });
    
    describe('with custom options', () => {
      it('should pass maxBuffer option', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'echo test';
        const options = { maxBuffer: 100 * 1024 * 1024 }; // 100MB
        mockExecAsync.mockResolvedValue({ stdout: 'test', stderr: '' });
        
        // Act
        await sut.execute(command, options);
        
        // Assert
        expect(mockExecAsync).toHaveBeenCalledWith(command, expect.objectContaining({
          maxBuffer: 100 * 1024 * 1024
        }));
      });
      
      it('should pass timeout option', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'long-running-command';
        const options = { timeout: 600000 }; // 10 minutes
        mockExecAsync.mockResolvedValue({ stdout: 'done', stderr: '' });
        
        // Act
        await sut.execute(command, options);
        
        // Assert
        expect(mockExecAsync).toHaveBeenCalledWith(command, expect.objectContaining({
          timeout: 600000
        }));
      });
      
      it('should pass shell option', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'echo $SHELL';
        const options = { shell: '/bin/zsh' };
        mockExecAsync.mockResolvedValue({ stdout: '/bin/zsh', stderr: '' });
        
        // Act
        await sut.execute(command, options);
        
        // Assert
        expect(mockExecAsync).toHaveBeenCalledWith(command, expect.objectContaining({
          shell: '/bin/zsh'
        }));
      });
      
      it('should use default options when not provided', async () => {
        // Arrange
        const { sut, mockExecAsync } = createSUT();
        const command = 'echo test';
        mockExecAsync.mockResolvedValue({ stdout: 'test', stderr: '' });
        
        // Act
        await sut.execute(command);
        
        // Assert
        expect(mockExecAsync).toHaveBeenCalledWith(command, {
          maxBuffer: 50 * 1024 * 1024,
          timeout: 300000,
          shell: '/bin/bash'
        });
      });
    });
  });
});
```

--------------------------------------------------------------------------------
/src/utils/devices/SimulatorBoot.ts:
--------------------------------------------------------------------------------

```typescript
import { execAsync } from '../../utils.js';
import { createModuleLogger } from '../../logger.js';

const logger = createModuleLogger('SimulatorBoot');

/**
 * Simple utility to boot simulators for Xcode builds
 * Extracted shared logic from BuildXcodeTool and RunXcodeTool
 */
export class SimulatorBoot {
  /**
   * Boot a simulator
   */
  async boot(deviceId: string): Promise<void> {
    try {
      await execAsync(`xcrun simctl boot "${deviceId}"`);
      logger.debug({ deviceId }, 'Simulator booted successfully');
    } catch (error: any) {
      // Check if already booted
      if (!error.message?.includes('Unable to boot device in current state: Booted')) {
        logger.error({ error: error.message, deviceId }, 'Failed to boot simulator');
        throw new Error(`Failed to boot simulator: ${error.message}`);
      }
      logger.debug({ deviceId }, 'Simulator already booted');
    }
  }

  /**
   * Shutdown a simulator
   */
  async shutdown(deviceId: string): Promise<void> {
    try {
      await execAsync(`xcrun simctl shutdown "${deviceId}"`);
      logger.debug({ deviceId }, 'Simulator shutdown successfully');
    } catch (error: any) {
      logger.error({ error: error.message, deviceId }, 'Failed to shutdown simulator');
      throw new Error(`Failed to shutdown simulator: ${error.message}`);
    }
  }

  /**
   * Opens the Simulator app GUI (skipped during tests)
   */
  async openSimulatorApp(): Promise<void> {
    // Skip opening GUI during tests
    if (process.env.NODE_ENV === 'test' || process.env.JEST_WORKER_ID) {
      logger.debug('Skipping Simulator GUI in test environment');
      return;
    }
    
    try {
      await execAsync('open -g -a Simulator');
      logger.debug('Opened Simulator app');
    } catch (error: any) {
      logger.warn({ error: error.message }, 'Failed to open Simulator app');
    }
  }

  /**
   * Ensures a simulator is booted for the given platform and device
   * Returns the booted device ID (UDID)
   */
  async ensureBooted(platform: string, deviceId?: string): Promise<string> {
    if (!deviceId) {
      // No specific device requested, use first available
      return this.bootFirstAvailable(platform);
    }

    // Check if the device exists and get its state
    try {
      const { stdout } = await execAsync('xcrun simctl list devices --json');
      const data = JSON.parse(stdout);
      
      // Collect all matching devices first, then pick the best one
      const matchingDevices: any[] = [];
      
      for (const deviceList of Object.values(data.devices)) {
        for (const device of deviceList as any[]) {
          if (device.udid === deviceId || device.name === deviceId) {
            matchingDevices.push(device);
          }
        }
      }
      
      if (matchingDevices.length === 0) {
        throw new Error(`Device '${deviceId}' not found`);
      }
      
      // Sort devices: prefer available ones, then already booted ones
      matchingDevices.sort((a, b) => {
        // First priority: available devices
        if (a.isAvailable && !b.isAvailable) return -1;
        if (!a.isAvailable && b.isAvailable) return 1;
        // Second priority: booted devices
        if (a.state === 'Booted' && b.state !== 'Booted') return -1;
        if (a.state !== 'Booted' && b.state === 'Booted') return 1;
        return 0;
      });
      
      // Use the best matching device
      const device = matchingDevices[0];
      
      if (!device.isAvailable) {
        // All matching devices are unavailable
        const availableErrors = matchingDevices
          .map(d => `${d.name} (${d.udid}): ${d.availabilityError || 'unavailable'}`)
          .join(', ');
        throw new Error(`All devices named '${deviceId}' are unavailable: ${availableErrors}`);
      }
      
      if (device.state === 'Booted') {
        logger.debug({ deviceId: device.udid, name: device.name }, 'Device already booted');
        // Still open the Simulator app to make it visible
        await this.openSimulatorApp();
        return device.udid;
      }
      
      // Boot the device
      logger.info({ deviceId: device.udid, name: device.name }, 'Booting simulator');
      try {
        await execAsync(`xcrun simctl boot "${device.udid}"`);
      } catch (error: any) {
        // Device might already be booted
        if (!error.message?.includes('Unable to boot device in current state: Booted')) {
          throw error;
        }
      }
      
      // Open the Simulator app to show the GUI
      await this.openSimulatorApp();
      
      return device.udid;
    } catch (error: any) {
      logger.error({ error: error.message, deviceId }, 'Failed to boot simulator');
      throw new Error(`Failed to boot simulator: ${error.message}`);
    }
  }

  /**
   * Boots the first available simulator for a platform
   */
  private async bootFirstAvailable(platform: string): Promise<string> {
    try {
      const { stdout } = await execAsync('xcrun simctl list devices --json');
      const data = JSON.parse(stdout);
      
      // Find first available device for the platform
      for (const [runtime, deviceList] of Object.entries(data.devices)) {
        const runtimeLower = runtime.toLowerCase();
        const platformLower = platform.toLowerCase();
        
        // Handle visionOS which is internally called xrOS
        const isVisionOS = platformLower === 'visionos' && runtimeLower.includes('xros');
        const isOtherPlatform = platformLower !== 'visionos' && runtimeLower.includes(platformLower);
        
        if (!isVisionOS && !isOtherPlatform) {
          continue;
        }
        
        for (const device of deviceList as any[]) {
          if (!device.isAvailable) continue;
          
          // Check if already booted
          if (device.state === 'Booted') {
            logger.debug({ deviceId: device.udid, name: device.name }, 'Using already booted device');
            // Still open the Simulator app to make it visible
            await this.openSimulatorApp();
            return device.udid;
          }
          
          // Boot this device
          logger.info({ deviceId: device.udid, name: device.name }, 'Booting first available simulator');
          try {
            await execAsync(`xcrun simctl boot ${device.udid}`);
          } catch (error: any) {
            // Device might already be booted
            if (!error.message?.includes('Unable to boot device in current state: Booted')) {
              throw error;
            }
          }
          
          // Open the Simulator app to show the GUI
          await this.openSimulatorApp();
          
          return device.udid;
        }
      }
      
      throw new Error(`No available simulators found for platform ${platform}`);
    } catch (error: any) {
      logger.error({ error: error.message, platform }, 'Failed to boot simulator');
      throw new Error(`Failed to boot simulator: ${error.message}`);
    }
  }
}
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/unit/BootSimulatorUseCase.unit.test.ts:
--------------------------------------------------------------------------------

```typescript
import { describe, it, expect, jest, beforeEach } from '@jest/globals';
import { BootSimulatorUseCase } from '../../use-cases/BootSimulatorUseCase.js';
import { BootRequest } from '../../domain/BootRequest.js';
import { DeviceId } from '../../../../shared/domain/DeviceId.js';
import { BootResult, BootOutcome, SimulatorNotFoundError, BootCommandFailedError, SimulatorBusyError } from '../../domain/BootResult.js';
import { SimulatorState } from '../../domain/SimulatorState.js';
import { ISimulatorLocator, ISimulatorControl, SimulatorInfo } from '../../../../application/ports/SimulatorPorts.js';

describe('BootSimulatorUseCase', () => {
  let useCase: BootSimulatorUseCase;
  let mockLocator: jest.Mocked<ISimulatorLocator>;
  let mockControl: jest.Mocked<ISimulatorControl>;

  beforeEach(() => {
    jest.clearAllMocks();
    
    mockLocator = {
      findSimulator: jest.fn<ISimulatorLocator['findSimulator']>(),
      findBootedSimulator: jest.fn<ISimulatorLocator['findBootedSimulator']>()
    };
    
    mockControl = {
      boot: jest.fn<ISimulatorControl['boot']>(),
      shutdown: jest.fn<ISimulatorControl['shutdown']>()
    };
    
    useCase = new BootSimulatorUseCase(mockLocator, mockControl);
  });

  describe('execute', () => {
    it('should boot a shutdown simulator', async () => {
      // Arrange
      const request = BootRequest.create(DeviceId.create('iPhone-15'));
      const simulatorInfo: SimulatorInfo = {
        id: 'ABC123',
        name: 'iPhone 15',
        state: SimulatorState.Shutdown,
        platform: 'iOS',
        runtime: 'iOS-17.0'
      };
      
      mockLocator.findSimulator.mockResolvedValue(simulatorInfo);
      mockControl.boot.mockResolvedValue(undefined);

      // Act
      const result = await useCase.execute(request);

      // Assert
      expect(mockLocator.findSimulator).toHaveBeenCalledWith('iPhone-15');
      expect(mockControl.boot).toHaveBeenCalledWith('ABC123');
      expect(result.outcome).toBe(BootOutcome.Booted);
      expect(result.diagnostics.simulatorId).toBe('ABC123');
      expect(result.diagnostics.simulatorName).toBe('iPhone 15');
      expect(result.diagnostics.platform).toBe('iOS');
      expect(result.diagnostics.runtime).toBe('iOS-17.0');
    });

    it('should handle already booted simulator', async () => {
      // Arrange
      const request = BootRequest.create(DeviceId.create('iPhone-15'));
      const simulatorInfo: SimulatorInfo = {
        id: 'ABC123',
        name: 'iPhone 15',
        state: SimulatorState.Booted,
        platform: 'iOS',
        runtime: 'iOS-17.0'
      };
      
      mockLocator.findSimulator.mockResolvedValue(simulatorInfo);

      // Act
      const result = await useCase.execute(request);

      // Assert
      expect(mockControl.boot).not.toHaveBeenCalled();
      expect(result.outcome).toBe(BootOutcome.AlreadyBooted);
      expect(result.diagnostics.simulatorId).toBe('ABC123');
    });

    it('should return failure when simulator not found', async () => {
      // Arrange
      const request = BootRequest.create(DeviceId.create('non-existent'));
      mockLocator.findSimulator.mockResolvedValue(null);

      // Act
      const result = await useCase.execute(request);
      
      // Assert - Test behavior: simulator not found error
      expect(mockControl.boot).not.toHaveBeenCalled();
      expect(result.outcome).toBe(BootOutcome.Failed);
      expect(result.diagnostics.error).toBeInstanceOf(SimulatorNotFoundError);
      expect((result.diagnostics.error as SimulatorNotFoundError).deviceId).toBe('non-existent');
    });

    it('should return failure on boot error', async () => {
      // Arrange
      const request = BootRequest.create(DeviceId.create('iPhone-15'));
      const simulatorInfo: SimulatorInfo = {
        id: 'ABC123',
        name: 'iPhone 15',
        state: SimulatorState.Shutdown,
        platform: 'iOS',
        runtime: 'iOS-17.0'
      };
      
      mockLocator.findSimulator.mockResolvedValue(simulatorInfo);
      mockControl.boot.mockRejectedValue(new Error('Boot failed'));

      // Act
      const result = await useCase.execute(request);

      // Assert - Test behavior: boot command failed error
      expect(result.outcome).toBe(BootOutcome.Failed);
      expect(result.diagnostics.error).toBeInstanceOf(BootCommandFailedError);
      expect((result.diagnostics.error as BootCommandFailedError).stderr).toBe('Boot failed');
    });

    it('should boot simulator found by UUID', async () => {
      // Arrange
      const uuid = '838C707D-5703-4AEE-AF43-4798E0BA1B05';
      const request = BootRequest.create(DeviceId.create(uuid));
      const simulatorInfo: SimulatorInfo = {
        id: uuid,
        name: 'iPhone 15',
        state: SimulatorState.Shutdown,
        platform: 'iOS',
        runtime: 'iOS-17.0'
      };
      
      mockLocator.findSimulator.mockResolvedValue(simulatorInfo);
      mockControl.boot.mockResolvedValue(undefined);

      // Act
      const result = await useCase.execute(request);

      // Assert
      expect(mockLocator.findSimulator).toHaveBeenCalledWith(uuid);
      expect(mockControl.boot).toHaveBeenCalledWith(uuid);
      expect(result.outcome).toBe(BootOutcome.Booted);
      expect(result.diagnostics.simulatorId).toBe(uuid);
    });

    it('should handle simulator in Booting state as already booted', async () => {
      // Arrange
      const request = BootRequest.create(DeviceId.create('iPhone-15'));
      const simulatorInfo: SimulatorInfo = {
        id: 'ABC123',
        name: 'iPhone 15',
        state: SimulatorState.Booting,
        platform: 'iOS',
        runtime: 'iOS-17.0'
      };
      
      mockLocator.findSimulator.mockResolvedValue(simulatorInfo);

      // Act
      const result = await useCase.execute(request);

      // Assert
      expect(mockControl.boot).not.toHaveBeenCalled();
      expect(result.outcome).toBe(BootOutcome.AlreadyBooted);
      expect(result.diagnostics.simulatorId).toBe('ABC123');
      expect(result.diagnostics.simulatorName).toBe('iPhone 15');
    });

    it('should return failure when simulator is ShuttingDown', async () => {
      // Arrange
      const request = BootRequest.create(DeviceId.create('iPhone-15'));
      const simulatorInfo: SimulatorInfo = {
        id: 'ABC123',
        name: 'iPhone 15',
        state: SimulatorState.ShuttingDown,
        platform: 'iOS',
        runtime: 'iOS-17.0'
      };
      
      mockLocator.findSimulator.mockResolvedValue(simulatorInfo);

      // Act
      const result = await useCase.execute(request);

      // Assert
      expect(mockControl.boot).not.toHaveBeenCalled();
      expect(result.outcome).toBe(BootOutcome.Failed);
      expect(result.diagnostics.error).toBeInstanceOf(SimulatorBusyError);
      expect((result.diagnostics.error as SimulatorBusyError).currentState).toBe(SimulatorState.ShuttingDown);
      expect(result.diagnostics.simulatorId).toBe('ABC123');
      expect(result.diagnostics.simulatorName).toBe('iPhone 15');
    });

  });
});
```

--------------------------------------------------------------------------------
/src/features/simulator/tests/e2e/ListSimulatorsController.e2e.test.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * E2E Test for ListSimulatorsController
 *
 * Tests CRITICAL USER PATH with REAL simulators:
 * - Can the controller actually list real simulators?
 * - Does filtering work with real simulator data?
 * - Does error handling work with real failures?
 *
 * NO MOCKS - uses real simulators
 * This is an E2E test (10% of test suite) for critical user journeys
 *
 * NOTE: This test requires Xcode and iOS simulators to be installed
 */

import { describe, it, expect, beforeAll, beforeEach } from '@jest/globals';
import { MCPController } from '../../../../presentation/interfaces/MCPController.js';
import { ListSimulatorsControllerFactory } from '../../factories/ListSimulatorsControllerFactory.js';
import { exec } from 'child_process';
import { promisify } from 'util';

const execAsync = promisify(exec);

describe('ListSimulatorsController E2E', () => {
  let controller: MCPController;

  beforeAll(() => {
    controller = ListSimulatorsControllerFactory.create();
  });

  describe('list real simulators', () => {
    it('should list all available simulators', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({});

      expect(result).toMatchObject({
        content: expect.arrayContaining([
          expect.objectContaining({
            type: 'text',
            text: expect.any(String)
          })
        ])
      });

      const text = result.content[0].text;
      expect(text).toMatch(/Found \d+ simulator/);

      // Verify actual device lines exist
      const deviceLines = text.split('\n').filter((line: string) =>
        line.includes('(') && line.includes(')') && line.includes('-')
      );
      expect(deviceLines.length).toBeGreaterThan(0);
    });

    it('should filter by iOS platform', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({ platform: 'iOS' });

      const text = result.content[0].text;
      expect(text).toMatch(/Found \d+ simulator/);

      const deviceLines = text.split('\n').filter((line: string) =>
        line.includes('(') && line.includes(')') && line.includes('-')
      );

      expect(deviceLines.length).toBeGreaterThan(0);
      for (const line of deviceLines) {
        // All devices should show iOS runtime since we filtered by iOS platform
        expect(line).toContain(' - iOS ');
        // Should not contain other platform devices
        expect(line).not.toMatch(/Apple TV|Apple Watch/);
      }
    });

    it('should filter by booted state', async () => {
      // First, check if there are any booted simulators
      const checkResult = await execAsync('xcrun simctl list devices booted --json');
      const bootedDevices = JSON.parse(checkResult.stdout);
      const hasBootedDevices = Object.values(bootedDevices.devices).some(
        (devices: any) => devices.length > 0
      );

      // Act
      const result = await controller.execute({ state: 'Booted' });

      // Assert
      const text = result.content[0].text;

      if (hasBootedDevices) {
        expect(text).toMatch(/Found \d+ simulator/);
        const lines = text.split('\n');
        const deviceLines = lines.filter((line: string) =>
          line.includes('(') && line.includes(')') && line.includes('-')
        );

        for (const line of deviceLines) {
          expect(line).toContain('Booted');
        }
      } else {
        expect(text).toBe('🔍 No simulators found');
      }
    });

    it('should show runtime information', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({});

      const text = result.content[0].text;
      expect(text).toMatch(/Found \d+ simulator/);

      const deviceLines = text.split('\n').filter((line: string) =>
        line.includes('(') && line.includes(')') && line.includes('-')
      );

      expect(deviceLines.length).toBeGreaterThan(0);
      for (const line of deviceLines) {
        expect(line).toMatch(/iOS \d+\.\d+|tvOS \d+\.\d+|watchOS \d+\.\d+|visionOS \d+\.\d+/);
      }
    });

    it('should filter by tvOS platform', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({ platform: 'tvOS' });

      const text = result.content[0].text;

      // tvOS simulators might not exist in all environments
      if (text.includes('No simulators found')) {
        expect(text).toBe('🔍 No simulators found');
      } else {
        expect(text).toMatch(/Found \d+ simulator/);
        const deviceLines = text.split('\n').filter((line: string) =>
          line.includes('(') && line.includes(')') && line.includes('-')
        );

        for (const line of deviceLines) {
          expect(line).toContain('Apple TV');
          expect(line).toContain(' - tvOS ');
        }
      }
    });

    it('should handle combined filters', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({
        platform: 'iOS',
        state: 'Shutdown'
      });

      const text = result.content[0].text;
      expect(text).toMatch(/Found \d+ simulator/);

      const deviceLines = text.split('\n').filter((line: string) =>
        line.includes('(') && line.includes(')') && line.includes('-')
      );

      expect(deviceLines.length).toBeGreaterThan(0);
      for (const line of deviceLines) {
        expect(line).toContain(' - iOS ');
        expect(line).toContain('Shutdown');
      }
    });
  });

  describe('error handling', () => {
    it('should return error for invalid platform', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({
        platform: 'Android'
      });

      expect(result.content[0].text).toBe('❌ Invalid platform: Android. Valid values are: iOS, macOS, tvOS, watchOS, visionOS');
    });

    it('should return error for invalid state', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({
        state: 'Running'
      });

      expect(result.content[0].text).toBe('❌ Invalid simulator state: Running. Valid values are: Booted, Booting, Shutdown, Shutting Down');
    });

    it('should return error for invalid input types', async () => {
      // Arrange, Act, Assert
      const result1 = await controller.execute({
        platform: 123
      });

      expect(result1.content[0].text).toBe('❌ Platform must be a string (one of: iOS, macOS, tvOS, watchOS, visionOS), got number');

      const result2 = await controller.execute({
        state: true
      });

      expect(result2.content[0].text).toBe('❌ Simulator state must be a string (one of: Booted, Booting, Shutdown, Shutting Down), got boolean');
    });
  });

  describe('output formatting', () => {
    it('should format simulator list properly', async () => {
      // Arrange, Act, Assert
      const result = await controller.execute({});

      const text = result.content[0].text;
      expect(text).toMatch(/^✅ Found \d+ simulator/);

      const lines = text.split('\n');
      expect(lines[0]).toMatch(/^✅ Found \d+ simulator/);
      expect(lines[1]).toBe('');

      const deviceLines = lines.filter((line: string) =>
        line.includes('(') && line.includes(')') && line.includes('-')
      );

      expect(deviceLines.length).toBeGreaterThan(0);
      for (const line of deviceLines) {
        expect(line).toMatch(/^• .+ \([A-F0-9-]+\) - (Booted|Booting|Shutdown|Shutting Down|Unknown) - (iOS|tvOS|watchOS|visionOS|macOS|Unknown) \d+\.\d+$/);
      }
    });

    it('should use warning emoji for no results', async () => {
      // Act - filter that likely returns no results
      const result = await controller.execute({
        platform: 'visionOS',
        state: 'Booted'
      });

      // Assert
      const text = result.content[0].text;

      if (text.includes('No simulators found')) {
        expect(text).toBe('🔍 No simulators found');
      }
    });
  });
});
```

--------------------------------------------------------------------------------
/src/utils/errors/xcbeautify-parser.ts:
--------------------------------------------------------------------------------

```typescript
/**
 * Unified parser for xcbeautify output
 * 
 * This replaces all the complex parsers and handlers since all our output
 * goes through xcbeautify which already formats it nicely.
 * 
 * xcbeautify output format:
 * - ❌ for errors
 * - ⚠️ for warnings
 * - ✔ for test passes
 * - ✖ for test failures
 */

import { createModuleLogger } from '../../logger.js';

const logger = createModuleLogger('XcbeautifyParser');

export interface Issue {
  type: 'error' | 'warning';
  file?: string;
  line?: number;
  column?: number;
  message: string;
  rawLine: string;
}

export interface Test {
  name: string;
  passed: boolean;
  duration?: number;
  failureReason?: string;
}

export interface XcbeautifyOutput {
  errors: Issue[];
  warnings: Issue[];
  tests: Test[];
  buildSucceeded: boolean;
  testsPassed: boolean;
  totalTests: number;
  failedTests: number;
}


/**
 * Parse a line with error or warning from xcbeautify
 */
function parseErrorLine(line: string, isError: boolean): Issue {
  // Remove the emoji prefix (❌ or ⚠️) and any color codes
  const cleanLine = line
    .replace(/^[❌⚠]\s*/, '')  // Character class with individual emojis
    .replace(/^️\s*/, '')       // Remove any lingering emoji variation selectors
    .replace(/\x1b\[[0-9;]*m/g, ''); // Remove ANSI color codes
  
  // Try to extract file:line:column information
  // Format: /path/to/file.swift:10:15: error message
  const fileMatch = cleanLine.match(/^([^:]+):(\d+):(\d+):\s*(.*)$/);
  
  if (fileMatch) {
    const [, file, lineStr, columnStr, message] = fileMatch;
    
    return {
      type: isError ? 'error' : 'warning',
      file,
      line: parseInt(lineStr, 10),
      column: parseInt(columnStr, 10),
      message,
      rawLine: line
    };
  }
  
  // No file information
  return {
    type: isError ? 'error' : 'warning',
    message: cleanLine,
    rawLine: line
  };
}

/**
 * Parse test results from xcbeautify output
 */
function parseTestLine(line: string): Test | null {
  // Remove color codes
  const cleanLine = line.replace(/\x1b\[[0-9;]*m/g, '');
  
  // Test passed: ✔ testName (0.123 seconds)
  const passMatch = cleanLine.match(/✔\s+(\w+)\s*\(([0-9.]+)\s+seconds?\)/);
  if (passMatch) {
    return {
      name: passMatch[1],
      passed: true,
      duration: parseFloat(passMatch[2])
    };
  }
  
  // Test failed: ✖ testName, failure reason
  const failMatch = cleanLine.match(/✖\s+(\w+)(?:,\s*(.*))?/);
  if (failMatch) {
    return {
      name: failMatch[1],
      passed: false,
      failureReason: failMatch[2] || 'Test failed'
    };
  }
  
  // XCTest format: Test Case '-[ClassName testName]' passed/failed (X.XXX seconds)
  const xcTestMatch = cleanLine.match(/Test Case\s+'-\[(\w+)\s+(\w+)\]'\s+(passed|failed)\s*\(([0-9.]+)\s+seconds\)/);
  if (xcTestMatch) {
    return {
      name: `${xcTestMatch[1]}.${xcTestMatch[2]}`,
      passed: xcTestMatch[3] === 'passed',
      duration: parseFloat(xcTestMatch[4])
    };
  }
  
  return null;
}

/**
 * Main parser for xcbeautify output
 */
export function parseXcbeautifyOutput(output: string): XcbeautifyOutput {
  const lines = output.split('\n');
  
  // Use Maps to deduplicate errors/warnings (for multi-architecture builds)
  const errorMap = new Map<string, Issue>();
  const warningMap = new Map<string, Issue>();
  
  let buildSucceeded = true;
  let testsPassed = true;
  let totalTests = 0;
  let failedTests = 0;
  const tests: Test[] = [];
  
  for (const line of lines) {
    if (!line.trim()) continue;
    
    // Skip xcbeautify header
    if (line.includes('xcbeautify') || line.startsWith('---') || line.startsWith('Version:')) {
      continue;
    }
    
    // Parse errors (❌)
    if (line.includes('❌')) {
      const error = parseErrorLine(line, true);
      const key = `${error.file}:${error.line}:${error.column}:${error.message}`;
      errorMap.set(key, error);
      buildSucceeded = false;
    }
    // Parse warnings (⚠️)
    else if (line.includes('⚠️')) {
      const warning = parseErrorLine(line, false);
      const key = `${warning.file}:${warning.line}:${warning.column}:${warning.message}`;
      warningMap.set(key, warning);
    }
    // Parse test results (✔ or ✖)
    else if (line.includes('✔') || line.includes('✖')) {
      const test = parseTestLine(line);
      if (test) {
        tests.push(test);
        totalTests++;
        if (!test.passed) {
          failedTests++;
          testsPassed = false;
        }
      }
    }
    // Check for build/test failure indicators
    else if (line.includes('** BUILD FAILED **') || line.includes('BUILD FAILED')) {
      buildSucceeded = false;
    }
    else if (line.includes('** TEST FAILED **') || line.includes('TEST FAILED')) {
      testsPassed = false;
    }
    // Parse test summary: "Executed X tests, with Y failures"
    else if (line.includes('Executed') && line.includes('test')) {
      const summaryMatch = line.match(/Executed\s+(\d+)\s+tests?,\s+with\s+(\d+)\s+failures?/);
      if (summaryMatch) {
        totalTests = parseInt(summaryMatch[1], 10);
        failedTests = parseInt(summaryMatch[2], 10);
        testsPassed = failedTests === 0;
      }
    }
  }
  
  // Convert Maps to arrays
  const result: XcbeautifyOutput = {
    errors: Array.from(errorMap.values()),
    warnings: Array.from(warningMap.values()),
    tests,
    buildSucceeded,
    testsPassed,
    totalTests,
    failedTests
  };
  
  // Log summary
  logger.debug({
    errors: result.errors.length,
    warnings: result.warnings.length,
    tests: result.tests.length,
    buildSucceeded: result.buildSucceeded,
    testsPassed: result.testsPassed
  }, 'Parsed xcbeautify output');
  
  return result;
}

/**
 * Format parsed output for display
 */
export function formatParsedOutput(parsed: XcbeautifyOutput): string {
  const lines: string[] = [];
  
  // Build status
  if (!parsed.buildSucceeded) {
    lines.push(`❌ Build failed with ${parsed.errors.length} error${parsed.errors.length !== 1 ? 's' : ''}`);
  } else if (parsed.errors.length === 0 && parsed.warnings.length === 0) {
    lines.push('✅ Build succeeded');
  } else {
    lines.push(`⚠️ Build succeeded with ${parsed.warnings.length} warning${parsed.warnings.length !== 1 ? 's' : ''}`);
  }
  
  // Errors
  if (parsed.errors.length > 0) {
    lines.push('\nErrors:');
    for (const error of parsed.errors.slice(0, 10)) { // Show first 10
      if (error.file) {
        lines.push(`  ❌ ${error.file}:${error.line}:${error.column} - ${error.message}`);
      } else {
        lines.push(`  ❌ ${error.message}`);
      }
    }
    if (parsed.errors.length > 10) {
      lines.push(`  ... and ${parsed.errors.length - 10} more errors`);
    }
  }
  
  // Warnings (only show if no errors)
  if (parsed.errors.length === 0 && parsed.warnings.length > 0) {
    lines.push('\nWarnings:');
    for (const warning of parsed.warnings.slice(0, 5)) { // Show first 5
      if (warning.file) {
        lines.push(`  ⚠️ ${warning.file}:${warning.line}:${warning.column} - ${warning.message}`);
      } else {
        lines.push(`  ⚠️ ${warning.message}`);
      }
    }
    if (parsed.warnings.length > 5) {
      lines.push(`  ... and ${parsed.warnings.length - 5} more warnings`);
    }
  }
  
  // Test results
  if (parsed.tests.length > 0) {
    lines.push('\nTest Results:');
    if (parsed.testsPassed) {
      lines.push(`  ✅ All ${parsed.totalTests} tests passed`);
    } else {
      lines.push(`  ❌ ${parsed.failedTests} of ${parsed.totalTests} tests failed`);
      
      // Show failed tests
      const failedTests = parsed.tests.filter(t => !t.passed);
      for (const test of failedTests.slice(0, 5)) {
        lines.push(`    ✖ ${test.name}: ${test.failureReason || 'Failed'}`);
      }
      if (failedTests.length > 5) {
        lines.push(`    ... and ${failedTests.length - 5} more failures`);
      }
    }
  }
  
  return lines.join('\n');
}
```
Page 2/4FirstPrevNextLast