agent-device 0.18.0 → 0.18.2

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 (159) hide show
  1. package/README.md +3 -2
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.0.apk → agent-device-android-multitouch-helper-0.18.2.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.2.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.18.0.manifest.json → agent-device-android-multitouch-helper-0.18.2.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.0.apk → agent-device-android-snapshot-helper-0.18.2.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.2.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.18.0.manifest.json → agent-device-android-snapshot-helper-0.18.2.manifest.json} +6 -6
  8. package/apple-runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.m +156 -0
  9. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.pbxproj +10 -16
  10. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+AXSnapshotFallback.swift +2 -0
  11. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +3 -1
  12. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandJournal.swift +2 -0
  13. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+FlatSnapshotFiltering.swift +2 -4
  14. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +9 -36
  15. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScrollGesture.swift +2 -0
  16. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SequenceExecution.swift +2 -0
  17. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Snapshot.swift +2 -0
  18. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SnapshotCapturePlan.swift +2 -0
  19. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TextEntry.swift +0 -1
  20. package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests.swift +2 -1
  21. package/dist/src/1986.js +1 -0
  22. package/dist/src/2748.js +1 -1
  23. package/dist/src/2948.js +21 -21
  24. package/dist/src/314.js +1 -1
  25. package/dist/src/3340.js +8 -7
  26. package/dist/src/4418.js +1 -1
  27. package/dist/src/4428.js +3 -3
  28. package/dist/src/485.js +1 -0
  29. package/dist/src/495.js +5 -0
  30. package/dist/src/5484.js +1 -1
  31. package/dist/src/587.js +1 -1
  32. package/dist/src/5913.js +4 -0
  33. package/dist/src/6849.js +1 -0
  34. package/dist/src/6918.js +1 -1
  35. package/dist/src/6967.js +1 -0
  36. package/dist/src/760.js +1 -0
  37. package/dist/src/7871.js +1 -0
  38. package/dist/src/8184.js +1 -1
  39. package/dist/src/8225.js +1 -1
  40. package/dist/src/8391.js +1 -0
  41. package/dist/src/8404.js +2 -0
  42. package/dist/src/8414.js +2 -0
  43. package/dist/src/8875.js +4 -1
  44. package/dist/src/8936.js +1 -1
  45. package/dist/src/9581.js +3 -3
  46. package/dist/src/9624.js +1 -1
  47. package/dist/src/9722.js +37 -32
  48. package/dist/src/android-adb.d.ts +19 -54
  49. package/dist/src/android-adb.js +1 -1
  50. package/dist/src/android.js +5 -5
  51. package/dist/src/apps.js +9 -11
  52. package/dist/src/audio-probe.js +1 -0
  53. package/dist/src/batch.d.ts +34 -26
  54. package/dist/src/batch.js +1 -1
  55. package/dist/src/cli-help.js +61 -9
  56. package/dist/src/cli.js +34 -22
  57. package/dist/src/contracts.d.ts +33 -123
  58. package/dist/src/contracts.js +1 -1
  59. package/dist/src/debug-symbols.js +3 -0
  60. package/dist/src/devices.js +1 -1
  61. package/dist/src/devices~1.js +1 -1
  62. package/dist/src/devices~2.js +1 -1
  63. package/dist/src/find.js +1 -1
  64. package/dist/src/finders.d.ts +2 -6
  65. package/dist/src/finders.js +1 -1
  66. package/dist/src/generic.js +1 -9
  67. package/dist/src/handler-utils.js +1 -0
  68. package/dist/src/index.d.ts +474 -180
  69. package/dist/src/index.js +1 -1
  70. package/dist/src/input-actions.js +1 -1
  71. package/dist/src/input-actions~1.js +1 -1
  72. package/dist/src/install-source.d.ts +0 -26
  73. package/dist/src/install-source.js +1 -1
  74. package/dist/src/interaction.js +1 -1
  75. package/dist/src/interactor.js +1 -0
  76. package/dist/src/internal/bin.js +1 -1
  77. package/dist/src/internal/companion-tunnel.js +1 -1
  78. package/dist/src/internal/png-worker.js +1 -1
  79. package/dist/src/lease.js +1 -1
  80. package/dist/src/linux.js +1 -1
  81. package/dist/src/metro.d.ts +10 -134
  82. package/dist/src/metro.js +1 -1
  83. package/dist/src/notifications.js +1 -1
  84. package/dist/src/react-native.js +1 -1
  85. package/dist/src/record-trace-recording.js +3 -3
  86. package/dist/src/record-trace.js +1 -1
  87. package/dist/src/remote-config.d.ts +15 -17
  88. package/dist/src/remote-config.js +1 -1
  89. package/dist/src/runner-sequence.js +1 -0
  90. package/dist/src/selector-runtime.js +1 -1
  91. package/dist/src/selectors.d.ts +15 -7
  92. package/dist/src/selectors.js +1 -1
  93. package/dist/src/server.js +2 -2
  94. package/dist/src/session.js +11 -11
  95. package/dist/src/simulator.js +2 -2
  96. package/dist/src/snapshot.js +2 -2
  97. package/dist/src/web.js +1 -1
  98. package/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +297 -0
  99. package/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +30 -0
  100. package/package.json +15 -11
  101. package/server.json +2 -2
  102. package/android-multitouch-helper/README.md +0 -41
  103. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.0.apk.sha256 +0 -1
  104. package/android-snapshot-helper/README.md +0 -88
  105. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.0.apk.sha256 +0 -1
  106. package/dist/src/1848.js +0 -4
  107. package/dist/src/2577.js +0 -1
  108. package/dist/src/2954.js +0 -2
  109. package/dist/src/4291.js +0 -1
  110. package/dist/src/432.js +0 -4
  111. package/dist/src/4723.js +0 -1
  112. package/dist/src/5341.js +0 -1
  113. package/dist/src/5910.js +0 -2
  114. package/dist/src/6024.js +0 -1
  115. package/dist/src/733.js +0 -1
  116. package/dist/src/7394.js +0 -6
  117. package/dist/src/8275.js +0 -2
  118. package/dist/src/9919.js +0 -6
  119. package/dist/src/android-snapshot-helper.d.ts +0 -359
  120. package/dist/src/android-snapshot-helper.js +0 -1
  121. package/dist/src/apple.js +0 -1
  122. package/dist/src/device-ready.js +0 -2
  123. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/AgentDeviceRunnerApp.swift +0 -17
  124. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AccentColor.colorset/Contents.json +0 -11
  125. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -36
  126. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/AppIcon.appiconset/logo.jpg +0 -0
  127. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Contents.json +0 -6
  128. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Logo.imageset/Contents.json +0 -21
  129. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/Logo.imageset/logo.jpg +0 -0
  130. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/PoweredBy.imageset/Contents.json +0 -21
  131. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/Assets.xcassets/PoweredBy.imageset/powered-by.png +0 -0
  132. package/ios-runner/AgentDeviceRunner/AgentDeviceRunner/ContentView.swift +0 -34
  133. package/ios-runner/README.md +0 -53
  134. package/ios-runner/RUNNER_PROTOCOL.md +0 -76
  135. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -0
  136. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunner.xcodeproj/xcshareddata/xcschemes/AgentDeviceRunner.xcscheme +0 -0
  137. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests-Bridging-Header.h +0 -0
  138. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/AgentDeviceRunnerUITests.entitlements +0 -0
  139. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.h +0 -0
  140. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerAXSnapshotBridge.m +0 -0
  141. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.h +0 -0
  142. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerObjCExceptionCatcher.m +0 -0
  143. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +0 -0
  144. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +0 -0
  145. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Alert.swift +0 -0
  146. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Environment.swift +0 -0
  147. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Exceptions.swift +0 -0
  148. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Lifecycle.swift +0 -0
  149. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +0 -0
  150. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+ScreenRecorder.swift +0 -0
  151. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+SystemModal.swift +0 -0
  152. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Transport.swift +0 -0
  153. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+TvRemote.swift +0 -0
  154. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  155. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  156. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  157. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
  158. /package/dist/src/{4069.js → 4917.js} +0 -0
  159. /package/dist/src/{9836.js → 893.js} +0 -0
@@ -1,14 +1,8 @@
1
- export declare type AppErrorCode = KnownAppErrorCode | (string & {});
2
-
3
1
  export declare function centerOfRect(rect: Rect): Point;
4
2
 
5
- export declare const DAEMON_LOCK_POLICIES: readonly ['reject', 'strip'];
6
-
7
- export declare const DAEMON_SERVER_MODES: readonly ['socket', 'http', 'dual'];
3
+ declare const DAEMON_LOCK_POLICIES: readonly ['reject', 'strip'];
8
4
 
