diff --git a/CHANGELOG.md b/CHANGELOG.md index f657851a..df9ab201 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,10 @@ - Added `xcodebuildmcp upgrade` command to check for updates and upgrade in place. Supports `--check` (report-only) and `--yes`/`-y` (skip confirmation). Detects install method (Homebrew, npm-global, npx) and queries the appropriate channel source (`brew info`, `npm view`, or GitHub Releases) for the latest version. Non-interactive environments exit 1 when an auto-upgrade is possible but `--yes` was not supplied. +### Changed + +- Auto-scope DerivedData per workspace/project path at xcodebuild invocation time when no explicit `derivedDataPath` is configured. Session defaults remain raw, while build/test/app-path commands derive a stable hashed subdirectory under the global DerivedData root from the resolved workspace or project path. Explicit `derivedDataPath` still takes precedence ([#340](https://github.com/getsentry/XcodeBuildMCP/issues/340)). + ## [2.3.2] ### Fixed diff --git a/src/mcp/tools/device/__tests__/build_device.test.ts b/src/mcp/tools/device/__tests__/build_device.test.ts index 41b25741..26a2eb5a 100644 --- a/src/mcp/tools/device/__tests__/build_device.test.ts +++ b/src/mcp/tools/device/__tests__/build_device.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import * as z from 'zod'; import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import { expectPendingBuildResponse, runToolLogic } from '../../../../test-utils/test-helpers.ts'; @@ -162,7 +162,7 @@ describe('build_device plugin', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ]); expect(spy.commandCalls[0].logPrefix).toBe('iOS Device Build'); @@ -196,7 +196,7 @@ describe('build_device plugin', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcodeproj'), 'build', ]); expect(spy.commandCalls[0].logPrefix).toBe('iOS Device Build'); @@ -222,6 +222,30 @@ describe('build_device plugin', () => { expectPendingBuildResponse(result, 'get_device_app_path'); }); + it('should include explicit derivedDataPath in get_device_app_path next step', async () => { + const mockExecutor = createMockExecutor({ + success: true, + output: 'Build succeeded', + }); + + const { result } = await runToolLogic(() => + buildDeviceLogic( + { + projectPath: '/path/to/MyProject.xcodeproj', + scheme: 'MyScheme', + derivedDataPath: '/tmp/derived-data', + }, + mockExecutor, + ), + ); + + expect(result.isError()).toBeFalsy(); + expect(result.nextStepParams?.get_device_app_path).toEqual({ + scheme: 'MyScheme', + derivedDataPath: '/tmp/derived-data', + }); + }); + it('should return exact build failure response', async () => { const mockExecutor = createMockExecutor({ success: false, diff --git a/src/mcp/tools/device/__tests__/get_device_app_path.test.ts b/src/mcp/tools/device/__tests__/get_device_app_path.test.ts index acfde74e..f464bb4a 100644 --- a/src/mcp/tools/device/__tests__/get_device_app_path.test.ts +++ b/src/mcp/tools/device/__tests__/get_device_app_path.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import * as z from 'zod'; import { createMockCommandResponse, @@ -132,7 +132,7 @@ describe('get_device_app_path plugin', () => { '-destination', 'generic/platform=iOS', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), ], logPrefix: 'Get App Path', useShell: false, @@ -191,7 +191,7 @@ describe('get_device_app_path plugin', () => { '-destination', 'generic/platform=watchOS', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), ], logPrefix: 'Get App Path', useShell: false, @@ -249,7 +249,7 @@ describe('get_device_app_path plugin', () => { '-destination', 'generic/platform=iOS', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/workspace.xcworkspace'), ], logPrefix: 'Get App Path', useShell: false, @@ -341,6 +341,60 @@ describe('get_device_app_path plugin', () => { expect(result.nextStepParams).toBeUndefined(); }); + it('should use explicit derivedDataPath when resolving build settings', async () => { + const calls: Array<{ + args: string[]; + logPrefix?: string; + useShell?: boolean; + opts?: { cwd?: string }; + }> = []; + + const mockExecutor = ( + args: string[], + logPrefix?: string, + useShell?: boolean, + opts?: { cwd?: string }, + _detached?: boolean, + ) => { + calls.push({ args, logPrefix, useShell, opts }); + return Promise.resolve( + createMockCommandResponse({ + success: true, + output: + 'Build settings for scheme "MyScheme"\n\nBUILT_PRODUCTS_DIR = /path/to/build/Debug-iphoneos\nFULL_PRODUCT_NAME = MyApp.app\n', + error: undefined, + }), + ); + }; + + await runLogic(() => + get_device_app_pathLogic( + { + projectPath: '/path/to/project.xcodeproj', + scheme: 'MyScheme', + derivedDataPath: '/custom/DerivedData', + }, + mockExecutor, + ), + ); + + expect(calls).toHaveLength(1); + expect(calls[0].args).toEqual([ + 'xcodebuild', + '-showBuildSettings', + '-project', + '/path/to/project.xcodeproj', + '-scheme', + 'MyScheme', + '-configuration', + 'Debug', + '-destination', + 'generic/platform=iOS', + '-derivedDataPath', + '/custom/DerivedData', + ]); + }); + it('should include optional configuration parameter in command', async () => { const calls: Array<{ args: string[]; @@ -392,7 +446,7 @@ describe('get_device_app_path plugin', () => { '-destination', 'generic/platform=iOS', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), ], logPrefix: 'Get App Path', useShell: false, diff --git a/src/mcp/tools/device/__tests__/test_device.test.ts b/src/mcp/tools/device/__tests__/test_device.test.ts index a737ccf1..4f0d5093 100644 --- a/src/mcp/tools/device/__tests__/test_device.test.ts +++ b/src/mcp/tools/device/__tests__/test_device.test.ts @@ -1,6 +1,6 @@ import { describe, it, expect, beforeEach } from 'vitest'; import * as z from 'zod'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import { createMockExecutor, createMockFileSystemExecutor, @@ -164,7 +164,7 @@ describe('test_device plugin', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), 'test', ]); }); diff --git a/src/mcp/tools/device/build_device.ts b/src/mcp/tools/device/build_device.ts index d7f2bf09..90df80af 100644 --- a/src/mcp/tools/device/build_device.ts +++ b/src/mcp/tools/device/build_device.ts @@ -27,6 +27,7 @@ import { setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; import type { BuildInvocationRequest } from '../../../types/domain-fragments.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; function createBuildDeviceRequest(params: BuildDeviceParams): BuildInvocationRequest { @@ -34,6 +35,7 @@ function createBuildDeviceRequest(params: BuildDeviceParams): BuildInvocationReq scheme: params.scheme, workspacePath: params.workspacePath, projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration: params.configuration ?? 'Debug', platform: 'iOS', target: 'device', @@ -121,6 +123,9 @@ export async function buildDeviceLogic( ctx.nextStepParams = { get_device_app_path: { scheme: params.scheme, + ...(params.derivedDataPath !== undefined + ? { derivedDataPath: params.derivedDataPath } + : {}), }, }; } diff --git a/src/mcp/tools/device/build_run_device.ts b/src/mcp/tools/device/build_run_device.ts index 6fc9eb59..5f1d60c5 100644 --- a/src/mcp/tools/device/build_run_device.ts +++ b/src/mcp/tools/device/build_run_device.ts @@ -34,6 +34,7 @@ import { createDomainStreamingPipeline, setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; function createBuildRunDeviceRequest(params: BuildRunDeviceParams): BuildInvocationRequest { @@ -41,6 +42,7 @@ function createBuildRunDeviceRequest(params: BuildRunDeviceParams): BuildInvocat scheme: params.scheme, workspacePath: params.workspacePath, projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration: params.configuration ?? 'Debug', platform: String(mapDevicePlatform(params.platform)), deviceId: params.deviceId, diff --git a/src/mcp/tools/device/get_device_app_path.ts b/src/mcp/tools/device/get_device_app_path.ts index 6dfe9345..71ea216e 100644 --- a/src/mcp/tools/device/get_device_app_path.ts +++ b/src/mcp/tools/device/get_device_app_path.ts @@ -32,6 +32,7 @@ import { const baseOptions = { scheme: z.string().describe('The scheme to use'), configuration: z.string().optional().describe('Build configuration (Debug, Release, etc.)'), + derivedDataPath: z.string().optional(), platform: z.enum(['iOS', 'watchOS', 'tvOS', 'visionOS']).optional().describe('default: iOS'), }; @@ -53,6 +54,7 @@ const publicSchemaObject = baseSchemaObject.omit({ workspacePath: true, scheme: true, configuration: true, + derivedDataPath: true, platform: true, } as const); @@ -83,6 +85,7 @@ export function createGetDeviceAppPathExecutor( scheme: params.scheme, configuration, platform, + derivedDataPath: params.derivedDataPath, }, executor, ); diff --git a/src/mcp/tools/device/test_device.ts b/src/mcp/tools/device/test_device.ts index e41879f6..cdcfe1e2 100644 --- a/src/mcp/tools/device/test_device.ts +++ b/src/mcp/tools/device/test_device.ts @@ -28,6 +28,7 @@ import { setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; import type { BuildInvocationRequest } from '../../../types/domain-fragments.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; const baseSchemaObject = z.object({ @@ -102,6 +103,9 @@ async function prepareTestDeviceExecution( preflight: preflight ?? undefined, invocationRequest: { scheme: params.scheme, + workspacePath: params.workspacePath, + projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration, platform: String(platform), deviceId: params.deviceId, diff --git a/src/mcp/tools/macos/__tests__/build_macos.test.ts b/src/mcp/tools/macos/__tests__/build_macos.test.ts index fee50aee..002f3be3 100644 --- a/src/mcp/tools/macos/__tests__/build_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/build_macos.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import * as z from 'zod'; import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; import { expectPendingBuildResponse, runToolLogic } from '../../../../test-utils/test-helpers.ts'; @@ -205,7 +205,7 @@ describe('build_macos plugin', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), 'build', ]); }); @@ -303,7 +303,7 @@ describe('build_macos plugin', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), 'build', ]); }); @@ -333,7 +333,7 @@ describe('build_macos plugin', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/Users/dev/My Project/MyProject.xcodeproj'), 'build', ]); }); @@ -363,7 +363,7 @@ describe('build_macos plugin', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/workspace.xcworkspace'), 'build', ]); }); diff --git a/src/mcp/tools/macos/__tests__/build_run_macos.test.ts b/src/mcp/tools/macos/__tests__/build_run_macos.test.ts index e846d805..de8c1a17 100644 --- a/src/mcp/tools/macos/__tests__/build_run_macos.test.ts +++ b/src/mcp/tools/macos/__tests__/build_run_macos.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import * as z from 'zod'; import { createMockExecutor, mockProcess } from '../../../../test-utils/mock-executors.ts'; import { runToolLogic, type MockToolHandlerResult } from '../../../../test-utils/test-helpers.ts'; @@ -127,7 +127,7 @@ describe('build_run_macos', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), 'build', ]); expect(executorCalls[0].description).toBe('macOS Build'); @@ -195,7 +195,7 @@ describe('build_run_macos', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/workspace.xcworkspace'), 'build', ]); @@ -398,7 +398,7 @@ describe('build_run_macos', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/project.xcodeproj'), 'build', ]); expect(executorCalls[0].description).toBe('macOS Build'); diff --git a/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts b/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts index e8388a36..139e3c88 100644 --- a/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts +++ b/src/mcp/tools/macos/__tests__/get_mac_app_path.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import * as z from 'zod'; import { createMockCommandResponse, @@ -131,7 +131,7 @@ describe('get_mac_app_path plugin', () => { '-destination', 'generic/platform=macOS', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), ], 'Get App Path', false, @@ -173,7 +173,7 @@ describe('get_mac_app_path plugin', () => { '-destination', 'generic/platform=macOS', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcodeproj'), ], 'Get App Path', false, @@ -217,7 +217,7 @@ describe('get_mac_app_path plugin', () => { '-destination', 'platform=macOS,arch=arm64', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), ], 'Get App Path', false, @@ -261,7 +261,7 @@ describe('get_mac_app_path plugin', () => { '-destination', 'platform=macOS,arch=x86_64', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), ], 'Get App Path', false, @@ -350,7 +350,7 @@ describe('get_mac_app_path plugin', () => { '-destination', 'platform=macOS,arch=arm64', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), ], 'Get App Path', false, diff --git a/src/mcp/tools/macos/build_macos.ts b/src/mcp/tools/macos/build_macos.ts index 7170a62b..a9cdda1b 100644 --- a/src/mcp/tools/macos/build_macos.ts +++ b/src/mcp/tools/macos/build_macos.ts @@ -22,6 +22,7 @@ import { setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; import type { BuildInvocationRequest } from '../../../types/domain-fragments.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; function createBuildMacOSRequest(params: BuildMacOSParams): BuildInvocationRequest { @@ -29,6 +30,7 @@ function createBuildMacOSRequest(params: BuildMacOSParams): BuildInvocationReque scheme: params.scheme, workspacePath: params.workspacePath, projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration: params.configuration ?? 'Debug', platform: 'macOS', arch: params.arch, diff --git a/src/mcp/tools/macos/build_run_macos.ts b/src/mcp/tools/macos/build_run_macos.ts index 11619c41..01ca5324 100644 --- a/src/mcp/tools/macos/build_run_macos.ts +++ b/src/mcp/tools/macos/build_run_macos.ts @@ -23,6 +23,7 @@ import { setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; import type { BuildInvocationRequest } from '../../../types/domain-fragments.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; function createBuildRunMacOSRequest(params: BuildRunMacOSParams): BuildInvocationRequest { @@ -30,6 +31,7 @@ function createBuildRunMacOSRequest(params: BuildRunMacOSParams): BuildInvocatio scheme: params.scheme, workspacePath: params.workspacePath, projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration: params.configuration ?? 'Debug', platform: 'macOS', arch: params.arch, diff --git a/src/mcp/tools/macos/test_macos.ts b/src/mcp/tools/macos/test_macos.ts index 9b6d85bc..2338f831 100644 --- a/src/mcp/tools/macos/test_macos.ts +++ b/src/mcp/tools/macos/test_macos.ts @@ -28,6 +28,7 @@ import { setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; import type { BuildInvocationRequest } from '../../../types/domain-fragments.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; const baseSchemaObject = z.object({ @@ -92,6 +93,9 @@ async function prepareTestMacosExecution( preflight: preflight ?? undefined, invocationRequest: { scheme: params.scheme, + workspacePath: params.workspacePath, + projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration, platform: 'macOS', onlyTesting: preflight?.selectors.onlyTesting.map((selector) => selector.raw), diff --git a/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts b/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts index 3173fe5d..19effdf4 100644 --- a/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/build_run_sim.test.ts @@ -1,4 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; import * as z from 'zod'; import { @@ -370,7 +371,7 @@ describe('build_run_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ]); expect(callHistory[1].logPrefix).toBe('iOS Simulator Build'); @@ -429,7 +430,7 @@ describe('build_run_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ]); expect(callHistory[1].logPrefix).toBe('iOS Simulator Build'); @@ -496,7 +497,7 @@ describe('build_run_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ]); expect(callHistory[1].logPrefix).toBe('iOS Simulator Build'); @@ -512,7 +513,7 @@ describe('build_run_sim tool', () => { '-destination', 'platform=iOS Simulator,name=iPhone 17', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), ]); expect(callHistory[2].logPrefix).toBe('Get App Path'); }); @@ -545,7 +546,7 @@ describe('build_run_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/Users/dev/My Project/MyProject.xcworkspace'), 'build', ]); expect(callHistory[1].logPrefix).toBe('iOS Simulator Build'); @@ -579,7 +580,7 @@ describe('build_run_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ]); expect(callHistory[1].logPrefix).toBe('tvOS Simulator Build'); diff --git a/src/mcp/tools/simulator/__tests__/build_sim.test.ts b/src/mcp/tools/simulator/__tests__/build_sim.test.ts index f1c2edc9..684011d1 100644 --- a/src/mcp/tools/simulator/__tests__/build_sim.test.ts +++ b/src/mcp/tools/simulator/__tests__/build_sim.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import * as z from 'zod'; import { createMockExecutor, @@ -212,7 +212,7 @@ describe('build_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ], 'iOS Simulator Build', @@ -247,7 +247,7 @@ describe('build_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcodeproj'), 'build', ], 'iOS Simulator Build', @@ -322,7 +322,7 @@ describe('build_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/Users/dev/My Project/MyProject.xcworkspace'), 'build', ], 'iOS Simulator Build', @@ -358,7 +358,7 @@ describe('build_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ], 'iOS Simulator Build', @@ -393,7 +393,7 @@ describe('build_sim tool', () => { '-collect-test-diagnostics', 'never', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/MyProject.xcworkspace'), 'build', ], 'watchOS Simulator Build', @@ -437,6 +437,9 @@ describe('build_sim tool', () => { expect(result.isError()).toBeFalsy(); expectPendingBuildResponse(result, 'get_sim_app_path'); + expect(result.nextStepParams?.get_sim_app_path).toMatchObject({ + derivedDataPath: '/path/to/derived', + }); }); it('should handle build failure', async () => { diff --git a/src/mcp/tools/simulator/__tests__/get_sim_app_path.test.ts b/src/mcp/tools/simulator/__tests__/get_sim_app_path.test.ts index 36e44cf8..567c8bb8 100644 --- a/src/mcp/tools/simulator/__tests__/get_sim_app_path.test.ts +++ b/src/mcp/tools/simulator/__tests__/get_sim_app_path.test.ts @@ -1,5 +1,5 @@ import { describe, it, expect, beforeEach } from 'vitest'; -import { DERIVED_DATA_DIR } from '../../../../utils/log-paths.ts'; +import { computeScopedDerivedDataPath } from '../../../../utils/derived-data-path.ts'; import { ChildProcess } from 'child_process'; import * as z from 'zod'; import { createMockExecutor } from '../../../../test-utils/mock-executors.ts'; @@ -161,7 +161,7 @@ describe('get_sim_app_path tool', () => { '-destination', 'platform=iOS Simulator,name=iPhone 17,OS=latest', '-derivedDataPath', - DERIVED_DATA_DIR, + computeScopedDerivedDataPath('/path/to/workspace.xcworkspace'), ]); expect(result.isError).toBeFalsy(); @@ -171,6 +171,63 @@ describe('get_sim_app_path tool', () => { expect(result.nextStepParams).toBeDefined(); }); + it('should use explicit derivedDataPath when resolving build settings', async () => { + const callHistory: Array<{ + command: string[]; + logPrefix?: string; + useShell?: boolean; + opts?: unknown; + }> = []; + + const trackingExecutor: CommandExecutor = async ( + command, + logPrefix, + useShell, + opts, + ): Promise<{ + success: boolean; + output: string; + process: ChildProcess; + }> => { + callHistory.push({ command, logPrefix, useShell, opts }); + return { + success: true, + output: + ' BUILT_PRODUCTS_DIR = /tmp/DerivedData/Build\n FULL_PRODUCT_NAME = MyApp.app\n', + process: { pid: 12345 } as unknown as ChildProcess, + }; + }; + + await runLogic(() => + get_sim_app_pathLogic( + { + workspacePath: '/path/to/workspace.xcworkspace', + scheme: 'MyScheme', + platform: XcodePlatform.iOSSimulator, + simulatorName: 'iPhone 17', + derivedDataPath: '/custom/DerivedData', + }, + trackingExecutor, + ), + ); + + expect(callHistory).toHaveLength(1); + expect(callHistory[0].command).toEqual([ + 'xcodebuild', + '-showBuildSettings', + '-workspace', + '/path/to/workspace.xcworkspace', + '-scheme', + 'MyScheme', + '-configuration', + 'Debug', + '-destination', + 'platform=iOS Simulator,name=iPhone 17,OS=latest', + '-derivedDataPath', + '/custom/DerivedData', + ]); + }); + it('should surface executor failures when build settings cannot be retrieved', async () => { const mockExecutor = createMockExecutor({ success: false, diff --git a/src/mcp/tools/simulator/build_run_sim.ts b/src/mcp/tools/simulator/build_run_sim.ts index 1706c826..32207f93 100644 --- a/src/mcp/tools/simulator/build_run_sim.ts +++ b/src/mcp/tools/simulator/build_run_sim.ts @@ -47,6 +47,7 @@ import { createDomainStreamingPipeline, setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; const baseOptions = { @@ -157,6 +158,7 @@ async function prepareBuildRunSimExecution( scheme: params.scheme, workspacePath: params.workspacePath, projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration, platform: displayPlatform, simulatorName: params.simulatorName, @@ -505,6 +507,7 @@ export async function build_run_simLogic( scheme: params.scheme, workspacePath: params.workspacePath, projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration: params.configuration ?? 'Debug', platform: 'Simulator', simulatorName: params.simulatorName, diff --git a/src/mcp/tools/simulator/build_sim.ts b/src/mcp/tools/simulator/build_sim.ts index af39d087..5a6a02f0 100644 --- a/src/mcp/tools/simulator/build_sim.ts +++ b/src/mcp/tools/simulator/build_sim.ts @@ -33,6 +33,7 @@ import { setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; import type { BuildInvocationRequest } from '../../../types/domain-fragments.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; const baseOptions = { @@ -130,6 +131,7 @@ async function prepareBuildSimExecution( scheme: params.scheme, workspacePath: params.workspacePath, projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration, platform: detectedPlatform, simulatorName: params.simulatorName, @@ -216,6 +218,9 @@ export async function build_simLogic( : { simulatorName: params.simulatorName ?? '' }), scheme: params.scheme, platform: prepared.detectedPlatform, + ...(params.derivedDataPath !== undefined + ? { derivedDataPath: params.derivedDataPath } + : {}), }, }; } diff --git a/src/mcp/tools/simulator/get_sim_app_path.ts b/src/mcp/tools/simulator/get_sim_app_path.ts index 8ed69ef0..fc19eef8 100644 --- a/src/mcp/tools/simulator/get_sim_app_path.ts +++ b/src/mcp/tools/simulator/get_sim_app_path.ts @@ -66,6 +66,7 @@ const baseGetSimulatorAppPathSchema = z.object({ "Name of the simulator (e.g., 'iPhone 17'). Provide EITHER this OR simulatorId, not both", ), configuration: z.string().optional().describe('Build configuration (Debug, Release, etc.)'), + derivedDataPath: z.string().optional(), useLatestOS: z .boolean() .optional() @@ -121,6 +122,7 @@ export function createGetSimAppPathExecutor( configuration, platform: params.platform, destination, + derivedDataPath: params.derivedDataPath, }, executor, ); @@ -181,6 +183,7 @@ const publicSchemaObject = baseGetSimulatorAppPathSchema.omit({ simulatorId: true, simulatorName: true, configuration: true, + derivedDataPath: true, useLatestOS: true, } as const); diff --git a/src/mcp/tools/simulator/test_sim.ts b/src/mcp/tools/simulator/test_sim.ts index 14ac2598..f6d425cf 100644 --- a/src/mcp/tools/simulator/test_sim.ts +++ b/src/mcp/tools/simulator/test_sim.ts @@ -37,6 +37,7 @@ import { setXcodebuildStructuredOutput, } from '../../../utils/xcodebuild-domain-results.ts'; import type { BuildInvocationRequest } from '../../../types/domain-fragments.ts'; +import { resolveEffectiveDerivedDataPath } from '../../../utils/derived-data-path.ts'; import { createBuildInvocationFragment } from '../../../utils/xcodebuild-pipeline.ts'; const baseSchemaObject = z.object({ @@ -134,6 +135,9 @@ async function prepareTestSimExecution( resolutionError: simulatorResolution.error, invocationRequest: { scheme: params.scheme, + workspacePath: params.workspacePath, + projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration, platform: inferred.platform, simulatorName: params.simulatorName, @@ -166,6 +170,9 @@ async function prepareTestSimExecution( resolvedSimulatorId: simulatorResolution.simulatorId, invocationRequest: { scheme: params.scheme, + workspacePath: params.workspacePath, + projectPath: params.projectPath, + derivedDataPath: resolveEffectiveDerivedDataPath(params), configuration, platform: inferred.platform, simulatorName: params.simulatorName, diff --git a/src/snapshot-tests/__fixtures__/cli/device/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/device/build--error-wrong-scheme.txt index 20da1b1c..c4540858 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/build--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/build--error-wrong-scheme.txt @@ -5,7 +5,7 @@ Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/device/build--success.txt b/src/snapshot-tests/__fixtures__/cli/device/build--success.txt index 27282c0a..c0152748 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/build--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/build--success.txt @@ -5,7 +5,7 @@ Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ✅ Build succeeded. (⏱️ ) └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_device__pid.log diff --git a/src/snapshot-tests/__fixtures__/cli/device/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/device/build-and-run--error-wrong-scheme.txt index 37a0c499..30782a48 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/build-and-run--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/build-and-run--error-wrong-scheme.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/device/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/cli/device/build-and-run--success.txt index 5596f05f..8500d23e 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/build-and-run--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/build-and-run--success.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ℹ️ Resolving app path ✅ Resolving app path @@ -16,7 +16,7 @@ ✅ Build succeeded. (⏱️ ) ✅ Build & Run complete - ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app ├ Bundle ID: io.sentry.calculatorapp ├ Process ID: └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_device__pid.log diff --git a/src/snapshot-tests/__fixtures__/cli/device/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/cli/device/get-app-path--success.txt index ec3e9c0b..726fd48d 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/get-app-path--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/get-app-path--success.txt @@ -7,9 +7,9 @@ Platform: iOS ✅ Success - └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app Next steps: -1. Get bundle ID: xcodebuildmcp device get-app-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" -2. Install app on device: xcodebuildmcp device install --device-id "DEVICE_UDID" --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" +1. Get bundle ID: xcodebuildmcp device get-app-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app" +2. Install app on device: xcodebuildmcp device install --device-id "DEVICE_UDID" --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app" 3. Launch app on device: xcodebuildmcp device launch --device-id "DEVICE_UDID" --bundle-id "BUNDLE_ID" diff --git a/src/snapshot-tests/__fixtures__/cli/device/install--success.txt b/src/snapshot-tests/__fixtures__/cli/device/install--success.txt index c500efa9..cde00749 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/install--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/install--success.txt @@ -2,6 +2,6 @@ 📦 Install App Device: () - App: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + App: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app ✅ App installed successfully. diff --git a/src/snapshot-tests/__fixtures__/cli/device/test--failure.txt b/src/snapshot-tests/__fixtures__/cli/device/test--failure.txt index b3d3e4cc..26b0696d 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/test--failure.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/test--failure.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Discovered 52 test(s): CalculatorAppFeatureTests/CalculatorBasicTests/testClear diff --git a/src/snapshot-tests/__fixtures__/cli/device/test--success.txt b/src/snapshot-tests/__fixtures__/cli/device/test--success.txt index fdd54e05..8b015d22 100644 --- a/src/snapshot-tests/__fixtures__/cli/device/test--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/device/test--success.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Selective Testing: CalculatorAppTests/CalculatorAppTests/testAddition diff --git a/src/snapshot-tests/__fixtures__/cli/macos/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/macos/build--error-wrong-scheme.txt index b07b3c73..9f4f4df8 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/build--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/build--error-wrong-scheme.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/macos/build--success.txt b/src/snapshot-tests/__fixtures__/cli/macos/build--success.txt index 900053f5..e1ae3bb7 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/build--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/build--success.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- ✅ Build succeeded. (⏱️ ) ├ Bundle ID: io.sentry.MCPTest.macOS diff --git a/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--error-wrong-scheme.txt index a9e244cf..7f8dd625 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--error-wrong-scheme.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--success.txt index a5f031a5..5a7a9706 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/build-and-run--success.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- ℹ️ Resolving app path ✅ Resolving app path @@ -14,7 +14,7 @@ ✅ Build succeeded. (⏱️ ) ✅ Build & Run complete - ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app ├ Bundle ID: io.sentry.MCPTest.macOS ├ Process ID: └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/cli/macos/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/cli/macos/get-app-path--success.txt index 1ab2fb05..8f2802a7 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/get-app-path--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/get-app-path--success.txt @@ -7,8 +7,8 @@ Platform: macOS ✅ Success - └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app Next steps: -1. Get bundle ID: xcodebuildmcp macos get-macos-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app" -2. Launch app: xcodebuildmcp macos launch --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app" +1. Get bundle ID: xcodebuildmcp macos get-macos-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app" +2. Launch app: xcodebuildmcp macos launch --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app" diff --git a/src/snapshot-tests/__fixtures__/cli/macos/launch--success.txt b/src/snapshot-tests/__fixtures__/cli/macos/launch--success.txt index 4196864c..1fdb6327 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/launch--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/launch--success.txt @@ -1,7 +1,7 @@ 🚀 Launch macOS App - App: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + App: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app ✅ App launched successfully ├ Bundle ID: io.sentry.MCPTest.macOS diff --git a/src/snapshot-tests/__fixtures__/cli/macos/test--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/macos/test--error-wrong-scheme.txt index 94fa73ba..6e87d6c2 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/test--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/test--error-wrong-scheme.txt @@ -2,9 +2,10 @@ 🧪 Test Scheme: NONEXISTENT + Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/macos/test--failure.txt b/src/snapshot-tests/__fixtures__/cli/macos/test--failure.txt index 7f876426..e347f14d 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/test--failure.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/test--failure.txt @@ -2,9 +2,10 @@ 🧪 Test Scheme: MCPTest + Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Discovered 4 test(s): MCPTestTests/MCPTestTests/appNameIsCorrect @@ -15,12 +16,12 @@ Discovered 4 test(s): MCPTestsXCTests ✗ testDeliberateFailure(): - XCTAssertTrue failed - This test is designed to fail for snapshot testing - MCPTestsXCTests.swift:11 + example_projects/macOS/MCPTestTests/MCPTestsXCTests.swift:11 MCPTestTests ✗ deliberateFailure(): - Expectation failed: 1 == 2: This test is designed to fail for snapshot testing - MCPTestTests.swift:11 + example_projects/macOS/MCPTestTests/MCPTestTests.swift:11 ❌ tests failed, passed, skipped (⏱️ ) └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/test_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/cli/macos/test--success.txt b/src/snapshot-tests/__fixtures__/cli/macos/test--success.txt index 384ca1bf..877b5a9a 100644 --- a/src/snapshot-tests/__fixtures__/cli/macos/test--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/macos/test--success.txt @@ -2,9 +2,10 @@ 🧪 Test Scheme: MCPTest + Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Selective Testing: MCPTestTests/MCPTestTests/appNameIsCorrect() MCPTestTests/MCPTestsXCTests/testAppNameIsCorrect diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/simulator/build--error-wrong-scheme.txt index de358b6d..709a9457 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/build--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/build--error-wrong-scheme.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/build--success.txt b/src/snapshot-tests/__fixtures__/cli/simulator/build--success.txt index d48009f4..14ef1940 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/build--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/build--success.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ✅ Build succeeded. (⏱️ ) └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--error-wrong-scheme.txt index 13a8d794..17ba47c7 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--error-wrong-scheme.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--success.txt index 45af2222..b4e0d675 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/build-and-run--success.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ℹ️ Resolving app path ✅ Resolving app path @@ -18,7 +18,7 @@ ✅ Build succeeded. (⏱️ ) ✅ Build & Run complete - ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app ├ Bundle ID: io.sentry.calculatorapp ├ Process ID: ├ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/cli/simulator/get-app-path--success.txt index 24820d4d..68d67877 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/get-app-path--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/get-app-path--success.txt @@ -8,10 +8,10 @@ Simulator: iPhone 17 ✅ Get app path successful (⏱️ ) - └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app Next steps: -1. Get bundle ID: xcodebuildmcp device get-app-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" +1. Get bundle ID: xcodebuildmcp device get-app-bundle-id --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app" 2. Boot simulator: xcodebuildmcp simulator-management boot --simulator-id "SIMULATOR_UUID" -3. Install app: xcodebuildmcp simulator install --simulator-id "SIMULATOR_UUID" --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" +3. Install app: xcodebuildmcp simulator install --simulator-id "SIMULATOR_UUID" --app-path "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app" 4. Launch app: xcodebuildmcp simulator launch-app --simulator-id "SIMULATOR_UUID" --bundle-id "BUNDLE_ID" diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/install--success.txt b/src/snapshot-tests/__fixtures__/cli/simulator/install--success.txt index ad875981..cf62bfbb 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/install--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/install--success.txt @@ -2,7 +2,7 @@ 📦 Install App Simulator: - App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app ✅ App installed successfully diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/test--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/cli/simulator/test--error-wrong-scheme.txt index 50619e67..d4042880 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/test--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/test--error-wrong-scheme.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/test--failure.txt b/src/snapshot-tests/__fixtures__/cli/simulator/test--failure.txt index 9db430ad..4e335e68 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/test--failure.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/test--failure.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Discovered 52 test(s): CalculatorAppFeatureTests/CalculatorBasicTests/testClear diff --git a/src/snapshot-tests/__fixtures__/cli/simulator/test--success.txt b/src/snapshot-tests/__fixtures__/cli/simulator/test--success.txt index d0fb32a1..d1595548 100644 --- a/src/snapshot-tests/__fixtures__/cli/simulator/test--success.txt +++ b/src/snapshot-tests/__fixtures__/cli/simulator/test--success.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Selective Testing: CalculatorAppTests/CalculatorAppTests/testAddition diff --git a/src/snapshot-tests/__fixtures__/json/device/build--error-wrong-scheme.json b/src/snapshot-tests/__fixtures__/json/device/build--error-wrong-scheme.json index a84d194d..771bf4cf 100644 --- a/src/snapshot-tests/__fixtures__/json/device/build--error-wrong-scheme.json +++ b/src/snapshot-tests/__fixtures__/json/device/build--error-wrong-scheme.json @@ -7,6 +7,7 @@ "request": { "scheme": "NONEXISTENT", "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS", "target": "device" diff --git a/src/snapshot-tests/__fixtures__/json/device/build--success.json b/src/snapshot-tests/__fixtures__/json/device/build--success.json index 9c51a15c..f19d92d6 100644 --- a/src/snapshot-tests/__fixtures__/json/device/build--success.json +++ b/src/snapshot-tests/__fixtures__/json/device/build--success.json @@ -7,6 +7,7 @@ "request": { "scheme": "CalculatorApp", "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS", "target": "device" diff --git a/src/snapshot-tests/__fixtures__/json/device/build-and-run--success.json b/src/snapshot-tests/__fixtures__/json/device/build-and-run--success.json index a15960e9..287ecd4e 100644 --- a/src/snapshot-tests/__fixtures__/json/device/build-and-run--success.json +++ b/src/snapshot-tests/__fixtures__/json/device/build-and-run--success.json @@ -18,7 +18,7 @@ "target": "device" }, "artifacts": { - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app", + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app", "bundleId": "io.sentry.calculatorapp", "processId": 99999, "deviceId": "", diff --git a/src/snapshot-tests/__fixtures__/json/device/get-app-path--success.json b/src/snapshot-tests/__fixtures__/json/device/get-app-path--success.json index f988deb6..a50b34c7 100644 --- a/src/snapshot-tests/__fixtures__/json/device/get-app-path--success.json +++ b/src/snapshot-tests/__fixtures__/json/device/get-app-path--success.json @@ -15,7 +15,7 @@ "target": "device" }, "artifacts": { - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app" } } } diff --git a/src/snapshot-tests/__fixtures__/json/device/install--success.json b/src/snapshot-tests/__fixtures__/json/device/install--success.json index 33533b50..27f62c64 100644 --- a/src/snapshot-tests/__fixtures__/json/device/install--success.json +++ b/src/snapshot-tests/__fixtures__/json/device/install--success.json @@ -9,7 +9,7 @@ }, "artifacts": { "deviceId": "", - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app" }, "diagnostics": { "warnings": [], diff --git a/src/snapshot-tests/__fixtures__/json/macos/build--error-wrong-scheme.json b/src/snapshot-tests/__fixtures__/json/macos/build--error-wrong-scheme.json index 5cdb9114..da3d342e 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/build--error-wrong-scheme.json +++ b/src/snapshot-tests/__fixtures__/json/macos/build--error-wrong-scheme.json @@ -7,6 +7,7 @@ "request": { "scheme": "NONEXISTENT", "projectPath": "example_projects/macOS/MCPTest.xcodeproj", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-", "configuration": "Debug", "platform": "macOS", "target": "macos" diff --git a/src/snapshot-tests/__fixtures__/json/macos/build--success.json b/src/snapshot-tests/__fixtures__/json/macos/build--success.json index 04e0c8c0..4a8884ad 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/build--success.json +++ b/src/snapshot-tests/__fixtures__/json/macos/build--success.json @@ -7,6 +7,7 @@ "request": { "scheme": "MCPTest", "projectPath": "example_projects/macOS/MCPTest.xcodeproj", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-", "configuration": "Debug", "platform": "macOS", "target": "macos" diff --git a/src/snapshot-tests/__fixtures__/json/macos/build-and-run--error-wrong-scheme.json b/src/snapshot-tests/__fixtures__/json/macos/build-and-run--error-wrong-scheme.json index 945a7138..0fbdf21c 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/build-and-run--error-wrong-scheme.json +++ b/src/snapshot-tests/__fixtures__/json/macos/build-and-run--error-wrong-scheme.json @@ -7,6 +7,7 @@ "request": { "scheme": "NONEXISTENT", "projectPath": "example_projects/macOS/MCPTest.xcodeproj", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-", "configuration": "Debug", "platform": "macOS", "target": "macos" diff --git a/src/snapshot-tests/__fixtures__/json/macos/build-and-run--success.json b/src/snapshot-tests/__fixtures__/json/macos/build-and-run--success.json index c6ab2219..13517b4d 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/build-and-run--success.json +++ b/src/snapshot-tests/__fixtures__/json/macos/build-and-run--success.json @@ -7,6 +7,7 @@ "request": { "scheme": "MCPTest", "projectPath": "example_projects/macOS/MCPTest.xcodeproj", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-", "configuration": "Debug", "platform": "macOS", "target": "macos" @@ -17,7 +18,7 @@ "target": "macos" }, "artifacts": { - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app", + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app", "bundleId": "io.sentry.MCPTest.macOS", "processId": 99999, "buildLogPath": "/Library/Developer/XcodeBuildMCP/logs/build_run_macos__pid.log" diff --git a/src/snapshot-tests/__fixtures__/json/macos/get-app-path--success.json b/src/snapshot-tests/__fixtures__/json/macos/get-app-path--success.json index e3adab1e..a57d11f1 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/get-app-path--success.json +++ b/src/snapshot-tests/__fixtures__/json/macos/get-app-path--success.json @@ -15,7 +15,7 @@ "target": "macos" }, "artifacts": { - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app" + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app" } } } diff --git a/src/snapshot-tests/__fixtures__/json/macos/launch--success.json b/src/snapshot-tests/__fixtures__/json/macos/launch--success.json index 20365102..648eb3ae 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/launch--success.json +++ b/src/snapshot-tests/__fixtures__/json/macos/launch--success.json @@ -8,7 +8,7 @@ "status": "SUCCEEDED" }, "artifacts": { - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app", + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app", "bundleId": "io.sentry.MCPTest.macOS", "processId": 99999 }, diff --git a/src/snapshot-tests/__fixtures__/json/macos/test--error-wrong-scheme.json b/src/snapshot-tests/__fixtures__/json/macos/test--error-wrong-scheme.json index e2a2e011..98807c78 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/test--error-wrong-scheme.json +++ b/src/snapshot-tests/__fixtures__/json/macos/test--error-wrong-scheme.json @@ -6,6 +6,8 @@ "data": { "request": { "scheme": "NONEXISTENT", + "projectPath": "example_projects/macOS/MCPTest.xcodeproj", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-", "configuration": "Debug", "platform": "macOS", "onlyTesting": [], diff --git a/src/snapshot-tests/__fixtures__/json/macos/test--failure.json b/src/snapshot-tests/__fixtures__/json/macos/test--failure.json index 23e544fc..66305c10 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/test--failure.json +++ b/src/snapshot-tests/__fixtures__/json/macos/test--failure.json @@ -6,6 +6,8 @@ "data": { "request": { "scheme": "MCPTest", + "projectPath": "example_projects/macOS/MCPTest.xcodeproj", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-", "configuration": "Debug", "platform": "macOS", "onlyTesting": [], diff --git a/src/snapshot-tests/__fixtures__/json/macos/test--success.json b/src/snapshot-tests/__fixtures__/json/macos/test--success.json index 470a6007..24b03306 100644 --- a/src/snapshot-tests/__fixtures__/json/macos/test--success.json +++ b/src/snapshot-tests/__fixtures__/json/macos/test--success.json @@ -6,6 +6,8 @@ "data": { "request": { "scheme": "MCPTest", + "projectPath": "example_projects/macOS/MCPTest.xcodeproj", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-", "configuration": "Debug", "platform": "macOS", "onlyTesting": [ diff --git a/src/snapshot-tests/__fixtures__/json/simulator/build--error-wrong-scheme.json b/src/snapshot-tests/__fixtures__/json/simulator/build--error-wrong-scheme.json index 19a60a8f..b7e81524 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/build--error-wrong-scheme.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/build--error-wrong-scheme.json @@ -7,6 +7,7 @@ "request": { "scheme": "NONEXISTENT", "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS Simulator", "simulatorName": "iPhone 17" diff --git a/src/snapshot-tests/__fixtures__/json/simulator/build--success.json b/src/snapshot-tests/__fixtures__/json/simulator/build--success.json index 449b5b35..72626e91 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/build--success.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/build--success.json @@ -7,6 +7,7 @@ "request": { "scheme": "CalculatorApp", "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS Simulator", "simulatorName": "iPhone 17" diff --git a/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--error-wrong-scheme.json b/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--error-wrong-scheme.json index 1ea50abb..04d99ee8 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--error-wrong-scheme.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--error-wrong-scheme.json @@ -7,6 +7,7 @@ "request": { "scheme": "NONEXISTENT", "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS Simulator", "simulatorName": "iPhone 17" diff --git a/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--success.json b/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--success.json index 0b4b3367..9e54153c 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--success.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/build-and-run--success.json @@ -7,6 +7,7 @@ "request": { "scheme": "CalculatorApp", "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS Simulator", "simulatorName": "iPhone 17" @@ -17,7 +18,7 @@ "target": "simulator" }, "artifacts": { - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app", + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app", "bundleId": "io.sentry.calculatorapp", "processId": 99999, "simulatorId": "", diff --git a/src/snapshot-tests/__fixtures__/json/simulator/get-app-path--success.json b/src/snapshot-tests/__fixtures__/json/simulator/get-app-path--success.json index b08f8dc5..6e0f8bd5 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/get-app-path--success.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/get-app-path--success.json @@ -17,7 +17,7 @@ "durationMs": 1234 }, "artifacts": { - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app" } } } diff --git a/src/snapshot-tests/__fixtures__/json/simulator/install--success.json b/src/snapshot-tests/__fixtures__/json/simulator/install--success.json index 5a71e725..1bd0167e 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/install--success.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/install--success.json @@ -9,7 +9,7 @@ }, "artifacts": { "simulatorId": "", - "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" + "appPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app" }, "diagnostics": { "warnings": [], diff --git a/src/snapshot-tests/__fixtures__/json/simulator/test--error-wrong-scheme.json b/src/snapshot-tests/__fixtures__/json/simulator/test--error-wrong-scheme.json index f5ab4bbc..92a9ce47 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/test--error-wrong-scheme.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/test--error-wrong-scheme.json @@ -6,6 +6,8 @@ "data": { "request": { "scheme": "NONEXISTENT", + "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS Simulator", "simulatorName": "iPhone 17", diff --git a/src/snapshot-tests/__fixtures__/json/simulator/test--failure.json b/src/snapshot-tests/__fixtures__/json/simulator/test--failure.json index 5dad8c81..41491101 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/test--failure.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/test--failure.json @@ -6,6 +6,8 @@ "data": { "request": { "scheme": "CalculatorApp", + "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS Simulator", "simulatorName": "iPhone 17", diff --git a/src/snapshot-tests/__fixtures__/json/simulator/test--success.json b/src/snapshot-tests/__fixtures__/json/simulator/test--success.json index a41fb5c0..2f7e95ad 100644 --- a/src/snapshot-tests/__fixtures__/json/simulator/test--success.json +++ b/src/snapshot-tests/__fixtures__/json/simulator/test--success.json @@ -6,6 +6,8 @@ "data": { "request": { "scheme": "CalculatorApp", + "workspacePath": "example_projects/iOS_Calculator/CalculatorApp.xcworkspace", + "derivedDataPath": "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-", "configuration": "Debug", "platform": "iOS Simulator", "simulatorName": "iPhone 17", diff --git a/src/snapshot-tests/__fixtures__/mcp/device/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/device/build--error-wrong-scheme.txt index 20da1b1c..c4540858 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/build--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/build--error-wrong-scheme.txt @@ -5,7 +5,7 @@ Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/device/build--success.txt b/src/snapshot-tests/__fixtures__/mcp/device/build--success.txt index c4481aa3..821c750a 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/build--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/build--success.txt @@ -5,7 +5,7 @@ Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ✅ Build succeeded. (⏱️ ) └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_device__pid.log diff --git a/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--error-wrong-scheme.txt index 37a0c499..30782a48 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--error-wrong-scheme.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--success.txt index 68f7f3ad..78847f92 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/build-and-run--success.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ℹ️ Resolving app path ✅ Resolving app path @@ -16,7 +16,7 @@ ✅ Build succeeded. (⏱️ ) ✅ Build & Run complete - ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app ├ Bundle ID: io.sentry.calculatorapp ├ Process ID: └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_device__pid.log diff --git a/src/snapshot-tests/__fixtures__/mcp/device/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/mcp/device/get-app-path--success.txt index 84ff3230..9512d14e 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/get-app-path--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/get-app-path--success.txt @@ -7,9 +7,9 @@ Platform: iOS ✅ Success - └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app Next steps: -1. Get bundle ID: get_app_bundle_id({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" }) -2. Install app on device: install_app_device({ deviceId: "DEVICE_UDID", appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app" }) +1. Get bundle ID: get_app_bundle_id({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app" }) +2. Install app on device: install_app_device({ deviceId: "DEVICE_UDID", appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app" }) 3. Launch app on device: launch_app_device({ deviceId: "DEVICE_UDID", bundleId: "BUNDLE_ID" }) diff --git a/src/snapshot-tests/__fixtures__/mcp/device/install--success.txt b/src/snapshot-tests/__fixtures__/mcp/device/install--success.txt index c500efa9..cde00749 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/install--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/install--success.txt @@ -2,6 +2,6 @@ 📦 Install App Device: () - App: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphoneos/CalculatorApp.app + App: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphoneos/CalculatorApp.app ✅ App installed successfully. diff --git a/src/snapshot-tests/__fixtures__/mcp/device/test--failure.txt b/src/snapshot-tests/__fixtures__/mcp/device/test--failure.txt index 3d426cb8..279b40fd 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/test--failure.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/test--failure.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Discovered 52 test(s): CalculatorAppFeatureTests/CalculatorBasicTests/testClear diff --git a/src/snapshot-tests/__fixtures__/mcp/device/test--success.txt b/src/snapshot-tests/__fixtures__/mcp/device/test--success.txt index fdd54e05..8b015d22 100644 --- a/src/snapshot-tests/__fixtures__/mcp/device/test--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/device/test--success.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Device: () - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Selective Testing: CalculatorAppTests/CalculatorAppTests/testAddition diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/macos/build--error-wrong-scheme.txt index b07b3c73..9f4f4df8 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/build--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/build--error-wrong-scheme.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/build--success.txt b/src/snapshot-tests/__fixtures__/mcp/macos/build--success.txt index 51abc264..fb2e36e9 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/build--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/build--success.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- ✅ Build succeeded. (⏱️ ) ├ Bundle ID: io.sentry.MCPTest.macOS diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--error-wrong-scheme.txt index a9e244cf..7f8dd625 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--error-wrong-scheme.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--success.txt index a5f031a5..5a7a9706 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/build-and-run--success.txt @@ -5,7 +5,7 @@ Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- ℹ️ Resolving app path ✅ Resolving app path @@ -14,7 +14,7 @@ ✅ Build succeeded. (⏱️ ) ✅ Build & Run complete - ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app ├ Bundle ID: io.sentry.MCPTest.macOS ├ Process ID: └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_macos__pid.log diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/mcp/macos/get-app-path--success.txt index 1dbb1e4f..ca9aae0c 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/get-app-path--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/get-app-path--success.txt @@ -7,8 +7,8 @@ Platform: macOS ✅ Success - └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app Next steps: -1. Get bundle ID: get_mac_bundle_id({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app" }) -2. Launch app: launch_mac_app({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app" }) +1. Get bundle ID: get_mac_bundle_id({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app" }) +2. Launch app: launch_mac_app({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app" }) diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/launch--success.txt b/src/snapshot-tests/__fixtures__/mcp/macos/launch--success.txt index 4196864c..1fdb6327 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/launch--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/launch--success.txt @@ -1,7 +1,7 @@ 🚀 Launch macOS App - App: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug/MCPTest.app + App: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest-/Build/Products/Debug/MCPTest.app ✅ App launched successfully ├ Bundle ID: io.sentry.MCPTest.macOS diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/test--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/macos/test--error-wrong-scheme.txt index 94fa73ba..6e87d6c2 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/test--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/test--error-wrong-scheme.txt @@ -2,9 +2,10 @@ 🧪 Test Scheme: NONEXISTENT + Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/test--failure.txt b/src/snapshot-tests/__fixtures__/mcp/macos/test--failure.txt index d564c0e2..f18e9f94 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/test--failure.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/test--failure.txt @@ -2,9 +2,10 @@ 🧪 Test Scheme: MCPTest + Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Discovered 4 test(s): MCPTestTests/MCPTestTests/appNameIsCorrect diff --git a/src/snapshot-tests/__fixtures__/mcp/macos/test--success.txt b/src/snapshot-tests/__fixtures__/mcp/macos/test--success.txt index 384ca1bf..877b5a9a 100644 --- a/src/snapshot-tests/__fixtures__/mcp/macos/test--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/macos/test--success.txt @@ -2,9 +2,10 @@ 🧪 Test Scheme: MCPTest + Project: example_projects/macOS/MCPTest.xcodeproj Configuration: Debug Platform: macOS - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/MCPTest- Selective Testing: MCPTestTests/MCPTestTests/appNameIsCorrect() MCPTestTests/MCPTestsXCTests/testAppNameIsCorrect diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/build--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/build--error-wrong-scheme.txt index de358b6d..709a9457 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/build--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/build--error-wrong-scheme.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/build--success.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/build--success.txt index 2b0df214..16bbaa0b 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/build--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/build--success.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ✅ Build succeeded. (⏱️ ) └ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--error-wrong-scheme.txt index 13a8d794..17ba47c7 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--error-wrong-scheme.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--success.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--success.txt index e06333b0..c69b56a4 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/build-and-run--success.txt @@ -6,7 +6,7 @@ Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- ℹ️ Resolving app path ✅ Resolving app path @@ -18,7 +18,7 @@ ✅ Build succeeded. (⏱️ ) ✅ Build & Run complete - ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + ├ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app ├ Bundle ID: io.sentry.calculatorapp ├ Process ID: ├ Build Logs: /Library/Developer/XcodeBuildMCP/logs/build_run_sim__pid.log diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/get-app-path--success.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/get-app-path--success.txt index 80373630..9d80b39c 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/get-app-path--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/get-app-path--success.txt @@ -8,10 +8,10 @@ Simulator: iPhone 17 ✅ Get app path successful (⏱️ ) - └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + └ App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app Next steps: -1. Get bundle ID: get_app_bundle_id({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" }) +1. Get bundle ID: get_app_bundle_id({ appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app" }) 2. Boot simulator: boot_sim({ simulatorId: "SIMULATOR_UUID" }) -3. Install app: install_app_sim({ simulatorId: "SIMULATOR_UUID", appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app" }) +3. Install app: install_app_sim({ simulatorId: "SIMULATOR_UUID", appPath: "/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app" }) 4. Launch app: launch_app_sim({ simulatorId: "SIMULATOR_UUID", bundleId: "BUNDLE_ID" }) diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/install--success.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/install--success.txt index 518afcf3..02528861 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/install--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/install--success.txt @@ -2,7 +2,7 @@ 📦 Install App Simulator: - App Path: /Library/Developer/XcodeBuildMCP/DerivedData/Build/Products/Debug-iphonesimulator/CalculatorApp.app + App Path: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-/Build/Products/Debug-iphonesimulator/CalculatorApp.app ✅ App installed successfully diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/test--error-wrong-scheme.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/test--error-wrong-scheme.txt index 50619e67..d4042880 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/test--error-wrong-scheme.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/test--error-wrong-scheme.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: NONEXISTENT + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Errors (1): diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/test--failure.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/test--failure.txt index 22abb7ef..67c14084 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/test--failure.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/test--failure.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Discovered 52 test(s): CalculatorAppFeatureTests/CalculatorBasicTests/testClear diff --git a/src/snapshot-tests/__fixtures__/mcp/simulator/test--success.txt b/src/snapshot-tests/__fixtures__/mcp/simulator/test--success.txt index d0fb32a1..d1595548 100644 --- a/src/snapshot-tests/__fixtures__/mcp/simulator/test--success.txt +++ b/src/snapshot-tests/__fixtures__/mcp/simulator/test--success.txt @@ -2,10 +2,11 @@ 🧪 Test Scheme: CalculatorApp + Workspace: example_projects/iOS_Calculator/CalculatorApp.xcworkspace Configuration: Debug Platform: iOS Simulator Simulator: iPhone 17 - Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData + Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp- Selective Testing: CalculatorAppTests/CalculatorAppTests/testAddition diff --git a/src/snapshot-tests/normalize.ts b/src/snapshot-tests/normalize.ts index 211aaff7..9a8ab534 100644 --- a/src/snapshot-tests/normalize.ts +++ b/src/snapshot-tests/normalize.ts @@ -23,7 +23,7 @@ const LLDB_SYS_FRAME_FUNC_REGEX = /(frame #\d+: )\S+( at (?:\/usr\/lib\/|\/Library\/Developer\/CoreSimulator\/)[^`\n]*`)[^:\n]+(:)/gm; const LLDB_FRAME_NUMBER_REGEX = / frame #\d+:/g; const LLDB_BREAKPOINT_LOCATIONS_REGEX = /locations = .+$/gm; -const DERIVED_DATA_HASH_REGEX = /(DerivedData\/[A-Za-z0-9_]+)-[a-z]{28}\b/g; +const DERIVED_DATA_HASH_REGEX = /(DerivedData\/[^/\s]+)-(?:[a-z]{28}|[0-9a-f]{12})(?=\/|\b)/g; const LOCAL_TIMESTAMP_REGEX = /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}/g; const XCTEST_PARENS_DURATION_REGEX = /\(\d+\.\d+\) seconds/g; const SWIFT_TESTING_DURATION_REGEX = /after \d+\.\d+ seconds/g; diff --git a/src/utils/__tests__/build-preflight.test.ts b/src/utils/__tests__/build-preflight.test.ts index 88e7be8a..56f0ef52 100644 --- a/src/utils/__tests__/build-preflight.test.ts +++ b/src/utils/__tests__/build-preflight.test.ts @@ -1,8 +1,11 @@ import { describe, it, expect } from 'vitest'; import { displayPath, formatToolPreflight } from '../build-preflight.ts'; +import { computeScopedDerivedDataPath } from '../derived-data-path.ts'; import { DERIVED_DATA_DIR } from '../log-paths.ts'; const DISPLAY_DERIVED_DATA = displayPath(DERIVED_DATA_DIR); +const displayScopedDerivedData = (anchorPath: string): string => + displayPath(computeScopedDerivedDataPath(anchorPath)); describe('formatToolPreflight', () => { it('formats simulator build with workspace and simulator name', () => { @@ -24,7 +27,7 @@ describe('formatToolPreflight', () => { ' Configuration: Debug', ' Platform: iOS Simulator', ' Simulator: iPhone 17', - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/MyApp.xcworkspace')}`, '', ].join('\n'), ); @@ -49,7 +52,7 @@ describe('formatToolPreflight', () => { ' Configuration: Release', ' Platform: iOS Simulator', ' Simulator: ABC-123-DEF', - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/MyApp.xcodeproj')}`, '', ].join('\n'), ); @@ -74,7 +77,7 @@ describe('formatToolPreflight', () => { ' Configuration: Debug', ' Platform: iOS', ' Device: DEVICE-UDID-123', - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/MyApp.xcodeproj')}`, '', ].join('\n'), ); @@ -100,7 +103,7 @@ describe('formatToolPreflight', () => { ' Configuration: Debug', ' Platform: iOS', " Device: Cameron's iPhone (DEVICE-UDID-123)", - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/MyApp.xcodeproj')}`, '', ].join('\n'), ); @@ -123,7 +126,7 @@ describe('formatToolPreflight', () => { ' Project: /path/to/MacApp.xcodeproj', ' Configuration: Debug', ' Platform: macOS', - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/MacApp.xcodeproj')}`, '', ].join('\n'), ); @@ -147,7 +150,7 @@ describe('formatToolPreflight', () => { ' Workspace: /path/to/workspace.xcworkspace', ' Configuration: Debug', ' Platform: macOS', - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/workspace.xcworkspace')}`, ' Architecture: arm64', '', ].join('\n'), @@ -171,7 +174,7 @@ describe('formatToolPreflight', () => { ' Project: /path/to/MyApp.xcodeproj', ' Configuration: Debug', ' Platform: iOS', - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/MyApp.xcodeproj')}`, '', ].join('\n'), ); @@ -217,7 +220,7 @@ describe('formatToolPreflight', () => { ' Configuration: Debug', ' Platform: iOS Simulator', ' Simulator: iPhone 17', - ` Derived Data: ${DISPLAY_DERIVED_DATA}`, + ` Derived Data: ${displayScopedDerivedData('/path/to/MyApp.xcworkspace')}`, '', ].join('\n'), ); diff --git a/src/utils/__tests__/derived-data-path.test.ts b/src/utils/__tests__/derived-data-path.test.ts new file mode 100644 index 00000000..f5d6f853 --- /dev/null +++ b/src/utils/__tests__/derived-data-path.test.ts @@ -0,0 +1,75 @@ +import path from 'node:path'; +import { describe, expect, it } from 'vitest'; +import { + computeScopedDerivedDataPath, + resolveEffectiveDerivedDataPath, +} from '../derived-data-path.ts'; +import { DERIVED_DATA_DIR } from '../log-paths.ts'; + +describe('resolveEffectiveDerivedDataPath', () => { + it('uses an explicit absolute derivedDataPath', () => { + expect(resolveEffectiveDerivedDataPath({ derivedDataPath: '/tmp/DerivedData' })).toBe( + '/tmp/DerivedData', + ); + }); + + it('resolves an explicit relative derivedDataPath from cwd', () => { + expect( + resolveEffectiveDerivedDataPath({ derivedDataPath: '.derivedData/app', cwd: '/repo' }), + ).toBe('/repo/.derivedData/app'); + }); + + it('scopes DerivedData from workspacePath when derivedDataPath is absent', () => { + const workspacePath = '/Users/dev/clone-1/MyApp.xcworkspace'; + + expect(resolveEffectiveDerivedDataPath({ workspacePath })).toBe( + computeScopedDerivedDataPath(workspacePath), + ); + }); + + it('prefers workspacePath over projectPath when both anchors are present', () => { + const workspacePath = '/Users/dev/clone-1/MyApp.xcworkspace'; + const projectPath = '/Users/dev/clone-1/MyApp.xcodeproj'; + + expect(resolveEffectiveDerivedDataPath({ workspacePath, projectPath })).toBe( + computeScopedDerivedDataPath(workspacePath), + ); + }); + + it('scopes DerivedData from projectPath when workspacePath is absent', () => { + const projectPath = '/Users/dev/clone-2/MyApp.xcodeproj'; + + expect(resolveEffectiveDerivedDataPath({ projectPath })).toBe( + computeScopedDerivedDataPath(projectPath), + ); + }); + + it('resolves relative workspace anchors before hashing', () => { + const cwd = '/Users/dev/repo'; + const workspacePath = 'App/MyApp.xcworkspace'; + + expect(resolveEffectiveDerivedDataPath({ workspacePath, cwd })).toBe( + computeScopedDerivedDataPath(path.join(cwd, workspacePath)), + ); + }); + + it('returns the global DerivedData root when no explicit path or anchor is present', () => { + expect(resolveEffectiveDerivedDataPath()).toBe(DERIVED_DATA_DIR); + expect( + resolveEffectiveDerivedDataPath({ + derivedDataPath: ' ', + workspacePath: '\t', + projectPath: '', + }), + ).toBe(DERIVED_DATA_DIR); + }); + + it('produces different scoped paths for matching basenames in different directories', () => { + const firstPath = computeScopedDerivedDataPath('/clone-1/MyApp.xcworkspace'); + const secondPath = computeScopedDerivedDataPath('/clone-2/MyApp.xcworkspace'); + + expect(firstPath).toMatch(/MyApp-[a-f0-9]{12}$/); + expect(secondPath).toMatch(/MyApp-[a-f0-9]{12}$/); + expect(firstPath).not.toBe(secondPath); + }); +}); diff --git a/src/utils/__tests__/session-store.test.ts b/src/utils/__tests__/session-store.test.ts index 7d45c6a2..ec373d55 100644 --- a/src/utils/__tests__/session-store.test.ts +++ b/src/utils/__tests__/session-store.test.ts @@ -121,4 +121,21 @@ describe('SessionStore', () => { const stored = sessionStore.getAll(); expect(stored.env).toEqual({ API_KEY: 'secret' }); }); + + it('does not compute derivedDataPath from workspacePath', () => { + sessionStore.setDefaults({ workspacePath: '/Users/dev/clone-1/MyApp.xcworkspace' }); + + const defaults = sessionStore.getAll(); + expect(defaults.workspacePath).toBe('/Users/dev/clone-1/MyApp.xcworkspace'); + expect(defaults.derivedDataPath).toBeUndefined(); + }); + + it('preserves an explicitly set derivedDataPath as raw session state', () => { + sessionStore.setDefaults({ + workspacePath: '/Users/dev/clone-1/MyApp.xcworkspace', + derivedDataPath: '/custom/path', + }); + + expect(sessionStore.getAll().derivedDataPath).toBe('/custom/path'); + }); }); diff --git a/src/utils/__tests__/snapshot-normalize.test.ts b/src/utils/__tests__/snapshot-normalize.test.ts index 445388d0..8dd17e76 100644 --- a/src/utils/__tests__/snapshot-normalize.test.ts +++ b/src/utils/__tests__/snapshot-normalize.test.ts @@ -39,4 +39,16 @@ describe('normalizeSnapshotOutput tilde handling', () => { 'Discovered 2 test(s):\n ExampleTests/testOne\n› Linking\n› Running tests\n\n✅ 2 tests passed, 0 skipped (⏱️ )\n', ); }); + + it('normalizes scoped XcodeBuildMCP DerivedData hashes', () => { + const input = + 'Derived Data: /Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-22d700c6d603\n'; + + const result = normalizeSnapshotOutput(input); + + expect(result).toContain( + '/Library/Developer/XcodeBuildMCP/DerivedData/CalculatorApp-', + ); + expect(result).not.toContain('22d700c6d603'); + }); }); diff --git a/src/utils/__tests__/xcodebuild-pipeline.test.ts b/src/utils/__tests__/xcodebuild-pipeline.test.ts index b8ad93ef..af9632a8 100644 --- a/src/utils/__tests__/xcodebuild-pipeline.test.ts +++ b/src/utils/__tests__/xcodebuild-pipeline.test.ts @@ -1,5 +1,8 @@ import { describe, expect, it, beforeEach, afterEach, vi } from 'vitest'; -import { createXcodebuildPipeline } from '../xcodebuild-pipeline.ts'; +import { + createXcodebuildPipeline, + invocationRequestToHeaderParams, +} from '../xcodebuild-pipeline.ts'; import { STAGE_RANK } from '../../types/domain-fragments.ts'; import type { AnyFragment, DomainFragment } from '../../types/domain-fragments.ts'; import { renderCliTextTranscript } from '../renderers/cli-text-renderer.ts'; @@ -276,6 +279,28 @@ describe('xcodebuild-pipeline', () => { expect(output).toContain(' (...and 2 more)'); }); + it('derives header DerivedData from request workspacePath', () => { + const params = invocationRequestToHeaderParams({ + scheme: 'MyApp', + workspacePath: '/path/to/MyApp.xcworkspace', + }); + + expect(params).toContainEqual({ label: 'Workspace', value: '/path/to/MyApp.xcworkspace' }); + expect(params).toContainEqual({ + label: 'Derived Data', + value: expect.stringMatching(/MyApp-[a-f0-9]{12}$/), + }); + }); + + it('does not add DerivedData header rows for package-only requests', () => { + const params = invocationRequestToHeaderParams({ + target: 'swift-package', + packagePath: '/path/to/Package', + }); + + expect(params.some((param) => param.label === 'Derived Data')).toBe(false); + }); + it('produces JSONL output in CLI json mode', () => { process.env.XCODEBUILDMCP_RUNTIME = 'cli'; process.env.XCODEBUILDMCP_CLI_OUTPUT_FORMAT = 'json'; diff --git a/src/utils/app-path-resolver.ts b/src/utils/app-path-resolver.ts index 4a7a5504..0f18c6cc 100644 --- a/src/utils/app-path-resolver.ts +++ b/src/utils/app-path-resolver.ts @@ -59,7 +59,11 @@ export async function resolveAppPathFromBuildSettings( const workspacePath = resolvePathFromCwd(params.workspacePath); const projectPath = resolvePathFromCwd(params.projectPath); - const derivedDataPath = resolveEffectiveDerivedDataPath(params.derivedDataPath); + const derivedDataPath = resolveEffectiveDerivedDataPath({ + derivedDataPath: params.derivedDataPath, + workspacePath, + projectPath, + }); let projectDir: string | undefined; diff --git a/src/utils/build-preflight.ts b/src/utils/build-preflight.ts index 2f3c2d4f..f5bfee74 100644 --- a/src/utils/build-preflight.ts +++ b/src/utils/build-preflight.ts @@ -94,7 +94,13 @@ export function formatToolPreflight(params: ToolPreflightParams): string { } lines.push( - ` Derived Data: ${displayPath(resolveEffectiveDerivedDataPath(params.derivedDataPath))}`, + ` Derived Data: ${displayPath( + resolveEffectiveDerivedDataPath({ + derivedDataPath: params.derivedDataPath, + workspacePath: params.workspacePath, + projectPath: params.projectPath, + }), + )}`, ); if (params.arch) { diff --git a/src/utils/build-utils.ts b/src/utils/build-utils.ts index a7f54e0d..24504c9f 100644 --- a/src/utils/build-utils.ts +++ b/src/utils/build-utils.ts @@ -84,7 +84,11 @@ export async function executeXcodeBuildCommand( ? resolvePathFromCwd(params.workspacePath) : undefined; const projectPath = params.projectPath ? resolvePathFromCwd(params.projectPath) : undefined; - const derivedDataPath = resolveEffectiveDerivedDataPath(params.derivedDataPath); + const derivedDataPath = resolveEffectiveDerivedDataPath({ + derivedDataPath: params.derivedDataPath, + workspacePath, + projectPath, + }); let projectDir = ''; if (workspacePath) { diff --git a/src/utils/derived-data-path.ts b/src/utils/derived-data-path.ts index 2b281a2c..4cb834aa 100644 --- a/src/utils/derived-data-path.ts +++ b/src/utils/derived-data-path.ts @@ -1,12 +1,48 @@ +import * as crypto from 'node:crypto'; import * as path from 'node:path'; import { DERIVED_DATA_DIR } from './log-paths.ts'; -export function resolveEffectiveDerivedDataPath(input?: string): string { - if (!input || input.trim().length === 0) { - return DERIVED_DATA_DIR; +export type DerivedDataPathInput = { + derivedDataPath?: string | null; + workspacePath?: string | null; + projectPath?: string | null; + cwd?: string; +}; + +function getNonEmptyPath(pathValue?: string | null): string | undefined { + return pathValue && pathValue.trim().length > 0 ? pathValue : undefined; +} + +export function resolvePathFromCwd(pathValue: string, cwd: string = process.cwd()): string { + if (path.isAbsolute(pathValue)) { + return pathValue; + } + return path.resolve(cwd, pathValue); +} + +export function computeScopedDerivedDataPath(anchorPath: string): string { + const resolved = path.resolve(anchorPath); + const hash = crypto.createHash('sha256').update(resolved).digest('hex').slice(0, 12); + const name = path.basename(resolved, path.extname(resolved)); + return path.join(DERIVED_DATA_DIR, `${name}-${hash}`); +} + +export function resolveEffectiveDerivedDataPath(input: DerivedDataPathInput = {}): string { + const cwd = input.cwd ?? process.cwd(); + const explicitDerivedDataPath = getNonEmptyPath(input.derivedDataPath); + if (explicitDerivedDataPath) { + return resolvePathFromCwd(explicitDerivedDataPath, cwd); + } + + const workspacePath = getNonEmptyPath(input.workspacePath); + if (workspacePath) { + return computeScopedDerivedDataPath(resolvePathFromCwd(workspacePath, cwd)); } - if (path.isAbsolute(input)) { - return input; + + const projectPath = getNonEmptyPath(input.projectPath); + if (projectPath) { + return computeScopedDerivedDataPath(resolvePathFromCwd(projectPath, cwd)); } - return path.resolve(process.cwd(), input); + + return DERIVED_DATA_DIR; } diff --git a/src/utils/session-store.ts b/src/utils/session-store.ts index 2d1cdf1b..186b745a 100644 --- a/src/utils/session-store.ts +++ b/src/utils/session-store.ts @@ -76,7 +76,7 @@ class SessionStore { } setDefaultsForProfile(profile: string | null, partial: Partial): void { - const previous = this.getAllForProfile(profile); + const previous = this.getRawForProfile(profile); const next = { ...previous, ...partial }; this.setDefaultsForResolvedProfile(profile, next); this.revision += 1; @@ -114,7 +114,7 @@ class SessionStore { return; } - const next = this.getAllForProfile(profile); + const next = this.getRawForProfile(profile); for (const k of keys) delete next[k]; this.setDefaultsForResolvedProfile(profile, next); @@ -132,6 +132,10 @@ class SessionStore { } getAllForProfile(profile: string | null): SessionDefaults { + return this.getRawForProfile(profile); + } + + private getRawForProfile(profile: string | null): SessionDefaults { const defaults = profile === null ? this.globalDefaults : (this.profiles[profile] ?? {}); return this.cloneDefaults(defaults); } diff --git a/src/utils/xcodebuild-pipeline.ts b/src/utils/xcodebuild-pipeline.ts index fc8dd18f..7c9f5055 100644 --- a/src/utils/xcodebuild-pipeline.ts +++ b/src/utils/xcodebuild-pipeline.ts @@ -131,7 +131,13 @@ function buildHeaderParams( (r) => r.label === 'Scheme' || r.label === 'Workspace' || r.label === 'Project', ); if (hasXcodebuildContext && !result.some((r) => r.label === 'Derived Data')) { - result.push({ label: 'Derived Data', value: displayPath(resolveEffectiveDerivedDataPath()) }); + const effectivePath = resolveEffectiveDerivedDataPath({ + derivedDataPath: + typeof params.derivedDataPath === 'string' ? params.derivedDataPath : undefined, + workspacePath: typeof params.workspacePath === 'string' ? params.workspacePath : undefined, + projectPath: typeof params.projectPath === 'string' ? params.projectPath : undefined, + }); + result.push({ label: 'Derived Data', value: displayPath(effectivePath) }); } return result;