agent-device 0.17.10 → 0.18.1

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 (160) hide show
  1. package/README.md +3 -2
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.10.apk → agent-device-android-multitouch-helper-0.18.1.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.18.1.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.17.10.manifest.json → agent-device-android-multitouch-helper-0.18.1.manifest.json} +4 -4
  5. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.10.apk → agent-device-android-snapshot-helper-0.18.1.apk} +0 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.18.1.apk.sha256 +1 -0
  7. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.17.10.manifest.json → agent-device-android-snapshot-helper-0.18.1.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/dist/src/1986.js +1 -0
  21. package/dist/src/2748.js +1 -1
  22. package/dist/src/2948.js +21 -21
  23. package/dist/src/314.js +1 -1
  24. package/dist/src/3340.js +8 -7
  25. package/dist/src/432.js +4 -4
  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/5643.js +1 -0
  32. package/dist/src/587.js +1 -1
  33. package/dist/src/5913.js +4 -0
  34. package/dist/src/6849.js +1 -0
  35. package/dist/src/6918.js +1 -1
  36. package/dist/src/6967.js +1 -0
  37. package/dist/src/760.js +1 -0
  38. package/dist/src/7871.js +1 -0
  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 +1 -1
  44. package/dist/src/8936.js +1 -0
  45. package/dist/src/9414.js +1 -0
  46. package/dist/src/9581.js +5 -5
  47. package/dist/src/9624.js +1 -1
  48. package/dist/src/9722.js +37 -37
  49. package/dist/src/android-adb.d.ts +19 -54
  50. package/dist/src/android-adb.js +1 -1
  51. package/dist/src/android.js +5 -5
  52. package/dist/src/apps.js +9 -11
  53. package/dist/src/audio-probe.js +1 -0
  54. package/dist/src/batch.d.ts +50 -25
  55. package/dist/src/batch.js +1 -1
  56. package/dist/src/cli-help.js +104 -37
  57. package/dist/src/cli.js +36 -27
  58. package/dist/src/contracts.d.ts +46 -122
  59. package/dist/src/contracts.js +1 -1
  60. package/dist/src/debug-symbols.js +3 -0
  61. package/dist/src/devices.js +1 -1
  62. package/dist/src/devices~1.js +1 -1
  63. package/dist/src/devices~2.js +1 -1
  64. package/dist/src/find.js +1 -1
  65. package/dist/src/finders.d.ts +2 -6
  66. package/dist/src/finders.js +1 -1
  67. package/dist/src/generic.js +1 -9
  68. package/dist/src/handler-utils.js +1 -0
  69. package/dist/src/index.d.ts +500 -182
  70. package/dist/src/index.js +1 -1
  71. package/dist/src/input-actions.js +1 -1
  72. package/dist/src/input-actions~1.js +1 -1
  73. package/dist/src/install-source.d.ts +0 -26
  74. package/dist/src/install-source.js +1 -1
  75. package/dist/src/interaction.js +1 -1
  76. package/dist/src/interactor.js +1 -0
  77. package/dist/src/internal/bin.js +1 -1
  78. package/dist/src/internal/companion-tunnel.js +1 -1
  79. package/dist/src/internal/png-worker.js +1 -1
  80. package/dist/src/lease.js +1 -1
  81. package/dist/src/linux.js +1 -1
  82. package/dist/src/metro.d.ts +10 -134
  83. package/dist/src/metro.js +1 -1
  84. package/dist/src/notifications.js +1 -1
  85. package/dist/src/react-native.js +1 -1
  86. package/dist/src/record-trace-recording.js +3 -3
  87. package/dist/src/record-trace.js +1 -1
  88. package/dist/src/remote-config.d.ts +28 -24
  89. package/dist/src/remote-config.js +1 -1
  90. package/dist/src/runner-sequence.js +1 -0
  91. package/dist/src/selector-runtime.js +1 -1
  92. package/dist/src/selectors.d.ts +7 -3
  93. package/dist/src/selectors.js +1 -1
  94. package/dist/src/server.js +2 -2
  95. package/dist/src/session.js +11 -8
  96. package/dist/src/simulator.js +2 -0
  97. package/dist/src/snapshot.js +2 -2
  98. package/dist/src/web.js +1 -1
  99. package/macos-helper/Sources/AgentDeviceMacOSHelper/AudioProbe.swift +297 -0
  100. package/macos-helper/Sources/AgentDeviceMacOSHelper/main.swift +30 -0
  101. package/package.json +15 -11
  102. package/server.json +2 -2
  103. package/android-multitouch-helper/README.md +0 -41
  104. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.17.10.apk.sha256 +0 -1
  105. package/android-snapshot-helper/README.md +0 -88
  106. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.17.10.apk.sha256 +0 -1
  107. package/dist/src/2133.js +0 -1
  108. package/dist/src/2577.js +0 -1
  109. package/dist/src/2954.js +0 -2
  110. package/dist/src/4291.js +0 -1
  111. package/dist/src/4723.js +0 -1
  112. package/dist/src/5628.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/8358.js +0 -4
  119. package/dist/src/9919.js +0 -6
  120. package/dist/src/android-snapshot-helper.d.ts +0 -359
  121. package/dist/src/android-snapshot-helper.js +0 -1
  122. package/dist/src/apple.js +0 -1
  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/RunnerTests.swift +0 -0
  155. /package/{ios-runner → apple-runner}/AgentDeviceRunner/AgentDeviceRunnerUITests.xctestplan +0 -0
  156. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-overlay.swift +0 -0
  157. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-resize.swift +0 -0
  158. /package/{ios-runner → apple-runner}/AgentDeviceRunner/RecordingScripts/recording-trim.swift +0 -0
  159. /package/dist/src/{4069.js → 4917.js} +0 -0
  160. /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'];