9
- export declare const DAEMON_TRANSPORT_PREFERENCES: readonly ['auto', 'socket', 'http'];
10
-
11
- export declare type DaemonArtifact = {
5
+ declare type DaemonArtifact = {
12
6
  field: string;
13
7
  artifactId?: string;
14
8
  fileName?: string;
@@ -16,8 +10,6 @@ export declare type DaemonArtifact = {
16
10
  path?: string;
17
11
  };
18
12
 
19
- export declare const daemonCommandRequestSchema: RuntimeSchema<DaemonRequest>;
20
-
21
13
  export declare type DaemonError = {
22
14
  code: string;
23
15
  message: string;
@@ -25,6 +17,18 @@ export declare type DaemonError = {
25
17
  diagnosticId?: string;
26
18
  logPath?: string;
27
19
  details?: Record<string, unknown>;
20
+ /**
21
+ * Machine-readable typed-error signals (Phase 2). Additive: present only when
22
+ * derivable, so the default error wire shape is unchanged.
23
+ *
24
+ * `retriable` flags a transient failure an agent should retry (vs. a
25
+ * deterministic one where a retry is wasted). `supportedOn` lists the platform
26
+ * families that DO support the command (derived from the capability matrix),
27
+ * surfaced on platform-mismatch errors so an agent self-corrects without a
28
+ * wasted round-trip.
29
+ */
30
+ retriable?: boolean;
31
+ supportedOn?: string;
28
32
  };
29
33
 
30
34
  export declare type DaemonInstallSource = {
@@ -47,7 +51,7 @@ export declare type DaemonInstallSource = {
47
51
  artifactName: string;
48
52
  }));
49
53
 
50
- export declare type DaemonLockPolicy = (typeof DAEMON_LOCK_POLICIES)[number];
54
+ declare type DaemonLockPolicy = (typeof DAEMON_LOCK_POLICIES)[number];
51
55
 
52
56
  export declare type DaemonRequest = {
53
57
  token?: string;
@@ -59,9 +63,11 @@ export declare type DaemonRequest = {
59
63
  meta?: DaemonRequestMeta;
60
64
  };
61
65
 
62
- export declare type DaemonRequestMeta = {
66
+ declare type DaemonRequestMeta = {
63
67
  requestId?: string;
64
68
  debug?: boolean;
69
+ includeCost?: boolean;
70
+ responseLevel?: ResponseLevel;
65
71
  cwd?: string;
66
72
  sessionExplicit?: boolean;
67
73
  tenantId?: string;
@@ -81,7 +87,7 @@ export declare type DaemonRequestMeta = {
81
87
  materializationId?: string;
82
88
  lockPolicy?: DaemonLockPolicy;
83
89
  lockPlatform?: PlatformSelector;
84
- requestProgress?: 'replay-test';
90
+ requestProgress?: 'replay-test' | 'command';
85
91
  };
86
92
 
87
93
  export declare type DaemonResponse = {
@@ -94,64 +100,7 @@ export declare type DaemonResponse = {
94
100
 
95
101
  export declare type DaemonResponseData = Record<string, unknown> & {
96
102
  artifacts?: DaemonArtifact[];
97
- };
98
-
99
- export declare const daemonRuntimeSchema: RuntimeSchema<SessionRuntimeHints>;
100
-
101
- export declare type DaemonServerMode = (typeof DAEMON_SERVER_MODES)[number];
102
-
103
- export declare type DaemonTransportPreference = (typeof DAEMON_TRANSPORT_PREFERENCES)[number];
104
-
105
- export declare type DebugSymbolsCrashFrame = {
106
- index: number;
107
- image: string;
108
- address: string;
109
- symbol?: string;
110
- };
111
-
112
- export declare type DebugSymbolsCrashSummary = {
113
- format: 'ips' | 'text';
114
- appName?: string;
115
- bundleId?: string;
116
- version?: string;
117
- incident?: string;
118
- timestamp?: string;
119
- exceptionType?: string;
120
- exceptionCodes?: string;
121
- terminationReason?: string;
122
- crashedThread?: number;
123
- topFrames: DebugSymbolsCrashFrame[];
124
- findings: string[];
125
- };
126
-
127
- export declare type DebugSymbolsImage = {
128
- name: string;
129
- uuid: string;
130
- arch?: string;
131
- dsymPath: string;
132
- binaryPath: string;
133
- };
134
-
135
- export declare type DebugSymbolsOptions = {
136
- action?: 'symbols';
137
- artifact: string;
138
- dsym?: string;
139
- searchPath?: string;
140
- out?: string;
141
- cwd?: string;
142
- };
143
-
144
- export declare type DebugSymbolsResult = {
145
- kind: 'debugSymbols';
146
- platform: 'apple';
147
- artifactPath: string;
148
- outPath: string;
149
- crash: DebugSymbolsCrashSummary;
150
- matchedImages: DebugSymbolsImage[];
151
- symbolicatedFrames: number;
152
- skippedImages: number;
153
- warnings?: string[];
154
- message: string;
103
+ cost?: ResponseCost;
155
104
  };
156
105
 
157
106
  export declare function defaultHintForCode(code: string): string | undefined;
@@ -165,11 +114,7 @@ export declare type JsonRpcRequestEnvelope<TParams = unknown> = {
165
114
  params?: TParams;
166
115
  };
167
116
 
168
- export declare const jsonRpcRequestSchema: RuntimeSchema<JsonRpcRequestEnvelope<unknown>>;
169
-
170
- declare type KnownAppErrorCode = 'INVALID_ARGS' | 'DEVICE_NOT_FOUND' | 'DEVICE_IN_USE' | 'TOOL_MISSING' | 'APP_NOT_INSTALLED' | 'UNSUPPORTED_PLATFORM' | 'UNSUPPORTED_OPERATION' | 'NOT_IMPLEMENTED' | 'COMMAND_FAILED' | 'SESSION_NOT_FOUND' | 'UNAUTHORIZED' | 'AMBIGUOUS_MATCH' | 'UNKNOWN';
171
-
172
- export declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
117
+ declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
173
118
 
174
119
  export declare type LeaseAllocatePayload = {
175
120
  token?: string;
@@ -184,8 +129,6 @@ export declare type LeaseAllocatePayload = {
184
129
  clientId?: string;
185
130
  };
186
131
 
187
- export declare const leaseAllocateSchema: RuntimeSchema<LeaseAllocatePayload>;
188
-
189
132
  export declare type LeaseBackend = (typeof LEASE_BACKENDS)[number];
190
133
 
191
134
  export declare type LeaseHeartbeatPayload = {
@@ -202,8 +145,6 @@ export declare type LeaseHeartbeatPayload = {
202
145
  clientId?: string;
203
146
  };
204
147
 
205
- export declare const leaseHeartbeatSchema: RuntimeSchema<LeaseHeartbeatPayload>;
206
-
207
148
  export declare type LeaseReleasePayload = {
208
149
  token?: string;
209
150
  session?: string;
@@ -217,12 +158,6 @@ export declare type LeaseReleasePayload = {
217
158
  clientId?: string;
218
159
  };
219
160
 
220
- export declare const leaseReleaseSchema: RuntimeSchema<LeaseReleasePayload>;
221
-
222
- export declare const NETWORK_INCLUDE_MODES: readonly ['summary', 'headers', 'body', 'all'];
223
-
224
- export declare type NetworkIncludeMode = (typeof NETWORK_INCLUDE_MODES)[number];
225
-
226
161
  declare type NormalizedError = {
227
162
  code: string;
228
163
  message: string;
@@ -237,7 +172,7 @@ export declare function normalizeError(err: unknown, context?: {
237
172
  logPath?: string;
238
173
  }): NormalizedError;
239
174
 
240
- declare const PLATFORM_SELECTORS: readonly ["ios", "macos", "android", "linux", "web", "apple"];
175
+ declare const PLATFORM_SELECTORS: readonly ["apple", "android", "linux", "web", "ios", "macos"];
241
176
 
242
177
  declare type PlatformSelector = (typeof PLATFORM_SELECTORS)[number];
243
178
 
@@ -246,47 +181,26 @@ declare type Point = {
246
181
  y: number;
247
182
  };
248
183
 
249
- declare type RawSnapshotNode = {
250
- index: number;
251
- type?: string;
252
- role?: string;
253
- subrole?: string;
254
- label?: string;
255
- value?: string;
256
- identifier?: string;
257
- rect?: Rect;
258
- enabled?: boolean;
259
- selected?: boolean;
260
- focused?: boolean;
261
- visibleToUser?: boolean;
262
- hittable?: boolean;
263
- depth?: number;
264
- parentIndex?: number;
265
- pid?: number;
266
- bundleId?: string;
267
- appName?: string;
268
- windowTitle?: string;
269
- surface?: string;
270
- hiddenContentAbove?: boolean;
271
- hiddenContentBelow?: boolean;
272
- interactionBlocked?: 'covered';
273
- presentationHints?: string[];
274
- };
275
-
276
- export declare type Rect = {
184
+ declare type Rect = {
277
185
  x: number;
278
186
  y: number;
279
187
  width: number;
280
188
  height: number;
281
189
  };
282
190
 
283
- declare type RuntimeSchema<T> = {
284
- parse(input: unknown): T;
191
+ declare const RESPONSE_LEVELS: readonly ['digest', 'default', 'full'];
192
+
193
+ declare type ResponseCost = {
194
+ wallClockMs: number;
195
+ runnerRoundTrips: number;
196
+ nodeCount?: number;
285
197
  };
286
198
 
287
- export declare const SESSION_ISOLATION_MODES: readonly ['none', 'tenant'];
199
+ declare type ResponseLevel = (typeof RESPONSE_LEVELS)[number];
200
+
201
+ declare const SESSION_ISOLATION_MODES: readonly ['none', 'tenant'];
288
202
 
289
- export declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
203
+ declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
290
204
 
291
205
  export declare type SessionRuntimeHints = {
292
206
  platform?: 'ios' | 'android';
@@ -296,8 +210,4 @@ export declare type SessionRuntimeHints = {
296
210
  launchUrl?: string;
297
211
  };
298
212
 
299
- export declare type SnapshotNode = RawSnapshotNode & {
300
- ref: string;
301
- };
302
-
303
213
  export { }
@@ -1 +1 @@
1
- export{DAEMON_LOCK_POLICIES,DAEMON_SERVER_MODES,DAEMON_TRANSPORT_PREFERENCES,LEASE_BACKENDS,NETWORK_INCLUDE_MODES,SESSION_ISOLATION_MODES,centerOfRect,daemonCommandRequestSchema,daemonRuntimeSchema,jsonRpcRequestSchema,leaseAllocateSchema,leaseHeartbeatSchema,leaseReleaseSchema}from"./4291.js";export{defaultHintForCode,normalizeError}from"./733.js";
1
+ export{centerOfRect}from"./6849.js";export{defaultHintForCode,normalizeError}from"./485.js";
@@ -0,0 +1,3 @@
1
+ import e from"node:fs/promises";import t from"node:path";import{AppError as r}from"./485.js";import{isRecord as a}from"./1986.js";import{runCmd as n}from"./8875.js";let i=/^[0-9a-fA-F-]{32,36}$/;function s(e){if(e&&i.test(e))return e.replaceAll("-","").toUpperCase()}function o(e,t){return`${e.uuid}:${d(t)}`}function d(e){return`0x${e.toString(16)}`}function l(e){return"string"==typeof e&&e.length>0?e:void 0}function u(...e){for(let t of e){let e=l(t);if(e)return e}}function c(e){try{let t=JSON.parse(e);return a(t)?t:null}catch{return null}}function m(e){if("number"==typeof e&&Number.isSafeInteger(e))return e;if("string"==typeof e){let t=e.startsWith("0x")?Number.parseInt(e,16):Number(e);return Number.isSafeInteger(t)?t:void 0}}function f(e,t,r){var a;if(!Object.hasOwn(e,t))return;let n="bigint"==typeof(a=e[t])?a:"number"==typeof a&&Number.isSafeInteger(a)?BigInt(a):"string"!=typeof a?void 0:/^(?:0x[0-9a-fA-F]+|\d+)$/.test(a)?BigInt(a):void 0;if(void 0!==n)return n;h(r,t)}function h(e,t){throw new r("INVALID_ARGS",`Invalid ${e} numeric field: ${t}`,{hint:"Crash artifact numeric fields must be integer numbers or integer numeric strings."})}function p(e){return[...new Set(e)]}let y=/^(?:arm64e?|arm64_32|x86_64|armv7[sk]?|i386)$/;async function g(e){return e.dsym&&e.searchPath?[v(e.cwd,e.dsym),...await w(v(e.cwd,e.searchPath))]:e.dsym?[v(e.cwd,e.dsym)]:e.searchPath?await w(v(e.cwd,e.searchPath)):[]}async function w(a){let n=[],i=0;async function s(o){if(!(n.length>=200)){if((i+=1)>1e4)throw new r("COMMAND_FAILED","debug symbols search-path scan exceeded bounds.",{searchPath:a,maxEntries:1e4,hint:"Pass --dsym <App.dSYM> directly or narrow --search-path to the build products directory."});if(!(await b(o,a)).isDirectory()){o===a&&function(e){throw new r("INVALID_ARGS",`debug symbols search path is not a directory: ${e}`,{hint:"Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly."})}(a);return}if(o.endsWith(".dSYM"))return void n.push(o);for(let r of(await e.readdir(o,{withFileTypes:!0})))r.isDirectory()&&await s(t.join(o,r.name))}}return await s(a),n}async function b(t,a){try{return await e.stat(t)}catch{throw new r("INVALID_ARGS",`debug symbols search path does not exist: ${a}`,{hint:"Pass an existing build products directory to --search-path, or pass --dsym <App.dSYM> directly."})}}async function I(e,t){let a=(await Promise.all(p(e).map(e=>A(e,t)))).flat();if(0===a.length)throw new r("COMMAND_FAILED","No UUIDs found in dSYM bundle.",{hint:"Verify the path points to a built .dSYM bundle with DWARF contents."});return a}async function A(e,t){var a;await S(e);let i=await n(t,["--uuid",e],{timeoutMs:15e3,allowFailure:!0});if(0!==i.exitCode)throw new r("COMMAND_FAILED",`Failed to inspect dSYM UUIDs: ${e}`,{stderr:i.stderr,hint:"Verify the dSYM bundle is valid and readable."});return a=e,i.stdout.split("\n").flatMap(e=>{let t=e.match(/^UUID:\s+([0-9a-fA-F-]{32,36})\s+\(([^)]+)\)\s+(.+)$/),r=s(t?.[1]);return t&&r?[{dsymPath:a,uuid:r,arch:t[2],binaryPath:t[3].trim()}]:[]})}async function S(t){let a=await e.stat(t).catch(()=>null);if(!(a?.isDirectory()&&t.endsWith(".dSYM")))throw new r("INVALID_ARGS",`Not a .dSYM bundle: ${t}`,{hint:"Pass the .dSYM bundle path, not the DWARF executable inside it."})}function v(e,r){return t.resolve(e,r)}function x(e,t){let r=`${t}:`,a=e.find(e=>e.trimStart().startsWith(r));return a&&a.slice(a.indexOf(":")+1).trim()||void 0}function M(e,t,r,a){return{index:e,image:t.name,address:d(r),symbol:a.get(o(t,r))?.text}}function $(e){var t;let r;return[(r=(t=e).topFrames.find(e=>e.symbol))?`Start with ${r.symbol} in ${r.image}; it is the first symbolicated frame captured on the crashed thread.`:t.topFrames.length>0?"No symbolicated frame was found on the crashed thread; verify matching dSYMs for the top images.":void 0,e.exceptionType?`Exception: ${e.exceptionType}`:void 0,e.terminationReason?`Termination: ${e.terminationReason}`:void 0].filter(e=>!!e).slice(0,3)}async function N(e,t,r){let a=new Map;for(let n of(function(e,t){let r=new Map;for(let a of e){let e=t.get(a.image.uuid);if(!e)continue;let n=`${a.image.uuid}:${e.dsym.binaryPath}`,i=r.get(n)??{...e,addresses:[]};i.addresses.push(a.address),r.set(n,i)}return r})(e,t).values())for(let e of(await _(r,n)))a.set(o(e.image,e.address),e);return a}async function _(e,t){var a,i,s,o;let l,u,c=p(t.addresses.map(d)),m=await n(e,(a=t,i=c,["-arch",a.image.arch??a.dsym.arch??"arm64","-o",a.dsym.binaryPath,"-l",d(a.image.base),...i]),{timeoutMs:3e4,allowFailure:!0});return 0!==m.exitCode&&function(e){throw new r("COMMAND_FAILED","atos failed while symbolicating crash frames.",{stderr:e,hint:"Verify the crash artifact and dSYM were produced from the same build and architecture."})}(m.stderr),s=t.image,o=c,u=(""===(l=m.stdout.split(/\r?\n/)).at(-1)&&l.pop(),l),o.map((e,t)=>{let r=u[t]?.trim();return{image:s,address:BigInt(e),text:!function(e,t){if(!e)return!1;let r=e.trim().toLowerCase();return!!r&&"??"!==r&&r!==t.toLowerCase()&&!r.startsWith("0x")}(r,e)?void 0:r}})}async function D(){return{dwarfdump:await F("dwarfdump"),atos:await F("atos")}}async function F(e){try{let t=await n("xcrun",["--find",e],{timeoutMs:5e3,allowFailure:!0}),r=t.stdout.trim();if(0===t.exitCode&&r.length>0)return r}catch{}throw new r("TOOL_MISSING",`Apple symbolication tool not found: ${e}`,{hint:"Install Xcode Command Line Tools and verify xcrun --find dwarfdump and xcrun --find atos succeed."})}async function P(n){var i,d,w,b,A,S,v,_,F,P,U,Y,T,L,O,E,V,B,G,W,j,k,K,z,H,J,q,X;let Q,Z,ee,et,er,ea,en,ei,es,eo,ed;if(void 0!==n.action&&"symbols"!==n.action)throw new r("INVALID_ARGS","debug supports only the symbols workflow.",{hint:"Use debug symbols --artifact <crash.ips|crash.log> --dsym <App.dSYM> or --search-path <dir> --out <path>."});let el=n.cwd??process.cwd(),eu=R(el,n.artifact),ec=R(el,n.out??(d=eu,Z=(Q=t.extname(d))?d.slice(0,-Q.length):d,`${Z}-symbolicated${Q||".log"}`)),em=function(e){var r;let n,i=function(e){let t=c(e);if(t)return{payload:t};let r=e.indexOf("\n");if(-1===r)return null;let a=e.slice(0,r),n=c(e.slice(r+1));return n?{header:a,payload:n}:null}(e);if(!i)return null;let d=(Array.isArray(i.payload.usedImages)?i.payload.usedImages:[]).flatMap((e,r)=>(function(e,r){if(!a(e))return[];let n=s(l(e.uuid)),i=f(e,"base","IPS usedImages");if(!n||void 0===i)return[];let o=l(e.path);return[{index:r,name:l(e.name)??(o?t.basename(o):`image-${r}`),uuid:n,arch:l(e.arch),base:i,path:o}]})(e,r));if(0===d.length)return null;let u=(r=Array.isArray(i.payload.threads)?i.payload.threads:[],n=new Map(d.map(e=>[e.index,e])),r.flatMap((e,t)=>{var r;return(a(r=e)&&Array.isArray(r.frames)?r.frames.filter(a):[]).flatMap((e,r)=>(function(e,t,r,a){let n=function(e,t,r){if(!Object.hasOwn(e,t))return;let a=m(e[t]);if(void 0!==a)return a;h(r,t)}(e,"imageIndex","IPS frame"),i=f(e,"imageOffset","IPS frame");if(void 0===n||void 0===i)return[];let s=t.get(n);return s?[{frame:e,frameIndex:a,threadIndex:r,image:s,address:s.base+i}]:[]})(e,n,t,r))}));return{format:"ips",images:d,addresses:u.map(({frame:e,...t})=>t),document:i,frameMatches:u,write:e=>(function(e,t,r){for(let e of t){let t=r.get(o(e.image,e.address))?.text;t&&function(e,t){let r,a=(r=t.match(/^(.*) \+ (\d+)$/))?{symbol:r[1],location:Number(r[2])}:{symbol:t};e.symbol=a.symbol,void 0!==a.location&&(e.symbolLocation=a.location)}(e.frame,t)}e.payload.agentDeviceSymbolication={tool:"agent-device debug symbols",symbolicatedFrames:[...r.values()].filter(e=>e.text).length};let a=`${JSON.stringify(e.payload,null,2)}
2
+ `;return e.header?`${e.header}
3
+ ${a}`:a})(i,u,e)}}(i=await C(eu,"crash artifact"))??function(e){let r=e.split("\n"),a=function(e){let r=[],a=e.findIndex(e=>/^Binary Images:/i.test(e.trim()));if(-1===a)return r;for(let n of e.slice(a+1)){let e=function(e){let r=e.match(/^\s*(0x[0-9a-fA-F]+)\s*-\s*(0x[0-9a-fA-F]+)\s+\+?(.+?)\s+<([0-9a-fA-F-]{32,36})>\s+(.+)$/);if(!r)return null;let a=s(r[4]);if(!a)return null;let n=function(e,r){let a=e.split(/\s+/),n=a.at(-1);if(n&&y.test(n))return{name:a.slice(0,-1).join(" ").trim(),arch:n};let i=t.basename(r);return{name:e.startsWith(i)?i:e}}(r[3].trim(),r[5].trim());return{name:n.name,arch:n.arch,uuid:a,base:BigInt(r[1]),end:BigInt(r[2]),path:r[5].trim()}}(n);e&&r.push(e)}return r}(r);if(0===a.length)return null;let n=function(e,t){let r,a=[];for(let[n,i]of e.entries()){let e=i.match(/^Thread\s+(\d+)\s+Crashed:/);e?r=Number(e[1]):(0===i.trim().length||/^Thread\s+\d+/.test(i))&&(r=void 0);let s=function(e,t){let r=e.match(/^\s*\d+\s+(.+?)\s+(0x[0-9a-fA-F]+)\b/);if(!r)return null;let a=r[1].trim(),n=BigInt(r[2]),i=function(e,t,r){let a=e.filter(e=>e.name===t);return a.find(e=>{var t,a;return t=e,a=r,void 0!==t.end&&t.base<=a&&a<=t.end})??(1===a.length?a[0]:void 0)}(t,a,n);return i?{image:i,address:n}:null}(i,t),o=i.match(/^\s*(\d+)/);s&&o&&a.push({...s,frameIndex:Number(o[1]),lineIndex:n,threadIndex:r})}return a}(r,a);return{format:"text",images:a,addresses:n,lines:r,frameMatches:n,write(e){let t=new Map(n.map(e=>[e.lineIndex,e]));return r.map((r,a)=>{let n=t.get(a);if(!n)return r;let i=e.get(o(n.image,n.address))?.text;return!i||r.includes(i)?r:`${r} // ${i}`}).join("\n")}}}(i);em||function(){throw new r("UNSUPPORTED_OPERATION","debug symbols currently supports Apple crash artifacts with Binary Images or IPS usedImages.",{hint:"For Android Java/R8 crashes, use retrace with mapping.txt. For Android native crashes, use ndk-stack or addr2line with unstripped .so symbols. Capture the crash with logs, then symbolicate externally until Android support is added."})}();let ef=await g({cwd:el,dsym:n.dsym,searchPath:n.searchPath});if(0===ef.length)throw new r("INVALID_ARGS","debug symbols requires --dsym or --search-path.",{hint:"Pass a matching .dSYM bundle directly, or pass --search-path <dir> so agent-device can match crash image UUIDs to local dSYMs."});let eh=await D(),ep=await I(ef,eh.dwarfdump),ey=function(e,t,a){let n=new Map;for(let r of e){let e=t.find(e=>e.uuid===r.uuid&&(void 0===r.arch||void 0===e.arch||e.arch===r.arch));e&&n.set(r.uuid,{image:r,dsym:e})}if(n.size>0)return n;let i=p(e.map(e=>e.uuid)),s=p(t.map(e=>e.uuid));throw new r("COMMAND_FAILED",a?"dSYM UUID does not match any Apple image in the crash artifact.":"No matching dSYM UUID found under search path.",{artifactUuidCount:i.length,artifactUuidSample:i.slice(0,5),dsymUuidCount:s.length,dsymUuidSample:s.slice(0,5),hint:"Use dwarfdump --uuid <App.dSYM> and compare it with the crash Binary Images or usedImages UUID, then pass the matching dSYM/search path."})}(em.images,ep,!!n.dsym),eg=await N(em.addresses,ey,eh.atos),ew=em.write(eg);await e.mkdir(t.dirname(ec),{recursive:!0}),await e.writeFile(ec,ew,"utf8");let eb=[...ey.values()].map(({image:e,dsym:t})=>({name:e.name,uuid:e.uuid,arch:e.arch??t.arch,dsymPath:t.dsymPath,binaryPath:t.binaryPath})),eI=[...eg.values()].filter(e=>e.text).length,eA=em.images.length-eb.length,eS=eA>0?[`${eA} Apple image${1===eA?"":"s"} had no matching dSYM and were left unchanged.`]:void 0;return{kind:"debugSymbols",platform:"apple",artifactPath:eu,outPath:ec,crash:"ips"===em.format?(w=em.document,b=em.frameMatches,A=eg,en=function(e){let t=m(e.faultingThread);if(void 0!==t)return t;let r=(Array.isArray(e.threads)?e.threads:[]).findIndex(e=>a(e)&&!0===e.triggered);return -1===r?void 0:r}(w.payload),{...ei={format:"ips",...(ee=(S=w).payload,et=(v=S.header)?c(v):null,{appName:(_=ee,F=et,u(_.procName,F?.app_name,F?.name)),bundleId:(P=ee,U=et,er=a(P.bundleInfo)?P.bundleInfo:void 0,u(er?.CFBundleIdentifier,U?.bundleID)),version:(Y=ee,T=et,ea=a(Y.bundleInfo)?Y.bundleInfo:void 0,u(ea?.CFBundleShortVersionString,T?.app_version)),incident:(L=ee,O=et,u(L.incident,O?.incident_id)),timestamp:(E=ee,V=et,u(E.captureTime,V?.timestamp)),exceptionType:a(B=ee.exception)?l(B.type):void 0,exceptionCodes:a(G=ee.exception)?u(G.codes,G.rawCodes):void 0,terminationReason:function(e){if(a(e)){let t;return(t=[l(e.namespace),l(e.code),l(e.reason)].filter(e=>!!e)).length>0?t.join(" "):void 0}}(ee.termination)}),crashedThread:en,topFrames:(W=b,j=en,k=A,W.filter(e=>void 0===j||e.threadIndex===j).slice(0,5).map(e=>M(e.frameIndex,e.image,e.address,k))),findings:[]},findings:$(ei)}):(K=em.lines,z=em.frameMatches,H=eg,eo=function(e){let t=x(e,"Triggered by Thread"),r=t?Number.parseInt(t,10):NaN;if(Number.isSafeInteger(r))return r;for(let t of e){let e=t.match(/^Thread\s+(\d+)\s+Crashed:/);if(e)return Number(e[1])}}(K),{...ed={format:"text",appName:(es=x(K,"Process"),es?.replace(/\s+\[\d+\]$/,"")),bundleId:x(K,"Identifier"),version:x(K,"Version"),incident:x(K,"Incident Identifier"),timestamp:x(K,"Date/Time"),exceptionType:x(K,"Exception Type"),exceptionCodes:x(K,"Exception Codes"),terminationReason:x(K,"Termination Reason"),crashedThread:eo,topFrames:(J=z,q=eo,X=H,void 0===q?[]:J.filter(e=>e.threadIndex===q).slice(0,5).map(e=>M(e.frameIndex,e.image,e.address,X))),findings:[]},findings:$(ed)}),matchedImages:eb,symbolicatedFrames:eI,skippedImages:eA,warnings:eS,message:`Symbolicated ${eI} frame${1===eI?"":"s"} -> ${ec}`}}async function C(t,a){await U(t,a);try{return await e.readFile(t,"utf8")}catch(e){throw new r("INVALID_ARGS",`Failed to read ${a}: ${t}`,{message:e instanceof Error?e.message:String(e)})}}async function U(t,a){try{let n=await e.stat(t);if(n.size<=0x4000000)return;throw new r("INVALID_ARGS",`${a} is too large: ${t}`,{actualBytes:n.size,maxBytes:0x4000000,hint:"Pass a bounded Apple .ips/.crash artifact. For very large logs, first narrow the log to the crash report, or use logs grep/tail for lead-up context."})}catch(e){if(e instanceof r)throw e;throw new r("INVALID_ARGS",`Failed to read ${a}: ${t}`,{message:e instanceof Error?e.message:String(e)})}}function R(e,r){return t.resolve(e,r)}export{P as symbolicateCrashArtifact};
@@ -1 +1 @@
1
- import{promises as t}from"node:fs";import e from"node:os";import i from"node:path";import{AppError as r}from"./733.js";import{buildHostMacDevice as o}from"./devices~2.js";import{runXcrun as n,resolveAppleToolProvider as l,buildSimctlArgs as a}from"./9722.js";import{resolveIosSimulatorDeviceSetPath as u}from"./3340.js";let s=/^(iphone|ipad|ipod|appletv)/i,c=/\b(iphone|ipad|ipod)\b/i,d=/^appletv/i,p=["apple tv","appletv","tvos"],f=/^==\s*(.+?)\s*==$/,m=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function v(t){return(t??"").trim().toLowerCase()}function h(t){return v(t.hardwareProperties?.platform)}function w(t){return t.includes("tvos")}function _(t){let e=v(t);return p.some(t=>e.includes(t))}function S(t){return[t.name??"",t.deviceProperties?.name??"",t.deviceProperties?.deviceType??""]}function P(t){return t.hardwareProperties?.productType??t.deviceProperties?.productType??""}async function b(t={}){let e,i,r=u(t.simulatorSetPath),o=t.target;try{e=await n(a(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{i=JSON.parse(e.stdout)}catch{return null}let l=y(i,r),s=null,c=null,d=null;for(let t of l)o&&t.target!==o||(t.booted&&(s=s??t),"mobile"===t.target&&(c=c??t),d=d??t);return s??c??d}function y(t,e){let i=[];for(let[r,o]of Object.entries(t.devices))if(function(t){let e=v(t);return e.includes("ios")||e.includes("tvos")}(r))for(let t of o)t.isAvailable&&i.push({platform:"ios",id:t.udid,name:t.name,kind:"simulator",target:w(v(r))?"tv":"mobile",booted:"Booted"===t.state,...e?{simulatorSetPath:e}:{}});return i}function C(t,e){let i=new Set(t.map(t=>t.id)),r=[...t];for(let t of e)i.has(t.id)||(i.add(t.id),r.push(t));return r}async function A(){let r=null;try{r=i.join(e.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let o=await n(["devicectl","list","devices","--json-output",r],{allowFailure:!0,timeoutMs:8e3});if(0!==o.exitCode)return[];let l=await t.readFile(r,"utf8");return function(t){let e=[];for(let i of t.result?.devices??[]){if(!function(t){var e;let i=h(t);return!!(i.includes("ios")||i.includes("tvos"))||(e=P(t),!!s.test(e.trim())||S(t).some(_))}(i))continue;let t=i.hardwareProperties?.udid??i.identifier??"",r=i.name??i.deviceProperties?.name??t;t&&e.push({platform:"ios",id:t,name:r,kind:"device",target:function(t){var e;return w(h(t))?"tv":(e=P(t),d.test(e.trim())||S(t).some(_))?"tv":"mobile"}(i),booted:!0})}return e}(JSON.parse(l))}catch{return[]}finally{r&&await t.rm(r,{force:!0}).catch(()=>{})}}async function N(){try{let t=await n(["xctrace","list","devices"],{allowFailure:!0});if(0!==t.exitCode)return[];return function(t){let e=[],i=null;for(let r of t.split(/\r?\n/)){let t=r.trim();if(!t)continue;let o=f.exec(t);if(o){i=o[1]?.trim()??null;continue}if("Devices"!==i)continue;let n=m.exec(t),l=n?.groups?.id?.trim()??"",a=n?.groups?.name?.trim()??"";if(!l||!a)continue;let u=function(t){return _(t)?"tv":c.test(t.trim())?"mobile":null}(a);u&&e.push({platform:"ios",id:l,name:a,kind:"device",target:u,booted:!0})}return e}(t.stdout)}catch{return[]}}async function O(t={}){if("darwin"!==process.platform)throw new r("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await l().whichCommand("xcrun"))throw new r("TOOL_MISSING","xcrun not found in PATH");let e=u(t.simulatorSetPath),i=await n(a(["list","devices","-j"],{simulatorSetPath:e})),s=[];try{let t=JSON.parse(i.stdout);s=y(t,e)}catch(t){throw new r("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,t)}if(s.push(o()),t.udid&&s.some(e=>"ios"===e.platform&&e.id===t.udid)||e)return s;let[c,d]=await Promise.all([A(),N()]);return s=C(s,c),C(s,d)}export{b as findBootableIosSimulator,O as listAppleDevices};
1
+ import{promises as e}from"node:fs";import t from"node:os";import i from"node:path";import{AppError as r}from"./485.js";import{isIosFamily as o,sortAppleDevicesForSelection as n}from"./6849.js";import{buildHostMacDevice as s}from"./devices~1.js";import{runXcrun as l,resolveAppleToolProvider as a,buildSimctlArgs as u}from"./9722.js";import{markSimulatorBooted as c}from"./simulator.js";import{resolveIosSimulatorDeviceSetPath as d}from"./3340.js";let p=/^(iphone|ipad|ipod|appletv|realitydevice)/i,f=/ipad/i,m=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,v=/\b(iphone|ipad|ipod)\b/i,_=/^appletv/i,h=["apple tv","appletv","tvos"],S=/^==\s*(.+?)\s*==$/,w=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function P(e){return(e??"").trim().toLowerCase()}function y(e){return P(e.hardwareProperties?.platform)}function C(e){return e.includes("tvos")}function b(e){let t=P(e);return h.some(e=>t.includes(e))}function O(e,t){return"tv"===e?"tvos":t.some(e=>m.test(e))?"visionos":t.some(e=>f.test(e))?"ipados":"ios"}function A(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function N(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function K(e={}){let t,i,r=d(e.simulatorSetPath),o=e.target;try{t=await l(u(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{i=JSON.parse(t.stdout)}catch{return null}return n(M(i,r)).find(e=>!o||e.target===o)??null}function M(e,t){let i=[];for(let[r,o]of Object.entries(e.devices))if(function(e){let t=P(e);return t.includes("ios")||t.includes("tvos")||t.includes("xros")||t.includes("visionos")}(r))for(let e of o){if(!e.isAvailable)continue;let o=C(P(r))?"tv":"mobile",n={platform:"apple",id:e.udid,name:e.name,kind:"simulator",target:o,appleOs:O(o,[e.deviceTypeIdentifier??"",e.name]),booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}};n.booted&&c(n),i.push(n)}return i}function x(e,t){let i=new Set(e.map(e=>e.id)),r=[...e];for(let e of t)i.has(e.id)||(i.add(e.id),r.push(e));return r}async function E(){let r=null;try{r=i.join(t.tmpdir(),`agent-device-devicectl-${process.pid}-${Date.now()}-${Math.random().toString(36).slice(2)}.json`);let o=await l(["devicectl","list","devices","--json-output",r],{allowFailure:!0,timeoutMs:8e3});if(0!==o.exitCode)return[];let n=await e.readFile(r,"utf8");return function(e){let t=[];for(let i of e.result?.devices??[]){if(!function(e){var t,i;let r=y(e);return!!(r.includes("ios")||r.includes("tvos")||(t=r).includes("xros")||t.includes("visionos"))||(i=N(e),!!p.test(i.trim())||A(e).some(b))}(i))continue;let e=i.hardwareProperties?.udid??i.identifier??"",r=i.name??i.deviceProperties?.name??e;if(!e)continue;let o=function(e){var t;return C(y(e))?"tv":(t=N(e),_.test(t.trim())||A(e).some(b))?"tv":"mobile"}(i);t.push({platform:"apple",id:e,name:r,kind:"device",target:o,appleOs:O(o,[N(i),...A(i)]),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{r&&await e.rm(r,{force:!0}).catch(()=>{})}}async function R(){try{let e=await l(["xctrace","list","devices"],{allowFailure:!0});if(0!==e.exitCode)return[];return function(e){let t=[],i=null;for(let r of e.split(/\r?\n/)){let e=r.trim();if(!e)continue;let o=S.exec(e);if(o){i=o[1]?.trim()??null;continue}if("Devices"!==i)continue;let n=w.exec(e),s=n?.groups?.id?.trim()??"",l=n?.groups?.name?.trim()??"";if(!s||!l)continue;let a=function(e){return b(e)?"tv":v.test(e.trim())||m.test(e)?"mobile":null}(l);a&&t.push({platform:"apple",id:s,name:l,kind:"device",target:a,appleOs:O(a,[l]),booted:!0})}return t}(e.stdout)}catch{return[]}}async function T(e={}){if("darwin"!==process.platform)throw new r("UNSUPPORTED_PLATFORM","Apple tools are only available on macOS");if(!await a().whichCommand("xcrun"))throw new r("TOOL_MISSING","xcrun not found in PATH");let t=d(e.simulatorSetPath),i=await l(u(["list","devices","-j"],{simulatorSetPath:t})),c=[];try{let e=JSON.parse(i.stdout);c=M(e,t)}catch(e){throw new r("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(c.push(s()),e.udid&&c.some(t=>o(t)&&t.id===e.udid))return c;if(t)return n(c);let[p,f]=await Promise.all([E(),R()]);return c=x(c,p),n(x(c,f))}export{K as findBootableIosSimulator,T as listAppleDevices};
@@ -1 +1 @@
1
- import{hostname as o}from"node:os";async function e(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:o(),kind:"device",target:"desktop",booted:!0}]}export{e as listLinuxDevices};
1
+ import o from"node:os";function e(){return{platform:"apple",id:"host-macos-local",name:o.hostname(),kind:"device",target:"desktop",appleOs:"macos",booted:!0}}async function t(){return[e()]}export{e as buildHostMacDevice,t as listMacosDevices};
@@ -1 +1 @@
1
- import o from"node:os";function e(){return{platform:"macos",id:"host-macos-local",name:o.hostname(),kind:"device",target:"desktop",booted:!0}}async function t(){return[e()]}export{e as buildHostMacDevice,t as listMacosDevices};
1
+ import{hostname as o}from"node:os";async function e(){return"linux"!==process.platform?[]:[{platform:"linux",id:"local",name:o(),kind:"device",target:"desktop",booted:!0}]}export{e as listLinuxDevices};
package/dist/src/find.js CHANGED
@@ -1 +1 @@
1
- import{context_contextFromFlags as e,errorResponse as t,dispatchCommand as r,resolveTargetDevice as n,stripInternalInteractionFlags as o}from"./9722.js";import{parseFindSelectorExpression as a,findBestMatchesByLocator as i,parseFindArgs as s}from"./587.js";import{ensureDeviceReady as l}from"./device-ready.js";import{dispatchFindReadOnlyViaRuntime as c,readTextForNode as f,createSelectorCaptureRuntime as u}from"./selector-runtime.js";import{resolveActionableTouchResolution as d,isSparseSnapshotQualityVerdict as p,isSnapshotNodeInteractionBlocked as h,resolveActionableTouchNode as _}from"./2948.js";import{resolveSelectorChain as g,extractNodeText as m}from"./9836.js";import{centerOfRect as y}from"./4291.js";import{sleep as A}from"./5560.js";async function w(e){var r,f,h,A;let w,{req:F,sessionName:E,logPath:b,sessionStore:L,invoke:O}=e,P=F.command;if("find"!==P)return null;let q=F.positionals??[];if(0===q.length)return t("INVALID_ARGS","find requires a locator or text");let{locator:H,query:$,action:B,value:G,timeoutMs:V}=s(q);if(!$)return t("INVALID_ARGS","find requires a value");if(F.flags?.findFirst&&F.flags?.findLast)return t("INVALID_ARGS","find accepts only one of --first or --last");let Q=await c({req:F,sessionName:E,logPath:b,sessionStore:L});if(Q)return Q;let T=L.get(E),j="exists"===(r=B)||"wait"===r||"get_text"===r||"get_attrs"===r;if(!T&&!j)return t("SESSION_NOT_FOUND","No active session. Run open first.");let z=T?.device??await n(F.flags??{});T||await l(z);let J="click"===(f=B)||"focus"===f||"fill"===f||"type"===f,W=a(H,$),X="web"!==z.platform&&!W&&U(H)&&!J?$:void 0,Y=function(e){let{device:t,session:r,req:n,logPath:o,locator:a,query:i,scope:s,interactiveOnly:l}=e,{sessionStore:c,sessionName:f}=e,d=u({device:t,session:r,sessionStore:c,sessionName:f,req:n,logPath:o});return async()=>{let{snapshot:e}=await d.capture({flags:{...n.flags,snapshotInteractiveOnly:l},snapshotScope:s,recovery:l?{legacyIosSparse:{query:i,scope:s,shouldScope:U(a)},sparseVerdictQueryScope:{query:i,shouldScope:U(a)}}:void 0});return{nodes:e.nodes,truncated:e.truncated,backend:e.backend,snapshotQuality:e.snapshotQuality}}}({device:z,session:T,req:F,logPath:b,locator:H,query:$,scope:X,interactiveOnly:J,sessionStore:L,sessionName:E}),Z={req:F,sessionName:E,logPath:b,sessionStore:L,invoke:O,session:T,device:z,command:P,locator:H,query:$,publicFlags:{...o(F.flags)??{}}};if("wait"===B)return v(Z,Y,H,$,V);let ee=await Y();if(p(ee.snapshotQuality))return S(ee.snapshotQuality);let{nodes:et}=ee,er=function(e){let{nodes:r,locator:n,query:o,selectorChain:a,requiresRect:s,flags:l,platform:c}=e,f=s?r.filter(e=>!N(e,r[0])):r;if(a){let e=g(f,a,{platform:c,requireRect:s,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:t("COMMAND_FAILED","find did not match any element")}}let u=i(f,n,o,{requireRect:s});if(s&&(u.matches=function(e,t){var r,n;let o=t[0]?.rect;if(!o)return e;let a=e.filter(e=>{if(!e.rect)return!1;let t=y(e.rect);return t.x>=o.x&&t.x<=o.x+o.width&&t.y>=o.y&&t.y<=o.y+o.height});return r=a.length>0?a:e,n=t,r.length<2?r:r.map((e,t)=>({node:e,index:t,score:function(e,t){var r,n;let o=d(t,e);if("covered"===o.reason)return 0;let a=(r=o,n=t[0],r.node.rect?"semantic-target"===r.reason||"same-rect-descendant"===r.reason?4:2*!("hittable-ancestor"!==r.reason||N(r.node,n)):0);return a>0?a:e.hittable&&e.rect&&!N(e,t[0])?3:+!!e.rect}(e,n)})).sort((e,t)=>t.score!==e.score?t.score-e.score:k(e.node)-k(t.node)||e.index-t.index).map(e=>e.node)}(u.matches,r)),s&&u.matches.length>1){var p,h,_,A,w;let e=(p=u.matches,h=l,h?.findFirst?[p[0]]:h?.findLast?[p[p.length-1]]:null);if(!e){let e;return{ok:!1,response:(_=u.matches,A=n,w=o,e=_.slice(0,8).map(e=>{let t=m(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),t("AMBIGUOUS_MATCH",`find matched ${_.length} elements for ${A} "${w}". Use a more specific locator or selector.`,{locator:A,query:w,matches:_.length,candidates:e}))}}u.matches=e}let S=u.matches[0]??null;return S?{ok:!0,node:S}:{ok:!1,response:t("COMMAND_FAILED","find did not match any element")}}({nodes:et,locator:H,query:$,selectorChain:W,requiresRect:J,flags:F.flags,platform:z.platform});if(!er.ok)return er.response;let en=er.node,eo=J?N(w=_(h=et,A=en),h[0])&&A.rect?A:w:en,ea=`@${eo.ref}`,ei={node:en,resolvedNode:eo,ref:ea,nodes:et,actionFlags:{...F.flags??{},noRecord:!0}},es={exists:()=>C(Z),get_text:()=>M(Z,ei),get_attrs:()=>I(Z,ei),click:()=>x(Z,ei),fill:()=>D(Z,ei,G),focus:()=>R(Z,ei),type:()=>K(Z,ei,G)}[B];return es?es():null}function S(e){return t("COMMAND_FAILED","find could not read the current accessibility tree",{reason:e.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen."})}function k(e){return e.rect?e.rect.width*e.rect.height:1/0}function N(e,t){var r,n;if(!t?.rect||!e.rect)return!1;let o=e.type?.toLowerCase()??"";return(!!o.includes("application")||!!o.includes("window"))&&(r=e.rect,n=t.rect,r.x===n.x&&r.y===n.y&&r.width===n.width&&r.height===n.height)}async function v(e,r,n,o,a){let s,{req:l,sessionStore:c,session:f,command:u,publicFlags:d}=e,h=a??1e4,_=Date.now();for(;Date.now()-_<h;){let{nodes:e,snapshotQuality:t}=await r();if(p(t)){s=t,await A(300);continue}if(i(e,n,o,{requireRect:!1}).matches[0])return f&&c.recordAction(f,{command:u,positionals:l.positionals??[],flags:d,result:{found:!0,waitedMs:Date.now()-_}}),{ok:!0,data:{found:!0,waitedMs:Date.now()-_}};await A(300)}return s?S(s):t("COMMAND_FAILED","find wait timed out")}async function C(e){let{req:t,sessionStore:r,session:n,command:o,publicFlags:a}=e;return n&&r.recordAction(n,{command:o,positionals:t.positionals??[],flags:a,result:{found:!0}}),{ok:!0,data:{found:!0}}}async function M(t,r){let{req:n,sessionStore:o,session:a,command:i,device:s,logPath:l,publicFlags:c}=t,u=await f({device:s,node:r.node,flags:n.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(t,r,n)=>e(l,t,r,n)});return a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:c,result:{ref:r.ref,action:"get text",text:u}}),{ok:!0,data:{ref:r.ref,text:u,node:r.node}}}async function I(e,t){let{req:r,sessionStore:n,session:o,command:a,publicFlags:i}=e;return o&&n.recordAction(o,{command:a,positionals:r.positionals??[],flags:i,result:{ref:t.ref,action:"get attrs"}}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function x(e,t){let{req:r,sessionName:n,sessionStore:o,session:a,invoke:i,command:s,locator:l,query:c,publicFlags:f}=e,u=await i({token:r.token,session:n,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!u.ok)return u;let d=t.resolvedNode.rect?y(t.resolvedNode.rect):t.node.rect?y(t.node.rect):null,p={ref:t.ref,locator:l,query:c};return d&&(p.x=d.x,p.y=d.y),a&&o.recordAction(a,{command:s,positionals:r.positionals??[],flags:f,result:{ref:t.ref,action:"click",locator:l,query:c}}),{ok:!0,data:p}}async function D(e,r,n){let{req:o,sessionName:a,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=e;if(!n)return t("INVALID_ARGS","find fill requires text");let u=await l({token:o.token,session:a,command:"fill",positionals:[r.ref,n],flags:r.actionFlags});return u.ok&&s&&i.recordAction(s,{command:c,positionals:o.positionals??[],flags:f,result:{ref:r.ref,action:"fill"}}),u}async function R(e,t){let r=await F(e,t);return r.ok&&E(e,t,"focus"),r}async function K(n,o,a){let{req:i,device:s,logPath:l,session:c}=n;if(!a)return t("INVALID_ARGS","find type requires text");let f=await F(n,o);if(!f.ok)return f;let u=await r(s,"type",[a],i.flags?.out,{...e(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return E(n,o,"type"),{ok:!0,data:u??{ref:o.ref}}}async function F(n,o){var a;let i,{req:s,device:l,logPath:c,session:f}=n,u=(i=[(a=o).resolvedNode,a.node].find(h))?t("COMMAND_FAILED",`Matched element ${a.ref} is covered by another visible element and cannot be focused safely`,{ref:`@${i.ref}`,interactionBlocked:i.interactionBlocked,hint:"Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying."}):null;if(u)return u;let d=o.resolvedNode.rect?y(o.resolvedNode.rect):null;return d?{ok:!0,data:await r(l,"focus",[String(d.x),String(d.y)],s.flags?.out,{...e(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:o.ref}}:t("COMMAND_FAILED","matched element has no bounds")}function E(e,t,r){let{req:n,sessionStore:o,session:a,command:i,publicFlags:s}=e;a&&o.recordAction(a,{command:i,positionals:n.positionals??[],flags:s,result:{ref:t.ref,action:r}})}function U(e){return"role"!==e}export{parseFindArgs}from"./587.js";export{w as handleFindCommands};
1
+ import{errorResponse as e,stripInternalInteractionFlags as t,dispatchCommand as r,noActiveSessionError as n,resolveTargetDevice as a,context_contextFromFlags as o}from"./9722.js";import{parseFindSelectorExpression as i,findBestMatchesByLocator as s,parseFindArgs as l}from"./587.js";import{ensureDeviceReady as c}from"./8414.js";import{dispatchFindReadOnlyViaRuntime as f,readTextForNode as d,createSelectorCaptureRuntime as u}from"./selector-runtime.js";import{resolveActionableTouchResolution as _,isSparseSnapshotQualityVerdict as h,isSnapshotNodeInteractionBlocked as p,resolveActionableTouchNode as m}from"./2948.js";import{resolveSelectorChain as g,extractNodeText as y}from"./893.js";import{centerOfRect as A}from"./6849.js";import{sleep as w}from"./5560.js";import{recordSessionAction as S}from"./handler-utils.js";async function k(r){var o,d,p,w;let S,{req:k,sessionName:U,logPath:b,sessionStore:P,invoke:H}=r,q=k.command;if("find"!==q)return null;let O=k.positionals??[];if(0===O.length)return e("INVALID_ARGS","find requires a locator or text");let{locator:$,query:B,action:G,value:V,timeoutMs:Q}=l(O);if(!B)return e("INVALID_ARGS","find requires a value");if(k.flags?.findFirst&&k.flags?.findLast)return e("INVALID_ARGS","find accepts only one of --first or --last");let T=await f({req:k,sessionName:U,logPath:b,sessionStore:P});if(T)return T;let j=P.get(U),z="exists"===(o=G)||"wait"===o||"get_text"===o||"get_attrs"===o;if(!j&&!z)return n();let J=j?.device??await a(k.flags??{});j||await c(J);let W="click"===(d=G)||"focus"===d||"fill"===d||"type"===d,X=i($,B),Y="web"!==J.platform&&!X&&L($)&&!W?B:void 0,Z=function(e){let{device:t,session:r,req:n,logPath:a,locator:o,query:i,scope:s,interactiveOnly:l}=e,{sessionStore:c,sessionName:f}=e,d=u({device:t,session:r,sessionStore:c,sessionName:f,req:n,logPath:a});return async()=>{let{snapshot:e}=await d.capture({flags:{...n.flags,snapshotInteractiveOnly:l},snapshotScope:s,recovery:l?{legacyIosSparse:{query:i,scope:s,shouldScope:L(o)},sparseVerdictQueryScope:{query:i,shouldScope:L(o)}}:void 0});return{nodes:e.nodes,truncated:e.truncated,backend:e.backend,snapshotQuality:e.snapshotQuality}}}({device:J,session:j,req:k,logPath:b,locator:$,query:B,scope:Y,interactiveOnly:W,sessionStore:P,sessionName:U}),ee={req:k,sessionName:U,logPath:b,sessionStore:P,invoke:H,session:j,device:J,command:q,locator:$,query:B,publicFlags:{...t(k.flags)??{}}};if("wait"===G)return N(ee,Z,$,B,Q);let et=await Z();if(h(et.snapshotQuality))return C(et.snapshotQuality);let{nodes:er}=et,en=function(t){let{nodes:r,locator:n,query:a,selectorChain:o,requiresRect:i,flags:l,platform:c}=t,f=i?r.filter(e=>!v(e,r[0])):r;if(o){let t=g(f,o,{platform:c,requireRect:i,requireUnique:!1});return t?{ok:!0,node:t.node}:{ok:!1,response:e("COMMAND_FAILED","find did not match any element")}}let d=s(f,n,a,{requireRect:i});if(i&&(d.matches=function(e,t){var r,n;let a=t[0]?.rect;if(!a)return e;let o=e.filter(e=>{if(!e.rect)return!1;let t=A(e.rect);return t.x>=a.x&&t.x<=a.x+a.width&&t.y>=a.y&&t.y<=a.y+a.height});return r=o.length>0?o:e,n=t,r.length<2?r:r.map((e,t)=>({node:e,index:t,score:function(e,t){var r,n;let a=_(t,e);if("covered"===a.reason)return 0;let o=(r=a,n=t[0],r.node.rect?"semantic-target"===r.reason||"same-rect-descendant"===r.reason?4:2*!("hittable-ancestor"!==r.reason||v(r.node,n)):0);return o>0?o:e.hittable&&e.rect&&!v(e,t[0])?3:+!!e.rect}(e,n)})).sort((e,t)=>t.score!==e.score?t.score-e.score:M(e.node)-M(t.node)||e.index-t.index).map(e=>e.node)}(d.matches,r)),i&&d.matches.length>1){var u,h,p,m,w;let t=(u=d.matches,h=l,h?.findFirst?[u[0]]:h?.findLast?[u[u.length-1]]:null);if(!t){let t;return{ok:!1,response:(p=d.matches,m=n,w=a,t=p.slice(0,8).map(e=>{let t=y(e)||e.label||e.identifier||e.type||"";return`@${e.ref}${t?`(${t})`:""}`}),e("AMBIGUOUS_MATCH",`find matched ${p.length} elements for ${m} "${w}". Use a more specific locator or selector.`,{locator:m,query:w,matches:p.length,candidates:t}))}}d.matches=t}let S=d.matches[0]??null;return S?{ok:!0,node:S}:{ok:!1,response:e("COMMAND_FAILED","find did not match any element")}}({nodes:er,locator:$,query:B,selectorChain:X,requiresRect:W,flags:k.flags,platform:J.platform});if(!en.ok)return en.response;let ea=en.node,eo=W?v(S=m(p=er,w=ea),p[0])&&w.rect?w:S:ea,ei=`@${eo.ref}`,es={node:ea,resolvedNode:eo,ref:ei,nodes:er,actionFlags:{...k.flags??{},noRecord:!0}},el={exists:()=>I(ee),get_text:()=>x(ee,es),get_attrs:()=>D(ee,es),click:()=>K(ee,es),fill:()=>R(ee,es,V),focus:()=>E(ee,es),type:()=>F(ee,es,V)}[G];return el?el():null}function C(t){return e("COMMAND_FAILED","find could not read the current accessibility tree",{reason:t.reason,hint:"The snapshot quality verdict is sparse. Use screenshot as visual truth, navigate with coordinates if needed, then retry find after reaching a readable screen."})}function M(e){return e.rect?e.rect.width*e.rect.height:1/0}function v(e,t){var r,n;if(!t?.rect||!e.rect)return!1;let a=e.type?.toLowerCase()??"";return(!!a.includes("application")||!!a.includes("window"))&&(r=e.rect,n=t.rect,r.x===n.x&&r.y===n.y&&r.width===n.width&&r.height===n.height)}async function N(t,r,n,a,o){let i,{req:l,sessionStore:c,session:f,command:d,publicFlags:u}=t,_=o??1e4,p=Date.now();for(;Date.now()-p<_;){let{nodes:e,snapshotQuality:t}=await r();if(h(t)){i=t,await w(300);continue}if(s(e,n,a,{requireRect:!1}).matches[0])return S(c,f,l,d,{found:!0,waitedMs:Date.now()-p},{flags:u}),{ok:!0,data:{found:!0,waitedMs:Date.now()-p}};await w(300)}return i?C(i):e("COMMAND_FAILED","find wait timed out")}async function I(e){let{req:t,sessionStore:r,session:n,command:a,publicFlags:o}=e;return S(r,n,t,a,{found:!0},{flags:o}),{ok:!0,data:{found:!0}}}async function x(e,t){let{req:r,sessionStore:n,session:a,command:i,device:s,logPath:l,publicFlags:c}=e,f=await d({device:s,node:t.node,flags:r.flags,appBundleId:a?.appBundleId,traceOutPath:a?.trace?.outPath,surface:a?.surface,contextFromFlags:(e,t,r)=>o(l,e,t,r)});return S(n,a,r,i,{ref:t.ref,action:"get text",text:f},{flags:c}),{ok:!0,data:{ref:t.ref,text:f,node:t.node}}}async function D(e,t){let{req:r,sessionStore:n,session:a,command:o,publicFlags:i}=e;return S(n,a,r,o,{ref:t.ref,action:"get attrs"},{flags:i}),{ok:!0,data:{ref:t.ref,node:t.node}}}async function K(e,t){let{req:r,sessionName:n,sessionStore:a,session:o,invoke:i,command:s,locator:l,query:c,publicFlags:f}=e,d=await i({token:r.token,session:n,command:"click",positionals:[t.ref],flags:t.actionFlags});if(!d.ok)return d;let u=t.resolvedNode.rect?A(t.resolvedNode.rect):t.node.rect?A(t.node.rect):null,_={ref:t.ref,locator:l,query:c};return u&&(_.x=u.x,_.y=u.y),S(a,o,r,s,{ref:t.ref,action:"click",locator:l,query:c},{flags:f}),{ok:!0,data:_}}async function R(t,r,n){let{req:a,sessionName:o,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=t;if(!n)return e("INVALID_ARGS","find fill requires text");let d=await l({token:a.token,session:o,command:"fill",positionals:[r.ref,n],flags:r.actionFlags});return d.ok&&S(i,s,a,c,{ref:r.ref,action:"fill"},{flags:f}),d}async function E(e,t){let r=await U(e,t);return r.ok&&b(e,t,"focus"),r}async function F(t,n,a){let{req:i,device:s,logPath:l,session:c}=t;if(!a)return e("INVALID_ARGS","find type requires text");let f=await U(t,n);if(!f.ok)return f;let d=await r(s,"type",[a],i.flags?.out,{...o(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return b(t,n,"type"),{ok:!0,data:d??{ref:n.ref}}}async function U(t,n){var a;let i,{req:s,device:l,logPath:c,session:f}=t,d=(i=[(a=n).resolvedNode,a.node].find(p))?e("COMMAND_FAILED",`Matched element ${a.ref} is covered by another visible element and cannot be focused safely`,{ref:`@${i.ref}`,interactionBlocked:i.interactionBlocked,hint:"Use a different visible target, scroll it clear of the overlay, or inspect with snapshot/screenshot before retrying."}):null;if(d)return d;let u=n.resolvedNode.rect?A(n.resolvedNode.rect):null;return u?{ok:!0,data:await r(l,"focus",[String(u.x),String(u.y)],s.flags?.out,{...o(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:n.ref}}:e("COMMAND_FAILED","matched element has no bounds")}function b(e,t,r){let{req:n,sessionStore:a,session:o,command:i,publicFlags:s}=e;S(a,o,n,i,{ref:t.ref,action:r},{flags:s})}function L(e){return"role"!==e}export{parseFindArgs}from"./587.js";export{k as handleFindCommands};
@@ -26,16 +26,12 @@ export declare function findBestMatchesByLocator(nodes: SnapshotNode[], locator:
26
26
  score: number;
27
27
  };
28
28
 
29
- export declare type FindLocator = (typeof FIND_LOCATORS)[number];
29
+ declare type FindLocator = (typeof FIND_LOCATORS)[number];
30
30
 
31
31
  export declare type FindMatchOptions = {
32
32
  requireRect?: boolean;
33
33
  };
34
34
 
35
- export declare function normalizeRole(value: string): string;
36
-
37
- export declare function normalizeText(value: string): string;
38
-
39
35
  export declare function parseFindArgs(args: string[]): {
40
36
  locator: FindLocator;
41
37
  query: string;
@@ -78,7 +74,7 @@ declare type Rect = {
78
74
  height: number;
79
75
  };
80
76
 
81
- export declare type SnapshotNode = RawSnapshotNode & {
77
+ declare type SnapshotNode = RawSnapshotNode & {
82
78
  ref: string;
83
79
  };
84
80
 
@@ -1 +1 @@
1
- import{findBestMatchesByLocator as e}from"./587.js";function o(o,r,t,_){return e(o,r,t,"boolean"==typeof _?{requireRect:_}:_)}export{normalizeRole,normalizeText,parseFindArgs}from"./587.js";export{o as findBestMatchesByLocator};
1
+ import{findBestMatchesByLocator as e}from"./587.js";function o(o,r,t,_){return e(o,r,t,"boolean"==typeof _?{requireRect:_}:_)}export{parseFindArgs}from"./587.js";export{o as findBestMatchesByLocator};
@@ -1,9 +1 @@
1
- import t from"node:fs";import e from"node:path";import{formatDurationSeconds as r,replayTestFailureStepLines as s}from"./9919.js";import{AppError as i}from"./733.js";import{colorize as n,supportsColor as o,printJson as a,readCommandMessage as u}from"./2948.js";import{runCliCommandWithOutput as d,writeCommandOutput as l}from"./cli.js";function f(t){return"failed"===t.status}function c(t){return"passed"===t.status&&t.attempts>1}function p(t){let r=$(t),s=e.basename(t.file),i=r&&r.length>0?`${JSON.stringify(r)} in ${s}`:s;return`${i}${m(t)}`}function $(t){let e=t.title?.trim();return e&&e.length>0?e:void 0}function m(t){if(!("shardIndex"in t)||"number"!=typeof t.shardIndex)return"";let e="number"==typeof t.shardCount?t.shardCount:"?",r="string"==typeof t.deviceId?` ${t.deviceId}`:"";return` [shard ${t.shardIndex+1}/${e}${r}]`}function h(t,e,r={}){r.includeMessage&&t.push(`errorMessage: ${e.message}`),_(t,y(e)),_(t,M(e,"diagnosticId")),_(t,w(e,"logPath")),!1!==r.includeDetails&&g(t,e,r.detailsIndent)}function g(t,e,r){let s=e.details?JSON.stringify(e.details,null,r):void 0;s&&t.push(`details: ${s}`)}function v(t,e){return"artifactsDir"in t&&t.artifactsDir?`${e}: ${t.artifactsDir}`:void 0}function y(t){return t.hint?`hint: ${t.hint}`:void 0}function M(t,e){return t.diagnosticId?`${e}: ${t.diagnosticId}`:void 0}function w(t,e){return t.logPath?`${e}: ${t.logPath}`:void 0}function _(t,e){e&&t.push(e)}function C(t){return void 0!==t}function I(t){return(Math.max(0,t)/1e3).toFixed(3)}function b(t){return t.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&apos;")}async function x({command:A,positionals:S,flags:D,client:k,debug:j}){let{result:F,cliOutput:K}=await d({client:k,command:A,positionals:S,flags:D});if(K){var N,P;N=D,P=K,!N.json&&P.stderr&&process.stderr.write(P.stderr),l(N,N.json?P.jsonData??P.data:P.data,()=>P.text)}else{let d=function(d,x,A,S={}){return"test"===d?function(u){let{suite:d,json:l,debug:x,reportJunit:A}=u;return(A&&function(r,s){let n=e.dirname(r);try{t.mkdirSync(n,{recursive:!0}),t.writeFileSync(r,function(t){let r=['<?xml version="1.0" encoding="UTF-8"?>',"<testsuites>",` <testsuite name="agent-device replay suite" tests="${t.total}" failures="${t.failed}" skipped="${t.skipped}" time="${I(t.durationMs)}">`];for(let s of t.tests)r.push(...function(t){let r=b(`${$(t)??e.basename(t.file)}${m(t)}`),s=b(`${"."===e.dirname(t.file)?t.file:e.dirname(t.file)}${m(t)}`),i=b(t.file),n=I(t.durationMs),o=[` <testcase classname="${s}" name="${r}" file="${i}" time="${n}">`];"failed"===t.status?o.push(` <failure message="${b(t.error.message)}">${b(function(t){let e=[t.error.message];return h(e,t.error,{includeDetails:!1}),_(e,v(t,"artifactsDir")),g(e,t.error,2),e.join("\n")}(t))}</failure>`):"skipped"===t.status&&o.push(` <skipped message="${b(t.message)}" />`);let a=function(t){let e=[`status: ${t.status}`,`durationMs: ${t.durationMs}`];return function(t,e){var r,s,i,n,o;for(let s of(_(t,"attempts"in e?`attempts: ${e.attempts}`:void 0),_(t,"session"in e?`session: ${e.session}`:void 0),_(t,"replayed"in e?`replayed: ${e.replayed}`:void 0),_(t,"healed"in e?`healed: ${e.healed}`:void 0),r=e,"passed"!==r.status?[]:(r.warnings??[]).map(t=>`warning: ${t}`)))t.push(s);_(t,v(e,"artifactsDir")),s=t,i=e,"shardIndex"in i&&"number"==typeof i.shardIndex&&(s.push(`shardIndex: ${i.shardIndex}`),_(s,"number"==typeof i.shardCount?`shardCount: ${i.shardCount}`:void 0),_(s,"string"==typeof i.deviceId?`deviceId: ${i.deviceId}`:void 0)),"failed"===e.status&&(n=t,o=e,n.push(`errorCode: ${o.error.code}`),h(n,o.error,{includeMessage:!0})),_(t,c(e)?"flaky: true":void 0)}(e,t),e.join("\n")}(t);return a&&o.push(` <system-out>${b(a)}</system-out>`),o.push(" </testcase>"),o}(s));return r.push(" </testsuite>"),r.push("</testsuites>"),`${r.join("\n")}
2
- `}(s),"utf8")}catch(e){let t=e instanceof Error?e.message:String(e);throw new i("COMMAND_FAILED",`Failed to write JUnit report to ${r}: ${t}`)}}(A,d),l)?(a({success:!0,data:d}),+(d.failed>0)):function(t,e={}){var i,a;let u,d,l,$=t.tests.filter(c);return process.stdout.write(`${(i=t,a=$.length,u="number"==typeof i.durationMs?i.durationMs:void 0,d=a>0?`, ${a} flaky`:"",l=void 0!==u?` in ${r(u)}`:"",`Test summary: ${i.passed} passed, ${i.failed} failed${d}${l}`)}
3
- `),function(t,e={}){if(0!==t.length)for(let r of(process.stdout.write("\n"),process.stdout.write("Failures:\n"),t))process.stdout.write(` ${p(r)}
4
- `),function(t,e){let{debug:r,indent:i}=e;for(let e of(process.stdout.write(`${i}${t.error?.message??"Unknown test failure"}
5
- `),[y(t.error),v(t,"artifacts"),w(t.error,"log"),M(t.error,"diagnostic")].filter(C)))process.stdout.write(`${i}${e}
6
- `);if(r)for(let e of s(t))process.stdout.write(`${i}${e}
7
- `)}(r,{debug:e.debug,indent:" "})}(t.tests.filter(f),{debug:e.debug}),function(t){if(0!==t.length)for(let e of(process.stdout.write("\n"),process.stdout.write("Flaky tests:\n"),t))for(let t of(process.stdout.write(` ${o()?n("✓","yellow"):"✓"} ${p(e)} after ${e.attempts} attempts${function(t){let e=["number"==typeof t.finalAttemptDurationMs?`passed attempt ${r(t.finalAttemptDurationMs)}`:"",t.durationMs>0?`total ${r(t.durationMs)}`:""].filter(Boolean);return e.length>0?` (${e.join(", ")})`:""}(e)}
8
- `),e.attemptFailures??[])){let e="number"==typeof t.durationMs?` (${r(t.durationMs)})`:"";process.stdout.write(` attempt ${t.attempt} failed${e}: ${t.message}
9
- `)}}($),+(t.failed>0)}(d,{debug:x})}({suite:A,debug:S.debug,json:x.json,reportJunit:x.reportJunit}):(l(x,A,()=>u(A)),0)}(A,D,F,{debug:j});0!==d&&process.exit(d)}return!0}export{x as runGenericClientBackedCommand};
1
+ import{runCliCommandWithOutput as e,renderReplayTestResponse as r,writeCommandOutput as t}from"./cli.js";import{isNonDefaultResponseLevel as o}from"./6849.js";import{readCommandMessage as n}from"./2948.js";async function s({command:i,positionals:a,flags:_,client:p,debug:u,replayTestReporterRuntime:m}){let{result:d,cliOutput:c}=await e({client:p,command:i,positionals:a,flags:_});if(o(_.responseLevel))return t(_,d,()=>JSON.stringify(d,null,2)),!0;if(c){var f,l;f=_,l=c,!f.json&&l.stderr&&process.stderr.write(l.stderr),t(f,f.json?l.jsonData??l.data:l.data,()=>l.text)}else{let e=await function(e,o,s,i={}){return"test"===e?r({suite:s,debug:i.debug,verbose:o.verbose,json:o.json,reporter:o.reporter,reportJunit:o.reportJunit,reporterRuntime:i.replayTestReporterRuntime}):(t(o,s,()=>n(s)),0)}(i,_,d,{debug:u,replayTestReporterRuntime:m});0!==e&&process.exit(e)}return!0}export{s as runGenericClientBackedCommand};
@@ -0,0 +1 @@
1
+ function o(o,s,i,n,t,l){s&&o.recordAction(s,{command:n,positionals:l?.positionals??i.positionals??[],flags:l?.flags??i.flags??{},result:t??{}})}export{o as recordSessionAction};