agent-device 0.19.3 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (168) hide show
  1. package/README.md +61 -70
  2. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk +0 -0
  3. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.apk.sha256 +1 -0
  4. package/android/ime-helper/dist/agent-device-android-ime-helper-0.20.0.manifest.json +10 -0
  5. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk +0 -0
  6. package/android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.apk.sha256 +1 -0
  7. package/{android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.manifest.json → android/snapshot-helper/dist/agent-device-android-snapshot-helper-0.20.0.manifest.json} +6 -6
  8. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +2 -0
  9. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +5 -0
  10. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +5 -10
  11. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +74 -174
  12. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +113 -19
  13. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+BlockingSystemModalResolution.swift +82 -0
  14. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +272 -118
  15. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -2
  16. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +134 -101
  17. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +56 -2
  18. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+LifecycleCacheTests.swift +73 -0
  19. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +44 -24
  20. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -2
  21. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -107
  22. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +126 -11
  23. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +51 -8
  24. package/dist/apple/runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotTraversalIdentityTests.swift +24 -0
  25. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SynthesizedGesturePolicy.swift +1 -1
  26. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +43 -35
  27. package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +14 -0
  28. package/dist/src/agent-browser-tool.js +1 -1
  29. package/dist/src/agent-device-client.js +3 -0
  30. package/dist/src/android-adb.d.ts +1 -1
  31. package/dist/src/android-adb.js +1 -1
  32. package/dist/src/android-input-method-overlays.js +1 -0
  33. package/dist/src/android-input-ownership.js +1 -6
  34. package/dist/src/android-system-chrome.js +1 -0
  35. package/dist/src/android.js +1 -1
  36. package/dist/src/app-lifecycle.js +5 -5
  37. package/dist/src/app-log-request-scope.js +1 -0
  38. package/dist/src/app-resolution.js +1 -0
  39. package/dist/src/apple-multitouch-support.js +1 -0
  40. package/dist/src/apps.js +5 -5
  41. package/dist/src/boot-diagnostics.js +2 -0
  42. package/dist/src/cli-config.js +1 -0
  43. package/dist/src/cli-help.js +61 -27
  44. package/dist/src/cli-runner.js +1 -1
  45. package/dist/src/cli.js +15 -11
  46. package/dist/src/command-schema.js +3 -3
  47. package/dist/src/config.js +1 -0
  48. package/dist/src/context.js +1 -0
  49. package/dist/src/contracts.d.ts +1 -1
  50. package/dist/src/daemon-shutdown-report.js +1 -0
  51. package/dist/src/debug-symbols.js +1 -1
  52. package/dist/src/device-input-state.js +1 -1
  53. package/dist/src/devices2.js +1 -1
  54. package/dist/src/find.js +1 -1
  55. package/dist/src/finders.js +1 -1
  56. package/dist/src/generic.js +1 -1
  57. package/dist/src/helper.js +1 -1
  58. package/dist/src/index.d.ts +412 -293
  59. package/dist/src/index.js +1 -1
  60. package/dist/src/input-actions.js +4 -3
  61. package/dist/src/install-artifact.js +1 -0
  62. package/dist/src/install-source.d.ts +5 -1
  63. package/dist/src/install-source.js +1 -1
  64. package/dist/src/install-source2.js +1 -1
  65. package/dist/src/interaction-snapshot.js +1 -1
  66. package/dist/src/interaction.d.ts +230 -0
  67. package/dist/src/interaction.js +1 -1
  68. package/dist/src/interactor.js +2 -2
  69. package/dist/src/internal/bin.js +1 -1
  70. package/dist/src/internal/daemon.js +42 -20
  71. package/dist/src/internal/png-worker.d.ts +22 -0
  72. package/dist/src/internal/png-worker.js +1 -1
  73. package/dist/src/launch-console.js +1 -0
  74. package/dist/src/lease-context.js +1 -0
  75. package/dist/src/lease.js +1 -1
  76. package/dist/src/linux.js +1 -1
  77. package/dist/src/logcat.js +5 -0
  78. package/dist/src/metro.d.ts +2 -2
  79. package/dist/src/notifications.js +1 -1
  80. package/dist/src/png-worker-contract.js +1 -1
  81. package/dist/src/process-lock.js +1 -0
  82. package/dist/src/react-native.js +1 -1
  83. package/dist/src/record-trace.js +1 -1
  84. package/dist/src/register-builtins.js +1 -0
  85. package/dist/src/registry.js +24 -24
  86. package/dist/src/reporting.js +8 -7
  87. package/dist/src/runner-client.js +1 -1
  88. package/dist/src/runner-disposal.js +2 -0
  89. package/dist/src/runner-lease.js +1 -0
  90. package/dist/src/runner-sequence.js +1 -1
  91. package/dist/src/runtime.js +3 -3
  92. package/dist/src/runtime2.js +1 -0
  93. package/dist/src/sdk-android-adb.d.ts +119 -33
  94. package/dist/src/sdk-android-adb.js +2 -2
  95. package/dist/src/sdk-batch-runner.d.ts +2 -1
  96. package/dist/src/sdk-batch-runner.js +2 -2
  97. package/dist/src/sdk-batch.js +2 -2
  98. package/dist/src/sdk-contracts.d.ts +105 -98
  99. package/dist/src/sdk-contracts.js +1 -1
  100. package/dist/src/sdk-device.js +1 -1
  101. package/dist/src/sdk-finders.d.ts +3 -3
  102. package/dist/src/sdk-finders.js +1 -1
  103. package/dist/src/sdk-io.d.ts +1 -1
  104. package/dist/src/sdk-remote-config.d.ts +9 -1
  105. package/dist/src/sdk-remote-config.js +1 -1
  106. package/dist/src/sdk-selectors.js +1 -1
  107. package/dist/src/selector-runtime.js +1 -1
  108. package/dist/src/selector-vocabulary.js +1 -0
  109. package/dist/src/selectors.d.ts +12 -3
  110. package/dist/src/selectors.js +1 -1
  111. package/dist/src/server.js +3 -3
  112. package/dist/src/session-target-evidence.js +1 -0
  113. package/dist/src/session.js +8 -10
  114. package/dist/src/simulator.js +1 -1
  115. package/dist/src/snapshot-diagnostics.js +5 -2
  116. package/dist/src/snapshot.js +1 -1
  117. package/dist/src/snapshot2.js +1 -2
  118. package/dist/src/tv-remote.js +13 -12
  119. package/dist/src/url.js +1 -1
  120. package/dist/src/web.js +1 -1
  121. package/package.json +28 -23
  122. package/server.json +2 -2
  123. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.apk +0 -0
  124. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.apk.sha256 +0 -1
  125. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.19.3.manifest.json +0 -10
  126. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.apk +0 -0
  127. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.19.3.apk.sha256 +0 -1
  128. package/dist/src/apple-runner-options.js +0 -1
  129. package/dist/src/cli-output.js +0 -1
  130. package/dist/src/client.js +0 -3
  131. package/dist/src/handler-utils.js +0 -1
  132. package/dist/src/output-path.js +0 -1
  133. package/dist/src/points.js +0 -4
  134. package/dist/src/provider.js +0 -1
  135. package/dist/src/providers.js +0 -1
  136. package/dist/src/record-trace-recording.js +0 -23
  137. package/dist/src/recording-provider.js +0 -1
  138. package/dist/src/selectors2.js +0 -1
  139. package/dist/src/simctl.js +0 -1
  140. package/dist/src/ttl-memo.js +0 -1
  141. package/dist/src/xml.js +0 -2
  142. /package/{macos-helper → apple/macos-helper}/Package.swift +0 -0
  143. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +0 -0
  144. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/SnapshotTraversal.swift +0 -0
  145. /package/{macos-helper → apple/macos-helper}/Sources/AgentDeviceMacOSHelper/main.swift +0 -0
  146. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +0 -0
  147. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +0 -0
  148. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  149. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  150. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  151. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  152. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  153. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  154. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTapPointPolicy.swift +0 -0
  155. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +0 -0
  156. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  157. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  158. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +0 -0
  159. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Navigation.swift +0 -0
  160. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  161. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +0 -0
  162. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
  163. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  164. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  165. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  166. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  167. /package/dist/{apple-runner → apple/runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
  168. /package/{src/platforms/linux → linux}/atspi-dump.py +0 -0
@@ -1,36 +1,11 @@
1
- import { A as AppError, B as PlatformSelector, C as SnapshotQualityVerdict, D as centerOfRect, E as SnapshotVisibility, I as AppleOS, L as DeviceKind, N as isAgentDeviceError, O as DebugSymbolsOptions, P as normalizeAgentDeviceError, R as DeviceTarget, S as SnapshotNode, T as SnapshotUnchanged, V as PublicPlatform, _ as ResponseLevel, a as DaemonRequest, b as Point, g as NetworkIncludeMode, i as DaemonLockPolicy, j as NormalizedError, k as DebugSymbolsResult, o as DaemonResponse, p as LeaseBackend, r as DaemonInstallSource, s as DaemonResponseData, t as DaemonArtifactType, v as SessionIsolationMode, x as ScreenshotOverlayRef, y as SessionRuntimeHints } from "./sdk-contracts.js";
1
+ import { B as DeviceKind, C as DebugSymbolsResult, D as isAgentDeviceError, I as SnapshotUnchanged, L as SnapshotVisibility, M as ScreenshotOverlayRef, N as SnapshotNode, O as normalizeAgentDeviceError, P as SnapshotQualityVerdict, R as centerOfRect, S as DebugSymbolsOptions, T as NormalizedError, U as PlatformSelector, V as DeviceTarget, W as PublicPlatform, _ as NetworkIncludeMode, a as DaemonLockPolicy, b as SessionIsolationMode, c as DaemonResponseData, i as DaemonInstallSource, m as LeaseBackend, n as DaemonArtifactType, o as DaemonRequest, r as DaemonError, s as DaemonResponse, t as DaemonArtifact, w as AppError, x as SessionRuntimeHints, y as ResponseLevel, z as AppleOS } from "./sdk-contracts.js";
2
+ import { a as GesturePointerCount, c as SwipePreset, l as TransformGestureParams, o as ScrollDirection, s as SwipePattern, u as AndroidSnapshotBackendMetadata } from "./sdk-android-adb.js";
2
3
  import { t as AppsFilter } from "./sdk-app-inventory.js";
3
4
  import { t as BatchRunResult } from "./sdk-batch-runner.js";
4
5
  import { r as FindLocator } from "./sdk-finders.js";
6
+ import { a as LongPressCommandResponseData, i as FindCommandResponseData, o as PressCommandResponseData, r as FillCommandResponseData, s as ClickButton, t as ClickCommandResponseData } from "./interaction.js";
5
7
  import { p as createLocalArtifactAdapter } from "./sdk-io.js";
6
8
  import { a as PrepareMetroRuntimeResult, c as MetroBridgeScope, i as MetroPrepareKind, o as ReloadMetroResult, r as RemoteConnectionProfileFields, t as CloudProviderProfileFields } from "./sdk-remote-config.js";
7
- //#region src/platforms/android/snapshot-helper-types.d.ts
8
- type AndroidSnapshotHelperTransport = 'instrumentation' | 'persistent-session';
9
- type AndroidSnapshotCaptureMode = 'interactive-windows' | 'active-window';
10
- type AndroidSnapshotHelperInstallReason = 'missing' | 'outdated' | 'forced' | 'current' | 'skipped';
11
- //#endregion
12
- //#region src/platforms/android/snapshot-types.d.ts
13
- type AndroidSnapshotBackendMetadata = {
14
- backend: 'android-helper' | 'uiautomator-dump';
15
- helperVersion?: string;
16
- helperApiVersion?: string;
17
- helperTransport?: AndroidSnapshotHelperTransport;
18
- helperSessionReused?: boolean;
19
- fallbackReason?: string;
20
- installReason?: AndroidSnapshotHelperInstallReason;
21
- waitForIdleTimeoutMs?: number;
22
- waitForIdleQuietMs?: number;
23
- timeoutMs?: number;
24
- maxDepth?: number;
25
- maxNodes?: number;
26
- rootPresent?: boolean;
27
- captureMode?: AndroidSnapshotCaptureMode;
28
- windowCount?: number;
29
- nodeCount?: number;
30
- helperTruncated?: boolean;
31
- elapsedMs?: number;
32
- };
33
- //#endregion
34
9
  //#region src/snapshot-capture-annotations.d.ts
35
10
  type SnapshotCaptureAnalysis = {
36
11
  rawNodeCount: number;
@@ -68,27 +43,15 @@ type SnapshotDiagnosticsSummary = {
68
43
  warning?: string;
69
44
  };
70
45
  //#endregion
71
- //#region src/core/back-mode.d.ts
46
+ //#region src/contracts/back-mode.d.ts
72
47
  declare const BACK_MODES: readonly ['in-app', 'system'];
73
48
  type BackMode = (typeof BACK_MODES)[number];
74
49
  //#endregion
75
- //#region src/core/click-button.d.ts
76
- declare const CLICK_BUTTONS: readonly ['primary', 'secondary', 'middle'];
77
- type ClickButton = (typeof CLICK_BUTTONS)[number];
78
- //#endregion
79
- //#region src/core/recording-export-quality.d.ts
80
- declare const RECORDING_EXPORT_QUALITIES: readonly ['medium', 'high'];
81
- type RecordingExportQuality = (typeof RECORDING_EXPORT_QUALITIES)[number];
82
- //#endregion
83
- //#region src/core/recording-scope.d.ts
84
- declare const RECORDING_SCOPE_VALUES: readonly ['app', 'device', 'system'];
85
- type RecordingScope = (typeof RECORDING_SCOPE_VALUES)[number];
86
- //#endregion
87
- //#region src/core/device-rotation.d.ts
50
+ //#region src/contracts/device-rotation.d.ts
88
51
  declare const DEVICE_ROTATIONS: readonly ['portrait', 'portrait-upside-down', 'landscape-left', 'landscape-right'];
89
52
  type DeviceRotation = (typeof DEVICE_ROTATIONS)[number];
90
53
  //#endregion
91
- //#region src/core/tv-remote.d.ts
54
+ //#region src/contracts/tv-remote.d.ts
92
55
  declare const TV_REMOTE_BUTTON_DEFINITIONS: {
93
56
  readonly up: {
94
57
  readonly aliases: readonly [];
@@ -134,23 +97,65 @@ declare const TV_REMOTE_BUTTON_DEFINITIONS: {
134
97
  declare const TV_REMOTE_BUTTONS: (keyof typeof TV_REMOTE_BUTTON_DEFINITIONS)[];
135
98
  type TvRemoteButton = (typeof TV_REMOTE_BUTTONS)[number];
136
99
  //#endregion
137
- //#region src/core/scroll-gesture.d.ts
138
- declare const SCROLL_DIRECTIONS: readonly ['up', 'down', 'left', 'right'];
139
- type ScrollDirection = (typeof SCROLL_DIRECTIONS)[number];
140
- declare const SWIPE_PRESETS: readonly ['left', 'right', 'left-edge', 'right-edge'];
141
- type SwipePreset = (typeof SWIPE_PRESETS)[number];
142
- declare const SWIPE_PATTERNS: readonly ['one-way', 'ping-pong'];
143
- type SwipePattern = (typeof SWIPE_PATTERNS)[number];
144
- type TransformGestureParams = {
145
- x: number;
146
- y: number;
147
- dx: number;
148
- dy: number;
149
- scale: number;
150
- degrees: number;
100
+ //#region src/contracts/navigation.d.ts
101
+ /**
102
+ * Closed results of the navigation/global action commands. Each mirrors the
103
+ * dispatch handler's literal return EXACTLY (src/core/dispatch.ts
104
+ * `DISPATCH_HANDLERS`): a fixed `action` discriminant plus the always-present
105
+ * `successText` message (the handlers always pass a non-empty message, so it is
106
+ * required here). The handlers spread nothing else, so the shapes are closed —
107
+ * consistent with the `viewport` contract, the generic-dispatch Android
108
+ * dialog-recovery `warning` annotation is intentionally not part of the contract.
109
+ */
110
+ /** `home` — `{ action: 'home', message: 'Home' }`. */
111
+ type HomeCommandResult = {
112
+ action: 'home';
113
+ message: string;
114
+ };
115
+ /** `back` — `{ action: 'back', mode, message: 'Back' }`; `mode` defaults to `'in-app'`. */
116
+ type BackCommandResult = {
117
+ action: 'back';
118
+ mode: BackMode;
119
+ message: string;
120
+ };
121
+ /** `orientation` — `{ action: 'orientation', orientation, message: 'Rotated to <orientation>' }`. */
122
+ type OrientationCommandResult = {
123
+ action: 'orientation';
124
+ orientation: DeviceRotation;
125
+ message: string;
126
+ };
127
+ /**
128
+ * @deprecated The `rotate` command was renamed to `orientation`. This is the
129
+ * legacy response contract (`action: 'rotate'`) that shipped in v0.18/v0.19,
130
+ * retained for existing SDK consumers until the next major version. New code
131
+ * should use {@link OrientationCommandResult}.
132
+ */
133
+ type RotateCommandResult = {
134
+ action: 'rotate';
135
+ orientation: DeviceRotation;
136
+ message: string;
137
+ };
138
+ /** `app-switcher` — `{ action: 'app-switcher', message: 'Opened app switcher' }`. */
139
+ type AppSwitcherCommandResult = {
140
+ action: 'app-switcher';
141
+ message: string;
142
+ };
143
+ /** `tv-remote` — `{ action: 'tv-remote', button, durationMs?, message }`. */
144
+ type TvRemoteCommandResult = {
145
+ action: 'tv-remote';
146
+ button: TvRemoteButton;
151
147
  durationMs?: number;
148
+ message: string;
152
149
  };
153
150
  //#endregion
151
+ //#region src/core/recording-export-quality.d.ts
152
+ declare const RECORDING_EXPORT_QUALITIES: readonly ['medium', 'high'];
153
+ type RecordingExportQuality = (typeof RECORDING_EXPORT_QUALITIES)[number];
154
+ //#endregion
155
+ //#region src/contracts/recording-scope.d.ts
156
+ declare const RECORDING_SCOPE_VALUES: readonly ['app', 'device', 'system'];
157
+ type RecordingScope = (typeof RECORDING_SCOPE_VALUES)[number];
158
+ //#endregion
154
159
  //#region src/alert-contract.d.ts
155
160
  declare const ALERT_ACTIONS: readonly ['get', 'accept', 'dismiss', 'wait'];
156
161
  type AlertAction = (typeof ALERT_ACTIONS)[number];
@@ -162,7 +167,27 @@ type JsonObject = {
162
167
  [key: string]: JsonValue;
163
168
  };
164
169
  //#endregion
165
- //#region src/core/session-surface.d.ts
170
+ //#region src/commands/command-contract.d.ts
171
+ type JsonSchema = {
172
+ type?: string | readonly string[];
173
+ description?: string;
174
+ properties?: Record<string, JsonSchema>;
175
+ required?: readonly string[];
176
+ additionalProperties?: boolean | JsonSchema;
177
+ items?: JsonSchema;
178
+ prefixItems?: readonly JsonSchema[];
179
+ oneOf?: readonly JsonSchema[];
180
+ enum?: readonly unknown[];
181
+ const?: unknown;
182
+ minimum?: number;
183
+ maximum?: number;
184
+ };
185
+ type ExecutableCommandProjection<ClientMethod extends string = string> = {
186
+ clientMethod: ClientMethod;
187
+ outputSchema: JsonSchema;
188
+ };
189
+ //#endregion
190
+ //#region src/contracts/session-surface.d.ts
166
191
  declare const SESSION_SURFACES: readonly ['app', 'frontmost-app', 'desktop', 'menubar'];
167
192
  type SessionSurface = (typeof SESSION_SURFACES)[number];
168
193
  //#endregion
@@ -177,161 +202,38 @@ type ScreenshotResultData = {
177
202
  overlayRefs?: ScreenshotOverlayRef[];
178
203
  };
179
204
  //#endregion
180
- //#region src/contracts/interaction.d.ts
181
- type ResolvedTarget = {
182
- kind: 'selector';
183
- selector: string;
184
- } | {
185
- kind: 'ref';
186
- ref: string;
187
- };
188
- type ResolvedInteractionTarget = {
189
- kind: 'point';
190
- point: Point;
191
- preActionNodes?: SnapshotNode[];
192
- } | {
193
- kind: 'ref';
194
- point?: Point;
195
- target: Extract<ResolvedTarget, {
196
- kind: 'ref';
197
- }>;
198
- node?: SnapshotNode;
199
- selectorChain?: string[];
200
- refLabel?: string;
201
- targetHittable?: boolean;
202
- hint?: string;
203
- preActionNodes?: SnapshotNode[];
204
- } | {
205
- kind: 'selector';
206
- point: Point;
207
- target: Extract<ResolvedTarget, {
208
- kind: 'selector';
209
- }>;
210
- node: SnapshotNode;
211
- selectorChain: string[];
212
- refLabel?: string;
213
- targetHittable?: boolean;
214
- hint?: string;
215
- preActionNodes?: SnapshotNode[];
216
- };
217
- /**
218
- * Opt-in (`--verify`) cheap post-condition evidence for mutating interaction
219
- * commands (#1047). `digest`/`nodeCount`/`interactiveNodeCount` describe a single
220
- * interactive-only capture taken right after the action; `changedFromBefore`
221
- * compares that digest against the pre-action capture the resolution path already
222
- * held, so no extra device round trip is spent beyond the one verify capture.
223
- * `changedFromBefore: false` is evidence, not failure — the command still
224
- * succeeded.
225
- */
226
- type InteractionEvidence = {
227
- foregroundApp?: string;
228
- nodeCount: number;
229
- interactiveNodeCount: number;
230
- digest: string;
231
- changedFromBefore: boolean;
232
- };
233
- type SettleDiffLine = {
234
- kind: 'added' | 'removed';
235
- text: string;
236
- /**
237
- * Plain ref body (`e12`) for ADDED lines: minted from the settled tree that
238
- * became the stored session snapshot, so it is immediately actionable and
239
- * lets the MCP layer pin it at `refsGeneration`. Removed lines never carry
240
- * one — their refs name nodes of the replaced tree.
241
- */
242
- ref?: string;
243
- };
244
- /**
245
- * One still-present, actionable element on the settled tree, surfaced by the
246
- * unchanged-interactive tail (see `SettleObservation.tail`).
247
- */
248
- type SettleTailEntry = {
249
- ref: string;
250
- role: string;
251
- label?: string;
252
- };
253
- type SettleObservation = {
254
- settled: boolean;
255
- waitedMs: number;
256
- captures: number;
257
- quietMs: number;
258
- timeoutMs: number;
259
- /**
260
- * The session's snapshot generation after the settled tree became the stored
261
- * snapshot (#1076 versioned refs). Attached by the daemon response layer
262
- * when `diff` is present: added lines carry refs minted from that tree, so
263
- * the response is ref-issuing — the MCP layer merges per-ref pins from it
264
- * exactly like snapshot/find responses.
265
- */
266
- refsGeneration?: number;
267
- /**
268
- * Digest response view only: capped added-line refs preserved without the
269
- * verbose diff line text, so MCP can still pin refs when `diff.lines` is
270
- * intentionally omitted.
271
- */
272
- refs?: Array<{
273
- ref: string;
274
- }>;
275
- /** Present only for `settled: true` observations that stored the settled tree. */
276
- diff?: {
277
- summary: {
278
- additions: number;
279
- removals: number;
280
- unchanged: number;
281
- };
282
- lines: SettleDiffLine[];
283
- /** Present (true) when lines were capped to the response bound. */
284
- truncated?: boolean;
285
- };
286
- /**
287
- * Unchanged interactive refs tail: benchmarks (July 2026) showed 27% of
288
- * `--settle` actions were followed by a fallback `snapshot -i` because a
289
- * change-only diff omits refs for elements that did not change — after a
290
- * modal dismiss the diff shows only removals, and the next button to press
291
- * (already on screen, untouched) is absent from the response. `tail` lists
292
- * the settled tree's remaining uncovered interactive elements (excluding
293
- * structural application/window chrome and the keyboard window's chrome)
294
- * so the response stays actionable without that extra round trip. Attached
295
- * ONLY when `diff` carries zero added-line refs naming a NEW target (the
296
- * modal-dismiss/toast-only/fill signature) — a diff whose added refs hand
297
- * the next target already pays its way, so the tail would be pure byte
298
- * cost. Keyboard-chrome refs and self-echo refs (added lines whose node
299
- * contains the action point: the acted-on element re-describing itself,
300
- * e.g. a filled field re-labeled with its new value) do not count as new
301
- * targets. Refs already present on `diff`'s added lines are excluded.
302
- * Capped; `tailTruncated` marks when candidates exceeded the cap.
303
- */
304
- tail?: SettleTailEntry[];
305
- tailTruncated?: true;
306
- hint?: string;
307
- };
308
- type PressCommandResult = ResolvedInteractionTarget & {
309
- backendResult?: Record<string, unknown>;
310
- message?: string;
311
- warning?: string;
312
- evidence?: InteractionEvidence;
313
- settle?: SettleObservation;
314
- };
315
- type FillCommandResult = ResolvedInteractionTarget & {
316
- text: string;
317
- warning?: string;
318
- backendResult?: Record<string, unknown>;
319
- message?: string;
320
- evidence?: InteractionEvidence;
321
- settle?: SettleObservation;
322
- };
323
- type LongPressCommandResult = ResolvedInteractionTarget & {
324
- durationMs?: number;
325
- backendResult?: Record<string, unknown>;
326
- message?: string;
327
- warning?: string;
328
- settle?: SettleObservation;
329
- };
330
- //#endregion
331
205
  //#region src/commands/interaction/runtime/gestures.d.ts
332
206
  declare const SCROLL_INPUT_DIRECTIONS: readonly ['up', 'down', 'left', 'right', 'top', 'bottom'];
333
207
  type ScrollInputDirection = (typeof SCROLL_INPUT_DIRECTIONS)[number];
334
208
  //#endregion
209
+ //#region src/commands/system/navigation-projection.d.ts
210
+ declare const navigationCommandProjectionType: unique symbol;
211
+ type NavigationCommandProjection<Options, Result, Required extends boolean, ClientMethod extends string> = ExecutableCommandProjection<ClientMethod> & {
212
+ readonly [navigationCommandProjectionType]?: {
213
+ options: Options;
214
+ result: Result;
215
+ required: Required;
216
+ };
217
+ };
218
+ declare const NAVIGATION_COMMAND_PROJECTIONS: {
219
+ readonly back: NavigationCommandProjection<{
220
+ mode?: BackMode;
221
+ }, BackCommandResult, false, "back">;
222
+ readonly home: NavigationCommandProjection<{}, HomeCommandResult, false, "home">;
223
+ readonly orientation: NavigationCommandProjection<{
224
+ orientation: DeviceRotation;
225
+ }, OrientationCommandResult, true, "orientation">;
226
+ readonly 'app-switcher': NavigationCommandProjection<{}, AppSwitcherCommandResult, false, "appSwitcher">;
227
+ readonly 'tv-remote': NavigationCommandProjection<{
228
+ button: TvRemoteButton;
229
+ durationMs?: number;
230
+ }, TvRemoteCommandResult, true, "tvRemote">;
231
+ };
232
+ type NavigationCommandName = keyof typeof NAVIGATION_COMMAND_PROJECTIONS;
233
+ type NavigationCommandOptions<Name extends NavigationCommandName> = (typeof NAVIGATION_COMMAND_PROJECTIONS)[Name] extends NavigationCommandProjection<infer Options, unknown, boolean, string> ? Options : never;
234
+ type ProjectedNavigationCommandMethod<BaseOptions, Projection> = Projection extends NavigationCommandProjection<infer Options, infer Result, infer Required, string> ? Required extends true ? (options: BaseOptions & Options) => Promise<Result> : (options?: BaseOptions & Options) => Promise<Result> : never;
235
+ type ProjectedNavigationCommandClient<BaseOptions> = { [Name in NavigationCommandName as (typeof NAVIGATION_COMMAND_PROJECTIONS)[Name]['clientMethod']]: ProjectedNavigationCommandMethod<BaseOptions, (typeof NAVIGATION_COMMAND_PROJECTIONS)[Name]>; };
236
+ //#endregion
335
237
  //#region src/contracts/logs.d.ts
336
238
  declare const LOG_ACTION_VALUES: readonly ['path', 'start', 'stop', 'doctor', 'mark', 'clear'];
337
239
  type LogAction = (typeof LOG_ACTION_VALUES)[number];
@@ -417,46 +319,6 @@ type ViewportCommandResult = {
417
319
  message: string;
418
320
  };
419
321
  //#endregion
420
- //#region src/contracts/navigation.d.ts
421
- /**
422
- * Closed results of the navigation/global action commands. Each mirrors the
423
- * dispatch handler's literal return EXACTLY (src/core/dispatch.ts
424
- * `DISPATCH_HANDLERS`): a fixed `action` discriminant plus the always-present
425
- * `successText` message (the handlers always pass a non-empty message, so it is
426
- * required here). The handlers spread nothing else, so the shapes are closed —
427
- * consistent with the `viewport` contract, the generic-dispatch Android
428
- * dialog-recovery `warning` annotation is intentionally not part of the contract.
429
- */
430
- /** `home` — `{ action: 'home', message: 'Home' }`. */
431
- type HomeCommandResult = {
432
- action: 'home';
433
- message: string;
434
- };
435
- /** `back` — `{ action: 'back', mode, message: 'Back' }`; `mode` defaults to `'in-app'`. */
436
- type BackCommandResult = {
437
- action: 'back';
438
- mode: BackMode;
439
- message: string;
440
- };
441
- /** `rotate` — `{ action: 'rotate', orientation, message: 'Rotated to <orientation>' }`. */
442
- type RotateCommandResult = {
443
- action: 'rotate';
444
- orientation: DeviceRotation;
445
- message: string;
446
- };
447
- /** `app-switcher` — `{ action: 'app-switcher', message: 'Opened app switcher' }`. */
448
- type AppSwitcherCommandResult = {
449
- action: 'app-switcher';
450
- message: string;
451
- };
452
- /** `tv-remote` — `{ action: 'tv-remote', button, durationMs?, message }`. */
453
- type TvRemoteCommandResult = {
454
- action: 'tv-remote';
455
- button: TvRemoteButton;
456
- durationMs?: number;
457
- message: string;
458
- };
459
- //#endregion
460
322
  //#region src/contracts/clipboard.d.ts
461
323
  /**
462
324
  * Closed result of the `clipboard` command. Mirrors the dispatch handler's
@@ -613,6 +475,172 @@ type TriggerAppEventCommandResult = {
613
475
  message: string;
614
476
  };
615
477
  //#endregion
478
+ //#region src/contracts/doctor.d.ts
479
+ type DoctorStatus = 'pass' | 'warn' | 'fail' | 'info';
480
+ type DoctorKind = 'auto' | 'react-native' | 'expo' | 'repack';
481
+ type DoctorCheck = {
482
+ id: string;
483
+ status: DoctorStatus;
484
+ summary: string;
485
+ hint?: string;
486
+ command?: string;
487
+ evidence?: Record<string, unknown>;
488
+ };
489
+ type DoctorCommandResult = {
490
+ status: DoctorStatus;
491
+ summary: string;
492
+ kind: DoctorKind;
493
+ platform?: PlatformSelector;
494
+ target?: DeviceTarget;
495
+ targetApp?: string;
496
+ metro?: {
497
+ host: string;
498
+ port: number;
499
+ };
500
+ checks: DoctorCheck[];
501
+ };
502
+ //#endregion
503
+ //#region src/snapshot/snapshot-diff.d.ts
504
+ type SnapshotDiffLine = {
505
+ kind: 'added' | 'removed' | 'unchanged';
506
+ text: string;
507
+ /**
508
+ * Plain ref body (`e12`) of the CURRENT-tree node behind an added line.
509
+ * Only populated with `withRefs` (interaction `--settle`, #1101) so the
510
+ * `diff` command's wire shape stays byte-identical. Removed/unchanged lines
511
+ * never carry it: a removed line's ref names a node of the replaced tree.
512
+ */
513
+ ref?: string;
514
+ };
515
+ type SnapshotDiffSummary = {
516
+ additions: number;
517
+ removals: number;
518
+ unchanged: number;
519
+ };
520
+ //#endregion
521
+ //#region src/contracts/diff.d.ts
522
+ type DiffSnapshotCommandResult = {
523
+ mode: 'snapshot';
524
+ baselineInitialized: boolean;
525
+ summary: SnapshotDiffSummary;
526
+ lines: SnapshotDiffLine[];
527
+ warnings?: string[];
528
+ };
529
+ //#endregion
530
+ //#region src/contracts/recording.d.ts
531
+ type RecordingAppIdentity = {
532
+ bundleId: string;
533
+ name?: string;
534
+ };
535
+ type RecordingStartCommandResult = {
536
+ recording: 'started';
537
+ outPath: string;
538
+ sessionStateDir: string;
539
+ recordingBackend?: string;
540
+ recordingScope?: RecordingScope;
541
+ recordOnlySession?: boolean;
542
+ activeSessionApp?: RecordingAppIdentity;
543
+ showTouches: boolean;
544
+ };
545
+ type RecordingStopCommandResult = {
546
+ recording: 'stopped';
547
+ outPath: string;
548
+ telemetryPath?: string;
549
+ artifacts: DaemonArtifact[];
550
+ recordingBackend?: string;
551
+ recordingScope?: RecordingScope;
552
+ recordOnlySession?: boolean;
553
+ activeSessionApp?: RecordingAppIdentity;
554
+ durationMs: number;
555
+ showTouches: boolean;
556
+ warning?: string;
557
+ overlayWarning?: string;
558
+ chunks?: Array<{
559
+ index: number;
560
+ path: string;
561
+ }>;
562
+ };
563
+ type RecordingCommandResult = RecordingStartCommandResult | RecordingStopCommandResult;
564
+ type TraceCommandResult = {
565
+ trace: 'started';
566
+ outPath: string;
567
+ } | {
568
+ trace: 'stopped';
569
+ outPath: string;
570
+ };
571
+ //#endregion
572
+ //#region src/contracts/replay.d.ts
573
+ type ReplayCommandResult = {
574
+ replayed: number;
575
+ healed: number;
576
+ session: string;
577
+ artifactPaths: string[];
578
+ warnings?: string[];
579
+ snapshotDiagnostics?: SnapshotDiagnosticsSummary;
580
+ message: string;
581
+ };
582
+ type ReplaySuiteTestSkipReason = 'skipped-by-filter';
583
+ type ReplaySuiteAttemptFailure = {
584
+ attempt: number;
585
+ message: string;
586
+ durationMs?: number;
587
+ };
588
+ type ReplaySuiteTestPassed = {
589
+ file: string;
590
+ title?: string;
591
+ session: string;
592
+ status: 'passed';
593
+ durationMs: number;
594
+ finalAttemptDurationMs?: number;
595
+ attempts: number;
596
+ artifactsDir?: string;
597
+ replayed: number;
598
+ healed: number;
599
+ warnings?: string[];
600
+ attemptFailures?: ReplaySuiteAttemptFailure[];
601
+ shardIndex?: number;
602
+ shardCount?: number;
603
+ deviceId?: string;
604
+ deviceName?: string;
605
+ snapshotDiagnostics?: SnapshotDiagnosticsSummary;
606
+ };
607
+ type ReplaySuiteTestFailed = {
608
+ file: string;
609
+ title?: string;
610
+ session: string;
611
+ status: 'failed';
612
+ durationMs: number;
613
+ attempts: number;
614
+ artifactsDir?: string;
615
+ error: DaemonError;
616
+ shardIndex?: number;
617
+ shardCount?: number;
618
+ deviceId?: string;
619
+ deviceName?: string;
620
+ snapshotDiagnostics?: SnapshotDiagnosticsSummary;
621
+ };
622
+ type ReplaySuiteTestSkipped = {
623
+ file: string;
624
+ title?: string;
625
+ status: 'skipped';
626
+ durationMs: 0;
627
+ reason: ReplaySuiteTestSkipReason;
628
+ message: string;
629
+ };
630
+ type ReplaySuiteTestResult = ReplaySuiteTestPassed | ReplaySuiteTestFailed | ReplaySuiteTestSkipped;
631
+ type ReplaySuiteResult = {
632
+ total: number;
633
+ executed: number;
634
+ passed: number;
635
+ failed: number;
636
+ skipped: number;
637
+ notRun: number;
638
+ durationMs: number;
639
+ failures: ReplaySuiteTestFailed[];
640
+ tests: ReplaySuiteTestResult[];
641
+ snapshotDiagnostics?: SnapshotDiagnosticsSummary;
642
+ };
643
+ //#endregion
616
644
  //#region src/core/command-descriptor/command-result.d.ts
617
645
  /**
618
646
  * The additive typed-result spine (ADR-0008, Phase 1 step 6).
@@ -625,8 +653,8 @@ type TriggerAppEventCommandResult = {
625
653
  * invented shape.
626
654
  *
627
655
  * Batches 1-2 wired `boot` / `shutdown` / `viewport` and the navigation/action
628
- * commands `home` / `back` / `rotate` / `app-switcher` alongside the seed
629
- * interaction trio. Batch 3 adds `clipboard` (a closed `read`/`write` union) and
656
+ * commands `home` / `back` / `orientation` / `app-switcher` alongside the seed
657
+ * interaction quartet. Batch 3 adds `clipboard` (a closed `read`/`write` union) and
630
658
  * `appstate` (a closed `platform` union — Apple session state with the iOS-only
631
659
  * device locators, or Android package/activity). Batch 4 adds `keyboard` (a
632
660
  * closed flat shape). Batch 5 adds the compact daemon projections for `wait`,
@@ -634,15 +662,17 @@ type TriggerAppEventCommandResult = {
634
662
  * re-read of the handler's literal return; see the per-type docstrings.
635
663
  */
636
664
  interface CommandResultMap {
637
- press: PressCommandResult;
638
- fill: FillCommandResult;
639
- longpress: LongPressCommandResult;
665
+ press: PressCommandResponseData;
666
+ click: ClickCommandResponseData;
667
+ fill: FillCommandResponseData;
668
+ longpress: LongPressCommandResponseData;
669
+ find: FindCommandResponseData;
640
670
  boot: BootCommandResult;
641
671
  shutdown: ShutdownCommandResult;
642
672
  viewport: ViewportCommandResult;
643
673
  home: HomeCommandResult;
644
674
  back: BackCommandResult;
645
- rotate: RotateCommandResult;
675
+ orientation: OrientationCommandResult;
646
676
  'app-switcher': AppSwitcherCommandResult;
647
677
  clipboard: ClipboardCommandResult;
648
678
  appstate: AppStateCommandResult;
@@ -652,6 +682,12 @@ interface CommandResultMap {
652
682
  prepare: PrepareCommandResult;
653
683
  push: PushCommandResult;
654
684
  'trigger-app-event': TriggerAppEventCommandResult;
685
+ doctor: DoctorCommandResult;
686
+ diff: DiffSnapshotCommandResult;
687
+ replay: ReplayCommandResult;
688
+ test: ReplaySuiteResult;
689
+ record: RecordingCommandResult;
690
+ trace: TraceCommandResult;
655
691
  }
656
692
  /**
657
693
  * The typed result for a command named `N`. Seeded commands resolve to their
@@ -809,6 +845,23 @@ type SessionCloseResult = {
809
845
  session: string;
810
846
  shutdown?: TargetShutdownResult;
811
847
  provider?: CloudProviderSessionResult;
848
+ /**
849
+ * #1258: absolute path of the committed session/healed script when this close
850
+ * published one (`close --save-script`, or a repair-armed session's finalize)
851
+ * — so a client that requested publication learns where the file landed.
852
+ */
853
+ savedScript?: string;
854
+ identifiers: AgentDeviceIdentifiers;
855
+ };
856
+ type SessionSaveScriptOptions = AgentDeviceRequestOverrides & {
857
+ path?: string;
858
+ /** Atomically replace an existing target instead of refusing publication. */
859
+ force?: boolean;
860
+ };
861
+ type SessionSaveScriptResult = {
862
+ session: string;
863
+ savedScript: string;
864
+ actionCount: number;
812
865
  identifiers: AgentDeviceIdentifiers;
813
866
  };
814
867
  type CloudArtifactsOptions = AgentDeviceRequestOverrides & {
@@ -841,12 +894,16 @@ type AppOpenOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions
841
894
  launchArgs?: string[];
842
895
  relaunch?: boolean;
843
896
  saveScript?: boolean | string;
897
+ /** #1258: overwrite an existing --save-script target instead of refusing. Alias: --overwrite. */
898
+ force?: boolean;
844
899
  deviceHub?: boolean;
900
+ testIme?: boolean;
845
901
  noRecord?: boolean;
846
902
  runtime?: SessionRuntimeHints;
847
903
  };
848
904
  type AppOpenResult = {
849
905
  session: string;
906
+ warnings?: string[];
850
907
  sessionStateDir?: string;
851
908
  runnerLogPath?: string;
852
909
  requestLogPath?: string;
@@ -862,11 +919,20 @@ type AppOpenResult = {
862
919
  type AppCloseOptions = AgentDeviceRequestOverrides & {
863
920
  app?: string;
864
921
  shutdown?: boolean;
922
+ saveScript?: boolean | string;
923
+ /** #1258: overwrite an existing --save-script target instead of refusing. Alias: --overwrite. */
924
+ force?: boolean;
865
925
  };
866
926
  type AppCloseResult = {
867
927
  session: string;
868
928
  closedApp?: string;
869
929
  shutdown?: TargetShutdownResult;
930
+ /**
931
+ * #1258: absolute path of the committed session/healed script when this close
932
+ * published one (`close --save-script`, or a repair-armed session's finalize)
933
+ * — so a client that requested publication learns where the file landed.
934
+ */
935
+ savedScript?: string;
870
936
  identifiers: AgentDeviceIdentifiers;
871
937
  };
872
938
  type AppInstallFromSourceOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & {
@@ -966,6 +1032,13 @@ type CaptureSnapshotOptions = AgentDeviceRequestOverrides & AgentDeviceSelection
966
1032
  raw?: boolean;
967
1033
  forceFull?: boolean;
968
1034
  timeoutMs?: number;
1035
+ /**
1036
+ * #1271 stage 2 (ADR 0012 amendment): `snapshot` is observation-only and
1037
+ * excluded from a repair-armed heal by default; `record` forces it
1038
+ * through. Mutually exclusive with `noRecord`.
1039
+ */
1040
+ noRecord?: boolean;
1041
+ record?: boolean;
969
1042
  };
970
1043
  type CaptureSnapshotResult = {
971
1044
  nodes: SnapshotNode[];
@@ -976,6 +1049,21 @@ type CaptureSnapshotResult = {
976
1049
  unchanged?: SnapshotUnchanged;
977
1050
  snapshotDiagnostics?: SnapshotDiagnosticsSummary;
978
1051
  identifiers: AgentDeviceIdentifiers;
1052
+ /**
1053
+ * ADR 0014: the response-level ref-frame epoch the plain node refs were minted
1054
+ * from. A ref-issuing snapshot carries it ONCE (nodes stay plain `@e12` for the
1055
+ * token budget); pair a ref with it (`@e12~s<refsGeneration>`) before a mutation.
1056
+ */
1057
+ refsGeneration?: number;
1058
+ /**
1059
+ * Digest response view only: a capped list of `{ ref, label? }` pairs taken
1060
+ * from the full `nodes` tree so the MCP layer can still pin refs when the
1061
+ * default-level `nodes` payload is intentionally omitted.
1062
+ */
1063
+ refs?: Array<{
1064
+ ref: string;
1065
+ label?: string;
1066
+ }>;
979
1067
  } & PublicSnapshotCaptureAnnotations;
980
1068
  type CaptureScreenshotOptions = AgentDeviceRequestOverrides & {
981
1069
  path?: string;
@@ -1039,14 +1127,9 @@ type AlertCommandOptions = DeviceCommandBaseOptions & {
1039
1127
  timeoutMs?: number;
1040
1128
  };
1041
1129
  type AppStateCommandOptions = DeviceCommandBaseOptions;
1042
- type BackCommandOptions = DeviceCommandBaseOptions & {
1043
- mode?: BackMode;
1044
- };
1045
- type HomeCommandOptions = DeviceCommandBaseOptions;
1046
- type RotateCommandOptions = DeviceCommandBaseOptions & {
1047
- orientation: DeviceRotation;
1048
- };
1049
- type AppSwitcherCommandOptions = DeviceCommandBaseOptions;
1130
+ type OrientationCommandOptions = DeviceCommandBaseOptions & NavigationCommandOptions<'orientation'>;
1131
+ /** @deprecated Renamed to `OrientationCommandOptions`. Retained until the next major. */
1132
+ type RotateCommandOptions = OrientationCommandOptions;
1050
1133
  type KeyboardCommandOptions = DeviceCommandBaseOptions & {
1051
1134
  action?: 'status' | 'dismiss' | 'enter' | 'return';
1052
1135
  };
@@ -1056,10 +1139,6 @@ type ClipboardCommandOptions = (DeviceCommandBaseOptions & {
1056
1139
  action: 'write';
1057
1140
  text: string;
1058
1141
  });
1059
- type TvRemoteCommandOptions = DeviceCommandBaseOptions & {
1060
- button: TvRemoteButton;
1061
- durationMs?: number;
1062
- };
1063
1142
  type ReactNativeCommandOptions = DeviceCommandBaseOptions & {
1064
1143
  action: 'dismiss-overlay';
1065
1144
  };
@@ -1075,19 +1154,14 @@ type ViewportCommandOptions = DeviceCommandBaseOptions & {
1075
1154
  width: number;
1076
1155
  height: number;
1077
1156
  };
1078
- type AgentDeviceCommandClient = {
1157
+ type NonNavigationCommandClient = {
1079
1158
  wait: (options: WaitCommandOptions) => Promise<CommandResult<'wait'>>;
1080
1159
  alert: (options?: AlertCommandOptions) => Promise<CommandRequestResult>;
1081
1160
  appState: (options?: AppStateCommandOptions) => Promise<CommandResult<'appstate'>>;
1082
- back: (options?: BackCommandOptions) => Promise<CommandResult<'back'>>;
1083
- home: (options?: HomeCommandOptions) => Promise<CommandResult<'home'>>;
1084
- rotate: (options: RotateCommandOptions) => Promise<CommandResult<'rotate'>>;
1085
- appSwitcher: (options?: AppSwitcherCommandOptions) => Promise<CommandResult<'app-switcher'>>;
1086
1161
  keyboard: (options?: KeyboardCommandOptions) => Promise<CommandResult<'keyboard'>>;
1087
1162
  clipboard: (options: ClipboardCommandOptions) => Promise<CommandResult<'clipboard'>>;
1088
- tvRemote: (options: TvRemoteCommandOptions) => Promise<CommandResult<'tv-remote'>>;
1089
1163
  reactNative: (options: ReactNativeCommandOptions) => Promise<CommandRequestResult>;
1090
- doctor: (options?: DoctorCommandOptions) => Promise<CommandRequestResult>;
1164
+ doctor: (options?: DoctorCommandOptions) => Promise<CommandResult<'doctor'>>;
1091
1165
  /**
1092
1166
  * JSON prepare results include timing.additiveParts for additive wall-clock phases.
1093
1167
  * Top-level buildMs/connectMs/healthCheckMs are diagnostics and may overlap.
@@ -1095,6 +1169,15 @@ type AgentDeviceCommandClient = {
1095
1169
  prepare: (options: PrepareCommandOptions) => Promise<CommandResult<'prepare'>>;
1096
1170
  viewport: (options: ViewportCommandOptions) => Promise<CommandResult<'viewport'>>;
1097
1171
  };
1172
+ type AgentDeviceCommandClient = ProjectedNavigationCommandClient<DeviceCommandBaseOptions> & NonNavigationCommandClient & DeprecatedCommandClient;
1173
+ /** Renamed command methods retained for existing consumers until the next major. */
1174
+ type DeprecatedCommandClient = {
1175
+ /**
1176
+ * @deprecated Renamed to `orientation`. Delegates to it and returns the legacy
1177
+ * `action: 'rotate'` response contract. Retained until the next major version.
1178
+ */
1179
+ rotate: (options: RotateCommandOptions) => Promise<RotateCommandResult>;
1180
+ };
1098
1181
  type SelectorSnapshotCommandOptions = Pick<CaptureSnapshotOptions, 'depth' | 'scope' | 'raw'>;
1099
1182
  type FindSnapshotCommandOptions = Pick<CaptureSnapshotOptions, 'depth' | 'raw'>;
1100
1183
  type PointTarget = {
@@ -1180,7 +1263,6 @@ type SwipeOptions = DeviceCommandBaseOptions & {
1180
1263
  x: number;
1181
1264
  y: number;
1182
1265
  };
1183
- durationMs?: number;
1184
1266
  count?: number;
1185
1267
  pauseMs?: number;
1186
1268
  pattern?: SwipePattern;
@@ -1190,6 +1272,7 @@ type PanOptions = DeviceCommandBaseOptions & {
1190
1272
  y: number;
1191
1273
  dx: number;
1192
1274
  dy: number;
1275
+ pointerCount?: GesturePointerCount;
1193
1276
  durationMs?: number;
1194
1277
  };
1195
1278
  type FlingOptions = DeviceCommandBaseOptions & {
@@ -1197,11 +1280,9 @@ type FlingOptions = DeviceCommandBaseOptions & {
1197
1280
  x: number;
1198
1281
  y: number;
1199
1282
  distance?: number;
1200
- durationMs?: number;
1201
1283
  };
1202
1284
  type SwipeGestureOptions = DeviceCommandBaseOptions & {
1203
1285
  preset: SwipePreset;
1204
- durationMs?: number;
1205
1286
  };
1206
1287
  type FocusOptions = DeviceCommandBaseOptions & {
1207
1288
  x: number;
@@ -1231,24 +1312,33 @@ type RotateGestureOptions = DeviceCommandBaseOptions & {
1231
1312
  degrees: number;
1232
1313
  x?: number;
1233
1314
  y?: number;
1234
- velocity?: number;
1235
1315
  };
1236
1316
  type TransformGestureOptions = DeviceCommandBaseOptions & TransformGestureParams;
1237
- type GetOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & ElementTarget & {
1317
+ /**
1318
+ * #1271 stage 2 (ADR 0012 amendment): `get`/`is`/`find` are observation-only
1319
+ * and excluded from a repair-armed heal by default. `record` forces this
1320
+ * action through (the corrective-read case); `noRecord` continues to opt the
1321
+ * action out entirely. Mutually exclusive.
1322
+ */
1323
+ type RecordControlOptions = {
1324
+ noRecord?: boolean;
1325
+ record?: boolean;
1326
+ };
1327
+ type GetOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & ElementTarget & RecordControlOptions & {
1238
1328
  format: 'text' | 'attrs';
1239
1329
  };
1240
- type IsTextPredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & {
1330
+ type IsTextPredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & RecordControlOptions & {
1241
1331
  predicate: 'text';
1242
1332
  selector: string;
1243
1333
  value: string;
1244
1334
  };
1245
- type IsStatePredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & {
1335
+ type IsStatePredicateOptions = DeviceCommandBaseOptions & SelectorSnapshotCommandOptions & RecordControlOptions & {
1246
1336
  predicate: 'visible' | 'hidden' | 'exists' | 'editable' | 'selected' | 'focused';
1247
1337
  selector: string;
1248
1338
  value?: never;
1249
1339
  };
1250
1340
  type IsOptions = IsTextPredicateOptions | IsStatePredicateOptions;
1251
- type FindBaseOptions = DeviceCommandBaseOptions & FindSnapshotCommandOptions & {
1341
+ type FindBaseOptions = DeviceCommandBaseOptions & FindSnapshotCommandOptions & RecordControlOptions & {
1252
1342
  locator?: FindLocator;
1253
1343
  query: string;
1254
1344
  first?: boolean;
@@ -1265,15 +1355,40 @@ type FindOptions = (FindBaseOptions & {
1265
1355
  });
1266
1356
  type ReplayRunOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & {
1267
1357
  path: string;
1358
+ runtime?: SessionRuntimeHints;
1359
+ /**
1360
+ * @deprecated ADR 0012 migration step 6: `--update` no longer rewrites
1361
+ * the script. Accepted for backward compatibility; every divergence
1362
+ * already carries ranked selector suggestions regardless of this flag.
1363
+ */
1268
1364
  update?: boolean;
1269
1365
  /** @deprecated Use backend: 'maestro'. */
1270
1366
  maestro?: boolean;
1271
1367
  backend?: string;
1272
1368
  env?: string[];
1273
1369
  timeoutMs?: number;
1370
+ /**
1371
+ * ADR 0012 decision 4 / migration step 5: resume at this 1-based plan
1372
+ * step, skipping `1..resumeFrom-1` without executing them. Requires
1373
+ * `resumePlanDigest` from the divergence report that reported this
1374
+ * step as the failure. `replay` only — `test` has no resume fields.
1375
+ */
1376
+ resumeFrom?: number;
1377
+ /** The `resume.planDigest` from the divergence report `resumeFrom` came from. */
1378
+ resumePlanDigest?: string;
1379
+ /**
1380
+ * ADR 0012 decision 6, R1/R6: arms agent-supervised re-record repair
1381
+ * from this replay attempt onward. Optional string value is the healed
1382
+ * `.ad`'s output path; absent one, it defaults to the `<path>` sibling
1383
+ * `<stem>.healed.ad` when the repair ends with `close --save-script`.
1384
+ */
1385
+ saveScript?: boolean | string;
1386
+ /** #1258: overwrite an existing --save-script target instead of refusing. Alias: --overwrite. */
1387
+ force?: boolean;
1274
1388
  };
1275
1389
  type ReplayTestOptions = AgentDeviceRequestOverrides & AgentDeviceSelectionOptions & {
1276
1390
  paths: string[];
1391
+ runtime?: SessionRuntimeHints;
1277
1392
  update?: boolean;
1278
1393
  /** @deprecated Use backend: 'maestro'. */
1279
1394
  maestro?: boolean;
@@ -1387,7 +1502,11 @@ type AgentDeviceClient = {
1387
1502
  stateDir: (options?: AgentDeviceRequestOverrides & Pick<AgentDeviceClientConfig, 'stateDir'>) => Promise<string>;
1388
1503
  close: (options?: AgentDeviceRequestOverrides & {
1389
1504
  shutdown?: boolean;
1505
+ saveScript?: boolean | string;
1506
+ /** #1258: overwrite an existing --save-script target instead of refusing. Alias: --overwrite. */
1507
+ force?: boolean;
1390
1508
  }) => Promise<SessionCloseResult>;
1509
+ saveScript: (options?: SessionSaveScriptOptions) => Promise<SessionSaveScriptResult>;
1391
1510
  artifacts: (options?: CloudArtifactsOptions) => Promise<AgentArtifactsResult>;
1392
1511
  };
1393
1512
  apps: {
@@ -1418,30 +1537,30 @@ type AgentDeviceClient = {
1418
1537
  capture: {
1419
1538
  snapshot: (options?: CaptureSnapshotOptions) => Promise<CaptureSnapshotResult>;
1420
1539
  screenshot: (options?: CaptureScreenshotOptions) => Promise<CaptureScreenshotResult>;
1421
- diff: (options: CaptureDiffOptions) => Promise<CommandRequestResult>;
1540
+ diff: (options: CaptureDiffOptions) => Promise<CommandResult<'diff'>>;
1422
1541
  };
1423
1542
  interactions: {
1424
- click: (options: ClickOptions) => Promise<CommandRequestResult>;
1425
- press: (options: PressOptions) => Promise<CommandRequestResult>;
1426
- longPress: (options: LongPressOptions) => Promise<CommandRequestResult>;
1543
+ click: (options: ClickOptions) => Promise<CommandResult<'click'>>;
1544
+ press: (options: PressOptions) => Promise<CommandResult<'press'>>;
1545
+ longPress: (options: LongPressOptions) => Promise<CommandResult<'longpress'>>;
1427
1546
  swipe: (options: SwipeOptions) => Promise<CommandRequestResult>;
1428
1547
  pan: (options: PanOptions) => Promise<CommandRequestResult>;
1429
1548
  fling: (options: FlingOptions) => Promise<CommandRequestResult>;
1430
1549
  swipeGesture: (options: SwipeGestureOptions) => Promise<CommandRequestResult>;
1431
1550
  focus: (options: FocusOptions) => Promise<CommandRequestResult>;
1432
1551
  type: (options: TypeTextOptions) => Promise<CommandRequestResult>;
1433
- fill: (options: FillOptions) => Promise<CommandRequestResult>;
1552
+ fill: (options: FillOptions) => Promise<CommandResult<'fill'>>;
1434
1553
  scroll: (options: ScrollOptions) => Promise<CommandRequestResult>;
1435
1554
  pinch: (options: PinchOptions) => Promise<CommandRequestResult>;
1436
1555
  rotateGesture: (options: RotateGestureOptions) => Promise<CommandRequestResult>;
1437
1556
  transformGesture: (options: TransformGestureOptions) => Promise<CommandRequestResult>;
1438
1557
  get: (options: GetOptions) => Promise<CommandRequestResult>;
1439
1558
  is: (options: IsOptions) => Promise<CommandRequestResult>;
1440
- find: (options: FindOptions) => Promise<CommandRequestResult>;
1559
+ find: (options: FindOptions) => Promise<CommandResult<'find'>>;
1441
1560
  };
1442
1561
  replay: {
1443
- run: (options: ReplayRunOptions) => Promise<CommandRequestResult>;
1444
- test: (options: ReplayTestOptions) => Promise<CommandRequestResult>;
1562
+ run: (options: ReplayRunOptions) => Promise<CommandResult<'replay'>>;
1563
+ test: (options: ReplayTestOptions) => Promise<CommandResult<'test'>>;
1445
1564
  };
1446
1565
  batch: {
1447
1566
  run: (options: BatchRunOptions) => Promise<BatchRunResult>;
@@ -1457,15 +1576,15 @@ type AgentDeviceClient = {
1457
1576
  symbols: (options: DebugSymbolsOptions) => Promise<DebugSymbolsResult>;
1458
1577
  };
1459
1578
  recording: {
1460
- record: (options: RecordOptions) => Promise<CommandRequestResult>;
1461
- trace: (options: TraceOptions) => Promise<CommandRequestResult>;
1579
+ record: (options: RecordOptions) => Promise<CommandResult<'record'>>;
1580
+ trace: (options: TraceOptions) => Promise<CommandResult<'trace'>>;
1462
1581
  };
1463
1582
  settings: {
1464
1583
  update: (options: SettingsUpdateOptions) => Promise<CommandRequestResult>;
1465
1584
  };
1466
1585
  };
1467
1586
  //#endregion
1468
- //#region src/client/client.d.ts
1587
+ //#region src/agent-device-client.d.ts
1469
1588
  declare function createAgentDeviceClient(config?: AgentDeviceClientConfig, deps?: {
1470
1589
  transport?: AgentDeviceDaemonTransport;
1471
1590
  }): AgentDeviceClient;