From 8566a146604bd0457e4a59d6edea9b921dd33c1b Mon Sep 17 00:00:00 2001 From: finalerock44 Date: Mon, 26 Oct 2026 10:44:08 +0000 Subject: [PATCH] fix(device): drop Pixel 6 Pro and Pixel 7 Pro, and mirror the Pixel 10 default The API removes pixel-6-pro and pixel-7-pro on 26 Oct 2026 and moves the default Android device from pixel-7 to pixel-10 (API 36 unchanged). pixel-7 stays until 9 Nov 2026. - The help-text enum loses both devices; validation already follows the live compatibility data. - The default-device mirror is pixel-10, so a version-only request is checked against the device the API will actually use. A level Pixel 10 doesn't offer (32-35) is refused with the devices that do offer it, which is what the API now answers too. - dcd live's --android-device help lists the live-session devices the API offers (the API already refuses pixel-7 and the Pro devices for live). - Device-matrix and MCP examples use devices that outlive Pixel 7. schema.types.ts is deliberately not regenerated: the API drift would come with it. --- src/commands/live.ts | 2 +- src/config/flags/device.flags.ts | 2 +- src/mcp/tools/run-cloud-test.ts | 2 +- src/services/device-validation.service.ts | 2 +- src/types/domain/device.types.ts | 2 -- src/utils/device-matrix.ts | 2 +- test/unit/device-validation.service.test.ts | 21 +++++++++++++-------- 7 files changed, 18 insertions(+), 15 deletions(-) diff --git a/src/commands/live.ts b/src/commands/live.ts index bc79aac..8e0b117 100644 --- a/src/commands/live.ts +++ b/src/commands/live.ts @@ -166,7 +166,7 @@ const startSub = defineCommand({ 'android-device': { type: 'string', description: - '[Android] Device profile to match a cloud run (options: pixel-6, pixel-6-pro, pixel-7, pixel-7-pro, pixel-8, pixel-10, pixel-10-pro, pixel-10-pro-xl, pixel-11)', + '[Android] Device profile to match a cloud run (options: pixel-6, pixel-8, pixel-10, pixel-10-pro, pixel-10-pro-xl, pixel-11)', }, 'android-api-level': { type: 'string', diff --git a/src/config/flags/device.flags.ts b/src/config/flags/device.flags.ts index eb0c49c..095558e 100644 --- a/src/config/flags/device.flags.ts +++ b/src/config/flags/device.flags.ts @@ -53,7 +53,7 @@ export const deviceFlags = { }, 'android-device-matrix': { type: 'string', - description: `[Android only] Device-matrix cell as : (append :play for Google Play), e.g. pixel-7:34 or pixel-7:34:play. Repeatable — every flow runs once per cell (no cross-product). Cannot be combined with --ios-device-matrix.`, + description: `[Android only] Device-matrix cell as : (append :play for Google Play), e.g. pixel-8:34 or pixel-8:34:play. Repeatable — every flow runs once per cell (no cross-product). Cannot be combined with --ios-device-matrix.`, }, orientation: { type: 'string', diff --git a/src/mcp/tools/run-cloud-test.ts b/src/mcp/tools/run-cloud-test.ts index 1d32845..99d1437 100644 --- a/src/mcp/tools/run-cloud-test.ts +++ b/src/mcp/tools/run-cloud-test.ts @@ -69,7 +69,7 @@ export function registerRunCloudTest(server: McpServer): void { iosVersion: z.string().optional().describe('iOS version, e.g. "17"'), iosDevice: z.string().optional().describe('iOS device, e.g. "iphone-14"'), androidApiLevel: z.string().optional().describe('Android API level, e.g. "34"'), - androidDevice: z.string().optional().describe('Android device, e.g. "pixel-7"'), + androidDevice: z.string().optional().describe('Android device, e.g. "pixel-10"'), googlePlay: z.boolean().optional().describe('Use a Google Play-enabled Android image'), name: z.string().optional().describe('A name for this run'), env: z diff --git a/src/services/device-validation.service.ts b/src/services/device-validation.service.ts index 482d97e..bdc1417 100644 --- a/src/services/device-validation.service.ts +++ b/src/services/device-validation.service.ts @@ -106,7 +106,7 @@ export class DeviceValidationService { // Mirrors the API, which applies these same global defaults to a // request that omits either half (execution-planner.service.ts) // and then rejects an incompatible pair. - defaultDevice: 'pixel-7', + defaultDevice: 'pixel-10', defaultVersion: '36', device, deviceArg: argNames.androidDevice, diff --git a/src/types/domain/device.types.ts b/src/types/domain/device.types.ts index e1ff8c8..20d58b5 100644 --- a/src/types/domain/device.types.ts +++ b/src/types/domain/device.types.ts @@ -32,9 +32,7 @@ export enum EiOSDevices { export enum EAndroidDevices { 'generic-tablet' = 'generic-tablet', 'pixel-6' = 'pixel-6', - 'pixel-6-pro' = 'pixel-6-pro', 'pixel-7' = 'pixel-7', - 'pixel-7-pro' = 'pixel-7-pro', 'pixel-8' = 'pixel-8', 'pixel-10' = 'pixel-10', 'pixel-10-pro' = 'pixel-10-pro', diff --git a/src/utils/device-matrix.ts b/src/utils/device-matrix.ts index 7f171ae..909e5dd 100644 --- a/src/utils/device-matrix.ts +++ b/src/utils/device-matrix.ts @@ -77,7 +77,7 @@ export function parseDeviceMatrix( (parts.length === 3 && parts[2] !== 'play') ) { throw new CliError( - `Invalid --android-device-matrix "${raw}". Expected : or ::play, e.g. pixel-7:34 or pixel-7:34:play.`, + `Invalid --android-device-matrix "${raw}". Expected : or ::play, e.g. pixel-8:34 or pixel-8:34:play.`, ); } configs.push({ diff --git a/test/unit/device-validation.service.test.ts b/test/unit/device-validation.service.test.ts index 2ed44c4..5f25e9f 100644 --- a/test/unit/device-validation.service.test.ts +++ b/test/unit/device-validation.service.test.ts @@ -130,7 +130,7 @@ describe('DeviceValidationService', () => { }); // The API fills an omitted half from the same global defaults (iphone-14 / - // iOS 17, pixel-7 / API 36) and rejects an incompatible pair, so the CLI + // iOS 17, pixel-10 / API 36) and rejects an incompatible pair, so the CLI // mirrors that — but must tell the user to pass the other half. describe('requests that rely on a default', () => { it('tells a device-only iOS request to pass the version explicitly', () => { @@ -174,25 +174,30 @@ describe('DeviceValidationService', () => { expect(() => ios('99')).to.throw( /No iOS device was given, so the default \(iphone-14\) was checked: no iOS device offers iOS 99$/, ); - expect(() => android('36', undefined, true)).to.throw( - /no Google Play device offers API level 36$/, + // The default device (pixel-10) has Play images, as it does in the API. + const playDefault = { + ...compat, + androidPlay: { ...compat.androidPlay, 'pixel-10': ['36', '37'] }, + }; + expect(() => android('35', undefined, true, playDefault)).to.throw( + /no Google Play device offers API level 35$/, ); }); it('leaves a version-only request to the API once the API no longer offers the assumed default device', () => { // The API has moved its default on; checking against the CLI's stale // assumption would refuse a request the API accepts. - const withoutPixel7 = { + const withoutPixel10 = { ...compat, - android: { 'pixel-10': ['36', '37'] }, + android: { 'pixel-12': ['38'] }, }; - expect(() => android('36', undefined, false, withoutPixel7)).to.not.throw(); + expect(() => android('38', undefined, false, withoutPixel10)).to.not.throw(); }); }); // With Google Play the API does not apply the global default to an omitted - // half — pixel-7 / API 36 has no Play image — but picks whichever value - // makes the pair a Play cell, and only rejects when there is none. + // half when that would miss a Play image, but picks whichever value makes + // the pair a Play cell, and only rejects when there is none. describe('Google Play requests that name one half', () => { const play36 = { ...compat,