From c3a7cdf0a81f3d1bb48663cfe01e2c3d83c009f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20Pierzcha=C5=82a?= Date: Tue, 30 Jun 2026 08:01:12 +0200 Subject: [PATCH] =?UTF-8?q?refactor:=20delete=20the=20WaitCommandResult/Al?= =?UTF-8?q?ertCommandResult=20mirror=20types=20=E2=80=94=20Phase=202c?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit BREAKING (intentional, approved): removes the last two hand-written result-type mirrors from client-types.ts. wait and alert are genuinely dynamic — wait's daemon data is toDaemonWaitData's Record, and alert's iOS path is a generic runner Record — so per the typed-result doctrine they should be the untyped CommandRequestResult, not an invented closed shape. - delete WaitCommandResult and AlertCommandResult from client-types.ts; the client.command.wait/alert methods now return CommandRequestResult. - drop their public exports from index.ts and the now-unused AlertInfo import. - the android-lifecycle integration test that read the typed alert.alert.source now casts the untyped bag. This completes the result-type half of the client-types.ts mirror deletion (the 13 closed commands already live in src/contracts/* via CommandResultMap). The Options-type half (deriving from inputSchema) is a separate follow-up. Verified: tsc, oxfmt + oxlint --deny-warnings, fallow audit clean, Layering Guard empty, 476 client/contracts/mcp tests pass. --- src/client-types.ts | 26 +++---------------- src/index.ts | 2 -- .../android-lifecycle.test.ts | 5 +++- 3 files changed, 7 insertions(+), 26 deletions(-) diff --git a/src/client-types.ts b/src/client-types.ts index 853e8c79c..4d53e60fa 100644 --- a/src/client-types.ts +++ b/src/client-types.ts @@ -42,7 +42,7 @@ export type { BatchRunResult } from './core/batch.ts'; import type { TargetShutdownResult } from './target-shutdown-contract.ts'; export type { TargetShutdownResult } from './target-shutdown-contract.ts'; import type { PerfAction, PerfArea, PerfKind, PerfSubject } from './contracts/perf.ts'; -import type { AlertAction, AlertInfo } from './alert-contract.ts'; +import type { AlertAction } from './alert-contract.ts'; import type { DebugSymbolsOptions, DebugSymbolsResult } from './contracts/debug-symbols.ts'; import type { RemoteConnectionProfileFields } from './remote-config-schema.ts'; import type { CommandResult } from './core/command-descriptor/command-result.ts'; @@ -459,26 +459,6 @@ export type ClipboardCommandOptions = text: string; }); -export type WaitCommandResult = DaemonResponseData & { - waitedMs?: number; - text?: string; - selector?: string; -}; - -export type AlertCommandResult = DaemonResponseData & { - kind?: 'alertStatus' | 'alertHandled' | 'alertWait'; - action?: AlertCommandOptions['action']; - alert?: AlertInfo | null; - handled?: boolean; - button?: string; - waitedMs?: number; - timedOut?: boolean; - platform?: AlertInfo['platform']; - accepted?: boolean; - dismissed?: boolean; - items?: string[]; -}; - export type ReactNativeCommandOptions = DeviceCommandBaseOptions & { action: 'dismiss-overlay'; }; @@ -494,8 +474,8 @@ export type ViewportCommandOptions = DeviceCommandBaseOptions & { }; export type AgentDeviceCommandClient = { - wait: (options: WaitCommandOptions) => Promise; - alert: (options?: AlertCommandOptions) => Promise; + wait: (options: WaitCommandOptions) => Promise; + alert: (options?: AlertCommandOptions) => Promise; appState: (options?: AppStateCommandOptions) => Promise>; back: (options?: BackCommandOptions) => Promise>; home: (options?: HomeCommandOptions) => Promise>; diff --git a/src/index.ts b/src/index.ts index f3109534b..24e81b392 100644 --- a/src/index.ts +++ b/src/index.ts @@ -47,7 +47,6 @@ export type { AlertCommandOptions, AlertInfo, AlertPlatform, - AlertCommandResult, AlertSource, AppCloseOptions, AppCloseResult, @@ -119,7 +118,6 @@ export type { TraceOptions, TypeTextOptions, WaitCommandOptions, - WaitCommandResult, } from './client.ts'; export type { diff --git a/test/integration/provider-scenarios/android-lifecycle.test.ts b/test/integration/provider-scenarios/android-lifecycle.test.ts index e2b775ad2..3dfcea024 100644 --- a/test/integration/provider-scenarios/android-lifecycle.test.ts +++ b/test/integration/provider-scenarios/android-lifecycle.test.ts @@ -353,7 +353,10 @@ test('Provider-backed integration Android alert wait polls until a dialog appear ...world.selection, }); assert.equal(alertWait.kind, 'alertWait'); - assert.equal(alertWait.alert?.source, 'permission'); + // alert now returns the untyped CommandRequestResult bag (its iOS path is a + // dynamic runner Record, so the public type is no longer a closed shape). + const alertInfo = alertWait.alert as { source?: string } | null | undefined; + assert.equal(alertInfo?.source, 'permission'); assert.ok(snapshotCount >= 2); }, );