8
-
9
- export declare const DAEMON_TRANSPORT_PREFERENCES: readonly ['auto', 'socket', 'http'];
3
+ declare const DAEMON_LOCK_POLICIES: readonly ['reject', 'strip'];
10
4
 
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;
@@ -69,6 +75,9 @@ export declare type DaemonRequestMeta = {
69
75
  leaseId?: string;
70
76
  leaseTtlMs?: number;
71
77
  leaseBackend?: LeaseBackend;
78
+ leaseProvider?: string;
79
+ deviceKey?: string;
80
+ clientId?: string;
72
81
  sessionIsolation?: SessionIsolationMode;
73
82
  uploadedArtifactId?: string;
74
83
  clientArtifactPaths?: Record<string, string>;
@@ -78,7 +87,7 @@ export declare type DaemonRequestMeta = {
78
87
  materializationId?: string;
79
88
  lockPolicy?: DaemonLockPolicy;
80
89
  lockPlatform?: PlatformSelector;
81
- requestProgress?: 'replay-test';
90
+ requestProgress?: 'replay-test' | 'command';
82
91
  };
83
92
 
84
93
  export declare type DaemonResponse = {
@@ -91,64 +100,7 @@ export declare type DaemonResponse = {
91
100
 
92
101
  export declare type DaemonResponseData = Record<string, unknown> & {
93
102
  artifacts?: DaemonArtifact[];
94
- };
95
-
96
- export declare const daemonRuntimeSchema: RuntimeSchema<SessionRuntimeHints>;
97
-
98
- export declare type DaemonServerMode = (typeof DAEMON_SERVER_MODES)[number];
99
-
100
- export declare type DaemonTransportPreference = (typeof DAEMON_TRANSPORT_PREFERENCES)[number];
101
-
102
- export declare type DebugSymbolsCrashFrame = {
103
- index: number;
104
- image: string;
105
- address: string;
106
- symbol?: string;
107
- };
108
-
109
- export declare type DebugSymbolsCrashSummary = {
110
- format: 'ips' | 'text';
111
- appName?: string;
112
- bundleId?: string;
113
- version?: string;
114
- incident?: string;
115
- timestamp?: string;
116
- exceptionType?: string;
117
- exceptionCodes?: string;
118
- terminationReason?: string;
119
- crashedThread?: number;
120
- topFrames: DebugSymbolsCrashFrame[];
121
- findings: string[];
122
- };
123
-
124
- export declare type DebugSymbolsImage = {
125
- name: string;
126
- uuid: string;
127
- arch?: string;
128
- dsymPath: string;
129
- binaryPath: string;
130
- };
131
-
132
- export declare type DebugSymbolsOptions = {
133
- action?: 'symbols';
134
- artifact: string;
135
- dsym?: string;
136
- searchPath?: string;
137
- out?: string;
138
- cwd?: string;
139
- };
140
-
141
- export declare type DebugSymbolsResult = {
142
- kind: 'debugSymbols';
143
- platform: 'apple';
144
- artifactPath: string;
145
- outPath: string;
146
- crash: DebugSymbolsCrashSummary;
147
- matchedImages: DebugSymbolsImage[];
148
- symbolicatedFrames: number;
149
- skippedImages: number;
150
- warnings?: string[];
151
- message: string;
103
+ cost?: ResponseCost;
152
104
  };
153
105
 
154
106
  export declare function defaultHintForCode(code: string): string | undefined;
@@ -162,11 +114,7 @@ export declare type JsonRpcRequestEnvelope<TParams = unknown> = {
162
114
  params?: TParams;
163
115
  };
164
116
 
165
- export declare const jsonRpcRequestSchema: RuntimeSchema<JsonRpcRequestEnvelope<unknown>>;
166
-
167
- 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';
168
-
169
- export declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
117
+ declare const LEASE_BACKENDS: readonly ['ios-simulator', 'ios-instance', 'android-instance'];
170
118
 
171
119
  export declare type LeaseAllocatePayload = {
172
120
  token?: string;
@@ -176,10 +124,11 @@ export declare type LeaseAllocatePayload = {
176
124
  runId?: string;
177
125
  ttlMs?: number;
178
126
  backend?: LeaseBackend;
127
+ leaseProvider?: string;
128
+ deviceKey?: string;
129
+ clientId?: string;
179
130
  };
180
131
 
181
- export declare const leaseAllocateSchema: RuntimeSchema<LeaseAllocatePayload>;
182
-
183
132
  export declare type LeaseBackend = (typeof LEASE_BACKENDS)[number];
184
133
 
185
134
  export declare type LeaseHeartbeatPayload = {
@@ -190,10 +139,12 @@ export declare type LeaseHeartbeatPayload = {
190
139
  runId?: string;
191
140
  leaseId?: string;
192
141
  ttlMs?: number;
142
+ backend?: LeaseBackend;
143
+ leaseProvider?: string;
144
+ deviceKey?: string;
145
+ clientId?: string;
193
146
  };
194
147
 
195
- export declare const leaseHeartbeatSchema: RuntimeSchema<LeaseHeartbeatPayload>;
196
-
197
148
  export declare type LeaseReleasePayload = {
198
149
  token?: string;
199
150
  session?: string;
@@ -201,14 +152,12 @@ export declare type LeaseReleasePayload = {
201
152
  tenant?: string;
202
153
  runId?: string;
203
154
  leaseId?: string;
155
+ backend?: LeaseBackend;
156
+ leaseProvider?: string;
157
+ deviceKey?: string;
158
+ clientId?: string;
204
159
  };
205
160
 
206
- export declare const leaseReleaseSchema: RuntimeSchema<LeaseReleasePayload>;
207
-
208
- export declare const NETWORK_INCLUDE_MODES: readonly ['summary', 'headers', 'body', 'all'];
209
-
210
- export declare type NetworkIncludeMode = (typeof NETWORK_INCLUDE_MODES)[number];
211
-
212
161
  declare type NormalizedError = {
213
162
  code: string;
214
163
  message: string;
@@ -232,47 +181,26 @@ declare type Point = {
232
181
  y: number;
233
182
  };
234
183
 
235
- declare type RawSnapshotNode = {
236
- index: number;
237
- type?: string;
238
- role?: string;
239
- subrole?: string;
240
- label?: string;
241
- value?: string;
242
- identifier?: string;
243
- rect?: Rect;
244
- enabled?: boolean;
245
- selected?: boolean;
246
- focused?: boolean;
247
- visibleToUser?: boolean;
248
- hittable?: boolean;
249
- depth?: number;
250
- parentIndex?: number;
251
- pid?: number;
252
- bundleId?: string;
253
- appName?: string;
254
- windowTitle?: string;
255
- surface?: string;
256
- hiddenContentAbove?: boolean;
257
- hiddenContentBelow?: boolean;
258
- interactionBlocked?: 'covered';
259
- presentationHints?: string[];
260
- };
261
-
262
- export declare type Rect = {
184
+ declare type Rect = {
263
185
  x: number;
264
186
  y: number;
265
187
  width: number;
266
188
  height: number;
267
189
  };
268
190
 
269
- declare type RuntimeSchema<T> = {
270
- 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;
271
197
  };
272
198
 
273
- 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'];
274
202
 
275
- export declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
203
+ declare type SessionIsolationMode = (typeof SESSION_ISOLATION_MODES)[number];
276
204
 
277
205
  export declare type SessionRuntimeHints = {
278
206
  platform?: 'ios' | 'android';
@@ -282,8 +210,4 @@ export declare type SessionRuntimeHints = {
282
210
  launchUrl?: string;
283
211
  };
284
212
 
285
- export declare type SnapshotNode = RawSnapshotNode & {
286
- ref: string;
287
- };
288
-
289
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{sortAppleDevicesForSelection as o}from"./6849.js";import{buildHostMacDevice as n}from"./devices~1.js";import{runXcrun as s,resolveAppleToolProvider as l,buildSimctlArgs as a}from"./9722.js";import{resolveIosSimulatorDeviceSetPath as u}from"./3340.js";let c=/^(iphone|ipad|ipod|appletv|realitydevice)/i,d=/ipad/i,p=/\b(apple vision|vision pro|xros|visionos|realitydevice)\b/i,f=/\b(iphone|ipad|ipod)\b/i,m=/^appletv/i,v=["apple tv","appletv","tvos"],_=/^==\s*(.+?)\s*==$/,h=/^(?<name>.+?)\s+\[(?<id>[^[\]]+)\]\s*$/;function w(e){return(e??"").trim().toLowerCase()}function S(e){return w(e.hardwareProperties?.platform)}function P(e){return e.includes("tvos")}function y(e){let t=w(e);return v.some(e=>t.includes(e))}function C(e,t){return"tv"===e?"tvos":t.some(e=>p.test(e))?"visionos":t.some(e=>d.test(e))?"ipados":"ios"}function b(e){return[e.name??"",e.deviceProperties?.name??"",e.deviceProperties?.deviceType??""]}function O(e){return e.hardwareProperties?.productType??e.deviceProperties?.productType??""}async function A(e={}){let t,i,r=u(e.simulatorSetPath),n=e.target;try{t=await s(a(["list","devices","-j"],{simulatorSetPath:r}))}catch{return null}try{i=JSON.parse(t.stdout)}catch{return null}return o(N(i,r)).find(e=>!n||e.target===n)??null}function N(e,t){let i=[];for(let[r,o]of Object.entries(e.devices))if(function(e){let t=w(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=P(w(r))?"tv":"mobile";i.push({platform:"ios",id:e.udid,name:e.name,kind:"simulator",target:o,appleOs:C(o,[e.deviceTypeIdentifier??"",e.name]),booted:"Booted"===e.state,...t?{simulatorSetPath:t}:{}})}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 M(){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 s(["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=S(e);return!!(r.includes("ios")||r.includes("tvos")||(t=r).includes("xros")||t.includes("visionos"))||(i=O(e),!!c.test(i.trim())||b(e).some(y))}(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 P(S(e))?"tv":(t=O(e),m.test(t.trim())||b(e).some(y))?"tv":"mobile"}(i);t.push({platform:"ios",id:e,name:r,kind:"device",target:o,appleOs:C(o,[O(i),...b(i)]),booted:!0})}return t}(JSON.parse(n))}catch{return[]}finally{r&&await e.rm(r,{force:!0}).catch(()=>{})}}async function K(){try{let e=await s(["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=_.exec(e);if(o){i=o[1]?.trim()??null;continue}if("Devices"!==i)continue;let n=h.exec(e),s=n?.groups?.id?.trim()??"",l=n?.groups?.name?.trim()??"";if(!s||!l)continue;let a=function(e){return y(e)?"tv":f.test(e.trim())||p.test(e)?"mobile":null}(l);a&&t.push({platform:"ios",id:s,name:l,kind:"device",target:a,appleOs:C(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 l().whichCommand("xcrun"))throw new r("TOOL_MISSING","xcrun not found in PATH");let t=u(e.simulatorSetPath),i=await s(a(["list","devices","-j"],{simulatorSetPath:t})),c=[];try{let e=JSON.parse(i.stdout);c=N(e,t)}catch(e){throw new r("COMMAND_FAILED","Failed to parse simctl devices JSON",void 0,e)}if(c.push(n()),e.udid&&c.some(t=>"ios"===t.platform&&t.id===e.udid))return c;if(t)return o(c);let[d,p]=await Promise.all([M(),K()]);return c=x(c,d),o(x(c,p))}export{A 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:"macos",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{stripInternalInteractionFlags as e,ensureDeviceReady as t,errorResponse as r,dispatchCommand as n,resolveTargetDevice as o,context_contextFromFlags as a}from"./9722.js";import{parseFindSelectorExpression as i,findBestMatchesByLocator as s,parseFindArgs as l}from"./587.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(n){var a,f,h,A;let w,{req:K,sessionName:b,logPath:U,sessionStore:L,invoke:O}=n,P=K.command;if("find"!==P)return null;let q=K.positionals??[];if(0===q.length)return r("INVALID_ARGS","find requires a locator or text");let{locator:H,query:$,action:B,value:G,timeoutMs:V}=l(q);if(!$)return r("INVALID_ARGS","find requires a value");if(K.flags?.findFirst&&K.flags?.findLast)return r("INVALID_ARGS","find accepts only one of --first or --last");let Q=await c({req:K,sessionName:b,logPath:U,sessionStore:L});if(Q)return Q;let T=L.get(b),j="exists"===(a=B)||"wait"===a||"get_text"===a||"get_attrs"===a;if(!T&&!j)return r("SESSION_NOT_FOUND","No active session. Run open first.");let z=T?.device??await o(K.flags??{});T||await t(z);let J="click"===(f=B)||"focus"===f||"fill"===f||"type"===f,W=i(H,$),X="web"!==z.platform&&!W&&E(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:E(a)},sparseVerdictQueryScope:{query:i,shouldScope:E(a)}}:void 0});return{nodes:e.nodes,truncated:e.truncated,backend:e.backend,snapshotQuality:e.snapshotQuality}}}({device:z,session:T,req:K,logPath:U,locator:H,query:$,scope:X,interactiveOnly:J,sessionStore:L,sessionName:b}),Z={req:K,sessionName:b,logPath:U,sessionStore:L,invoke:O,session:T,device:z,command:P,locator:H,query:$,publicFlags:{...e(K.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:t,locator:n,query:o,selectorChain:a,requiresRect:i,flags:l,platform:c}=e,f=i?t.filter(e=>!N(e,t[0])):t;if(a){let e=g(f,a,{platform:c,requireRect:i,requireUnique:!1});return e?{ok:!0,node:e.node}:{ok:!1,response:r("COMMAND_FAILED","find did not match any element")}}let u=s(f,n,o,{requireRect:i});if(i&&(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,t)),i&&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})`:""}`}),r("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:r("COMMAND_FAILED","find did not match any element")}}({nodes:et,locator:H,query:$,selectorChain:W,requiresRect:J,flags:K.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:{...K.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:()=>F(Z,ei,G)}[B];return es?es():null}function S(e){return r("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,t,n,o,a){let i,{req:l,sessionStore:c,session:f,command:u,publicFlags:d}=e,h=a??1e4,_=Date.now();for(;Date.now()-_<h;){let{nodes:e,snapshotQuality:r}=await t();if(p(r)){i=r,await A(300);continue}if(s(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 i?S(i):r("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(e,t){let{req:r,sessionStore:n,session:o,command:i,device:s,logPath:l,publicFlags:c}=e,u=await f({device:s,node:t.node,flags:r.flags,appBundleId:o?.appBundleId,traceOutPath:o?.trace?.outPath,surface:o?.surface,contextFromFlags:(e,t,r)=>a(l,e,t,r)});return o&&n.recordAction(o,{command:i,positionals:r.positionals??[],flags:c,result:{ref:t.ref,action:"get text",text:u}}),{ok:!0,data:{ref:t.ref,text:u,node:t.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,t,n){let{req:o,sessionName:a,sessionStore:i,session:s,invoke:l,command:c,publicFlags:f}=e;if(!n)return r("INVALID_ARGS","find fill requires text");let u=await l({token:o.token,session:a,command:"fill",positionals:[t.ref,n],flags:t.actionFlags});return u.ok&&s&&i.recordAction(s,{command:c,positionals:o.positionals??[],flags:f,result:{ref:t.ref,action:"fill"}}),u}async function R(e,t){let r=await K(e,t);return r.ok&&b(e,t,"focus"),r}async function F(e,t,o){let{req:i,device:s,logPath:l,session:c}=e;if(!o)return r("INVALID_ARGS","find type requires text");let f=await K(e,t);if(!f.ok)return f;let u=await n(s,"type",[o],i.flags?.out,{...a(l,i.flags,c?.appBundleId,c?.trace?.outPath)});return b(e,t,"type"),{ok:!0,data:u??{ref:t.ref}}}async function K(e,t){var o;let i,{req:s,device:l,logPath:c,session:f}=e,u=(i=[(o=t).resolvedNode,o.node].find(h))?r("COMMAND_FAILED",`Matched element ${o.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=t.resolvedNode.rect?y(t.resolvedNode.rect):null;return d?{ok:!0,data:await n(l,"focus",[String(d.x),String(d.y)],s.flags?.out,{...a(c,s.flags,f?.appBundleId,f?.trace?.outPath)})??{ref:t.ref}}:r("COMMAND_FAILED","matched element has no bounds")}function b(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 E(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};