agent-device 0.16.10 → 0.16.12

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 (45) hide show
  1. package/README.md +8 -8
  2. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.10.apk → agent-device-android-multitouch-helper-0.16.12.apk} +0 -0
  3. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.12.apk.sha256 +1 -0
  4. package/android-multitouch-helper/dist/{agent-device-android-multitouch-helper-0.16.10.manifest.json → agent-device-android-multitouch-helper-0.16.12.manifest.json} +4 -4
  5. package/android-snapshot-helper/README.md +6 -0
  6. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.12.apk +0 -0
  7. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.12.apk.sha256 +1 -0
  8. package/android-snapshot-helper/dist/{agent-device-android-snapshot-helper-0.16.10.manifest.json → agent-device-android-snapshot-helper-0.16.12.manifest.json} +6 -6
  9. package/dist/src/1352.js +1 -1
  10. package/dist/src/221.js +6 -6
  11. package/dist/src/2415.js +27 -27
  12. package/dist/src/2805.js +1 -1
  13. package/dist/src/4778.js +1 -0
  14. package/dist/src/5792.js +1 -1
  15. package/dist/src/6085.js +1 -1
  16. package/dist/src/6232.js +1 -1
  17. package/dist/src/8699.js +1 -1
  18. package/dist/src/9238.js +4 -0
  19. package/dist/src/9533.js +1 -1
  20. package/dist/src/9542.js +3 -3
  21. package/dist/src/apple.js +1 -1
  22. package/dist/src/args.js +54 -25
  23. package/dist/src/batch.d.ts +1 -0
  24. package/dist/src/cli.js +19 -19
  25. package/dist/src/command-metadata.js +1 -1
  26. package/dist/src/command-surface.js +1 -1
  27. package/dist/src/contracts.d.ts +1 -0
  28. package/dist/src/contracts.js +1 -1
  29. package/dist/src/generic.js +10 -10
  30. package/dist/src/index.d.ts +9 -0
  31. package/dist/src/record-trace.js +3 -3
  32. package/dist/src/session.js +9 -9
  33. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.h +7 -0
  34. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerSynthesizedGesture.m +109 -0
  35. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+CommandExecution.swift +123 -32
  36. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Interaction.swift +36 -0
  37. package/ios-runner/AgentDeviceRunner/AgentDeviceRunnerUITests/RunnerTests+Models.swift +11 -1
  38. package/package.json +1 -1
  39. package/server.json +2 -2
  40. package/skills/dogfood/SKILL.md +1 -1
  41. package/android-multitouch-helper/dist/agent-device-android-multitouch-helper-0.16.10.apk.sha256 +0 -1
  42. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.10.apk +0 -0
  43. package/android-snapshot-helper/dist/agent-device-android-snapshot-helper-0.16.10.apk.sha256 +0 -1
  44. package/dist/src/2842.js +0 -1
  45. package/dist/src/8114.js +0 -4
@@ -14,6 +14,13 @@ NS_ASSUME_NONNULL_BEGIN
14
14
  radius:(double)radius
15
15
  durationMs:(double)durationMs;
16
16
 
17
+ + (NSString * _Nullable)synthesizeSwipeWithApplication:(id)application
18
+ x:(double)x
19
+ y:(double)y
20
+ x2:(double)x2
21
+ y2:(double)y2
22
+ durationMs:(double)durationMs;
23
+
17
24
  @end
18
25
 
19
26
  NS_ASSUME_NONNULL_END
@@ -47,6 +47,12 @@ static id RunnerPointerPath(
47
47
  double durationMs,
48
48
  double side
49
49
  );
50
+ static id RunnerSwipePointerPath(
51
+ const RunnerXCTestEventBridge *bridge,
52
+ CGPoint start,
53
+ CGPoint end,
54
+ double durationMs
55
+ );
50
56
  static CGPoint RunnerPointerPointAt(
51
57
  double x,
52
58
  double y,
@@ -58,6 +64,8 @@ static CGPoint RunnerPointerPointAt(
58
64
  double t,
59
65
  double side
60
66
  );
67
+ static CGPoint RunnerInterpolatedPoint(CGPoint start, CGPoint end, double t);
68
+ static double RunnerSmoothStep(double t);
61
69
 
62
70
  @implementation RunnerSynthesizedGesture
63
71
 
@@ -87,6 +95,26 @@ static CGPoint RunnerPointerPointAt(
87
95
  }
88
96
  }
89
97
 
98
+ + (NSString * _Nullable)synthesizeSwipeWithApplication:(id)application
99
+ x:(double)x
100
+ y:(double)y
101
+ x2:(double)x2
102
+ y2:(double)y2
103
+ durationMs:(double)durationMs {
104
+ @try {
105
+ return [self trySynthesizeSwipeWithApplication:application
106
+ x:x
107
+ y:y
108
+ x2:x2
109
+ y2:y2
110
+ durationMs:durationMs];
111
+ } @catch (NSException *exception) {
112
+ NSString *name = exception.name ?: @"NSException";
113
+ NSString *reason = exception.reason ?: @"private XCTest event synthesis failed";
114
+ return [NSString stringWithFormat:@"%@: %@", name, reason];
115
+ }
116
+ }
117
+
90
118
  + (NSString * _Nullable)trySynthesizeTransformWithApplication:(id)application
91
119
  x:(double)x
92
120
  y:(double)y
@@ -151,6 +179,51 @@ static CGPoint RunnerPointerPointAt(
151
179
  return nil;
152
180
  }
153
181
 
182
+ + (NSString * _Nullable)trySynthesizeSwipeWithApplication:(id)application
183
+ x:(double)x
184
+ y:(double)y
185
+ x2:(double)x2
186
+ y2:(double)y2
187
+ durationMs:(double)durationMs {
188
+ RunnerXCTestEventBridge bridge;
189
+ NSString *missing = RunnerResolveXCTestEventBridge(application, &bridge);
190
+ if (missing != nil) {
191
+ return missing;
192
+ }
193
+
194
+ NSInteger interfaceOrientation =
195
+ ((RunnerMsgSendInteger)objc_msgSend)(application, bridge.interfaceOrientationSelector);
196
+ NSInteger targetProcessID = ((RunnerMsgSendInteger)objc_msgSend)(application, bridge.processIDSelector);
197
+ if (targetProcessID <= 0) {
198
+ return @"private XCTest event synthesis unavailable: could not resolve target process ID";
199
+ }
200
+
201
+ id record = ((RunnerMsgSendInitRecord)objc_msgSend)(
202
+ [bridge.recordClass alloc],
203
+ bridge.initRecordSelector,
204
+ @"agent-device-swipe",
205
+ interfaceOrientation
206
+ );
207
+ if (record == nil) {
208
+ return @"private XCTest event synthesis failed: could not create event record";
209
+ }
210
+ ((RunnerMsgSendSetInteger)objc_msgSend)(record, bridge.setTargetProcessIDSelector, targetProcessID);
211
+
212
+ id path = RunnerSwipePointerPath(&bridge, CGPointMake(x, y), CGPointMake(x2, y2), durationMs);
213
+ if (path == nil) {
214
+ return @"private XCTest event synthesis failed: could not create pointer path";
215
+ }
216
+ ((RunnerMsgSendAddPath)objc_msgSend)(record, bridge.addPathSelector, path);
217
+
218
+ NSError *error = nil;
219
+ BOOL ok = ((RunnerMsgSendSynthesize)objc_msgSend)(record, bridge.synthesizeSelector, &error);
220
+ if (!ok) {
221
+ NSString *detail = error.localizedDescription ?: @"synthesizeWithError returned false";
222
+ return [NSString stringWithFormat:@"private XCTest event synthesis failed: %@", detail];
223
+ }
224
+ return nil;
225
+ }
226
+
154
227
  static NSString * _Nullable RunnerResolveXCTestEventBridge(
155
228
  id application,
156
229
  RunnerXCTestEventBridge *bridge
@@ -270,6 +343,31 @@ static id RunnerPointerPath(
270
343
  return path;
271
344
  }
272
345
 
346
+ static id RunnerSwipePointerPath(
347
+ const RunnerXCTestEventBridge *bridge,
348
+ CGPoint start,
349
+ CGPoint end,
350
+ double durationMs
351
+ ) {
352
+ id path =
353
+ ((RunnerMsgSendInitPath)objc_msgSend)([bridge->pathClass alloc], bridge->initPathSelector, start, 0.0);
354
+ if (path == nil) {
355
+ return nil;
356
+ }
357
+
358
+ int frameCount = MAX(3, (int)(durationMs / 16.0));
359
+ NSTimeInterval durationSeconds = durationMs / 1000.0;
360
+ for (int index = 1; index <= frameCount; index += 1) {
361
+ double t = (double)index / (double)frameCount;
362
+ CGPoint point = RunnerInterpolatedPoint(start, end, RunnerSmoothStep(t));
363
+ NSTimeInterval offset = durationSeconds * t;
364
+ ((RunnerMsgSendPathMove)objc_msgSend)(path, bridge->moveSelector, point, offset);
365
+ }
366
+
367
+ ((RunnerMsgSendPathOffset)objc_msgSend)(path, bridge->liftSelector, durationSeconds);
368
+ return path;
369
+ }
370
+
273
371
  static CGPoint RunnerPointerPointAt(
274
372
  double x,
275
373
  double y,
@@ -294,4 +392,15 @@ static CGPoint RunnerPointerPointAt(
294
392
  return CGPointMake(centerX + cos(angle) * radius * side, centerY + sin(angle) * radius * side);
295
393
  }
296
394
 
395
+ static CGPoint RunnerInterpolatedPoint(CGPoint start, CGPoint end, double t) {
396
+ return CGPointMake(
397
+ start.x + (end.x - start.x) * t,
398
+ start.y + (end.y - start.y) * t
399
+ );
400
+ }
401
+
402
+ static double RunnerSmoothStep(double t) {
403
+ return t * t * (3.0 - 2.0 * t);
404
+ }
405
+
297
406
  @end
@@ -13,6 +13,10 @@ extension RunnerTests {
13
13
  return (gestureStartUptimeMs, currentUptimeMs())
14
14
  }
15
15
 
16
+ private func synthesizedSwipeFallbackHoldDuration(durationMs: Double) -> TimeInterval {
17
+ min(max((durationMs / 5.0) / 1000.0, 0.016), 0.120)
18
+ }
19
+
16
20
  func unsupportedResponse(for outcome: RunnerInteractionOutcome) -> Response? {
17
21
  switch outcome {
18
22
  case .performed:
@@ -32,6 +36,43 @@ extension RunnerTests {
32
36
  case drag(DragVisualizationFrame)
33
37
  }
34
38
 
39
+ struct GestureFallback {
40
+ let strategy: String
41
+ let message: String
42
+ let hint: String?
43
+ }
44
+
45
+ private func gestureFallback(strategy: String, from outcome: RunnerInteractionOutcome) -> GestureFallback? {
46
+ switch outcome {
47
+ case .performed:
48
+ return nil
49
+ case .unsupported(let message, let hint):
50
+ return GestureFallback(strategy: strategy, message: message, hint: hint)
51
+ }
52
+ }
53
+
54
+ private func performDragSeries(
55
+ count: Int,
56
+ pauseMs: Double,
57
+ pattern: String,
58
+ points: DragPoints,
59
+ _ drag: (_ x: Double, _ y: Double, _ x2: Double, _ y2: Double) -> RunnerInteractionOutcome
60
+ ) -> RunnerInteractionOutcome {
61
+ var outcome = RunnerInteractionOutcome.performed
62
+ runSeries(count: count, pauseMs: pauseMs) { idx in
63
+ guard case .performed = outcome else {
64
+ return
65
+ }
66
+ let reverse = pattern == "ping-pong" && (idx % 2 == 1)
67
+ let startX = reverse ? points.x2 : points.x
68
+ let startY = reverse ? points.y2 : points.y
69
+ let endX = reverse ? points.x : points.x2
70
+ let endY = reverse ? points.y : points.y2
71
+ outcome = drag(startX, startY, endX, endY)
72
+ }
73
+ return outcome
74
+ }
75
+
35
76
  /// Runs a gesture action with uniform timing capture. Touch gestures pass `idleTimeout: true`
36
77
  /// (the default) to run inside the scroll idle-timeout + quiescence-skip wrapper; synthesis
37
78
  /// gestures (pinch/rotate/transform) pass `false` because RunnerSynthesizedGesture governs its
@@ -60,7 +101,8 @@ extension RunnerTests {
60
101
  private func gestureResponse(
61
102
  message: String,
62
103
  timing: (gestureStartUptimeMs: Double, gestureEndUptimeMs: Double),
63
- frame: GestureFrame = .none
104
+ frame: GestureFrame = .none,
105
+ fallback: GestureFallback? = nil
64
106
  ) -> Response {
65
107
  let data: DataPayload
66
108
  switch frame {
@@ -68,7 +110,10 @@ extension RunnerTests {
68
110
  data = DataPayload(
69
111
  message: message,
70
112
  gestureStartUptimeMs: timing.gestureStartUptimeMs,
71
- gestureEndUptimeMs: timing.gestureEndUptimeMs
113
+ gestureEndUptimeMs: timing.gestureEndUptimeMs,
114
+ gestureFallback: fallback?.strategy,
115
+ gestureFallbackMessage: fallback?.message,
116
+ gestureFallbackHint: fallback?.hint
72
117
  )
73
118
  case .touch(let f):
74
119
  data = DataPayload(
@@ -78,7 +123,10 @@ extension RunnerTests {
78
123
  x: f?.x,
79
124
  y: f?.y,
80
125
  referenceWidth: f?.referenceWidth,
81
- referenceHeight: f?.referenceHeight
126
+ referenceHeight: f?.referenceHeight,
127
+ gestureFallback: fallback?.strategy,
128
+ gestureFallbackMessage: fallback?.message,
129
+ gestureFallbackHint: fallback?.hint
82
130
  )
83
131
  case .drag(let f):
84
132
  data = DataPayload(
@@ -90,7 +138,10 @@ extension RunnerTests {
90
138
  x2: f.x2,
91
139
  y2: f.y2,
92
140
  referenceWidth: f.referenceWidth,
93
- referenceHeight: f.referenceHeight
141
+ referenceHeight: f.referenceHeight,
142
+ gestureFallback: fallback?.strategy,
143
+ gestureFallbackMessage: fallback?.message,
144
+ gestureFallbackHint: fallback?.hint
94
145
  )
95
146
  }
96
147
  return Response(ok: true, data: data)
@@ -495,7 +546,6 @@ extension RunnerTests {
495
546
  guard let x = command.x, let y = command.y, let x2 = command.x2, let y2 = command.y2 else {
496
547
  return Response(ok: false, error: ErrorPayload(message: "drag requires x, y, x2, and y2"))
497
548
  }
498
- let holdDuration = min(max((command.durationMs ?? 60) / 1000.0, 0.016), 10.0)
499
549
  let dragPoints = keyboardAvoidingDragPoints(app: activeApp, x: x, y: y, x2: x2, y2: y2)
500
550
  let dragFrame = resolvedDragVisualizationFrame(
501
551
  app: activeApp,
@@ -504,6 +554,27 @@ extension RunnerTests {
504
554
  x2: dragPoints.x2,
505
555
  y2: dragPoints.y2
506
556
  )
557
+ var fallback: GestureFallback?
558
+ if command.synthesized == true {
559
+ let durationMs = min(max(command.durationMs ?? 250, 16), 10000)
560
+ let (timing, outcome) = performGesture(activeApp, idleTimeout: false) {
561
+ synthesizedDragAt(
562
+ app: activeApp,
563
+ x: dragPoints.x,
564
+ y: dragPoints.y,
565
+ x2: dragPoints.x2,
566
+ y2: dragPoints.y2,
567
+ durationMs: durationMs
568
+ )
569
+ }
570
+ if case .performed = outcome {
571
+ return gestureResponse(message: "dragged", timing: timing, frame: .drag(dragFrame))
572
+ }
573
+ fallback = gestureFallback(strategy: "xctest-coordinate-drag", from: outcome)
574
+ }
575
+ let holdDuration = command.synthesized == true
576
+ ? synthesizedSwipeFallbackHoldDuration(durationMs: command.durationMs ?? 250)
577
+ : min(max((command.durationMs ?? 60) / 1000.0, 0.016), 10.0)
507
578
  let (timing, outcome) = performGesture(activeApp) {
508
579
  dragAt(
509
580
  app: activeApp,
@@ -517,7 +588,12 @@ extension RunnerTests {
517
588
  if let response = unsupportedResponse(for: outcome) {
518
589
  return response
519
590
  }
520
- return gestureResponse(message: "dragged", timing: timing, frame: .drag(dragFrame))
591
+ return gestureResponse(
592
+ message: "dragged",
593
+ timing: timing,
594
+ frame: .drag(dragFrame),
595
+ fallback: fallback
596
+ )
521
597
  case .dragSeries:
522
598
  guard let x = command.x, let y = command.y, let x2 = command.x2, let y2 = command.y2 else {
523
599
  return Response(ok: false, error: ErrorPayload(message: "dragSeries requires x, y, x2, and y2"))
@@ -528,41 +604,56 @@ extension RunnerTests {
528
604
  if pattern != "one-way" && pattern != "ping-pong" {
529
605
  return Response(ok: false, error: ErrorPayload(message: "dragSeries pattern must be one-way or ping-pong"))
530
606
  }
531
- let holdDuration = min(max((command.durationMs ?? 60) / 1000.0, 0.016), 10.0)
532
607
  let dragPoints = keyboardAvoidingDragPoints(app: activeApp, x: x, y: y, x2: x2, y2: y2)
533
- let (timing, outcome) = performGesture(activeApp) {
534
- var outcome = RunnerInteractionOutcome.performed
535
- runSeries(count: count, pauseMs: pauseMs) { idx in
536
- guard case .performed = outcome else {
537
- return
538
- }
539
- let reverse = pattern == "ping-pong" && (idx % 2 == 1)
540
- if reverse {
541
- outcome = dragAt(
608
+ var fallback: GestureFallback?
609
+ if command.synthesized == true {
610
+ let durationMs = min(max(command.durationMs ?? 250, 16), 10000)
611
+ let (timing, outcome) = performGesture(activeApp, idleTimeout: false) {
612
+ performDragSeries(
613
+ count: count,
614
+ pauseMs: pauseMs,
615
+ pattern: pattern,
616
+ points: dragPoints
617
+ ) { startX, startY, endX, endY in
618
+ synthesizedDragAt(
542
619
  app: activeApp,
543
- x: dragPoints.x2,
544
- y: dragPoints.y2,
545
- x2: dragPoints.x,
546
- y2: dragPoints.y,
547
- holdDuration: holdDuration
548
- )
549
- } else {
550
- outcome = dragAt(
551
- app: activeApp,
552
- x: dragPoints.x,
553
- y: dragPoints.y,
554
- x2: dragPoints.x2,
555
- y2: dragPoints.y2,
556
- holdDuration: holdDuration
620
+ x: startX,
621
+ y: startY,
622
+ x2: endX,
623
+ y2: endY,
624
+ durationMs: durationMs
557
625
  )
558
626
  }
559
627
  }
560
- return outcome
628
+ if case .performed = outcome {
629
+ return gestureResponse(message: "drag series", timing: timing)
630
+ }
631
+ fallback = gestureFallback(strategy: "xctest-coordinate-drag-series", from: outcome)
632
+ }
633
+ let holdDuration = command.synthesized == true
634
+ ? synthesizedSwipeFallbackHoldDuration(durationMs: command.durationMs ?? 250)
635
+ : min(max((command.durationMs ?? 60) / 1000.0, 0.016), 10.0)
636
+ let (timing, outcome) = performGesture(activeApp) {
637
+ performDragSeries(
638
+ count: count,
639
+ pauseMs: pauseMs,
640
+ pattern: pattern,
641
+ points: dragPoints
642
+ ) { startX, startY, endX, endY in
643
+ dragAt(
644
+ app: activeApp,
645
+ x: startX,
646
+ y: startY,
647
+ x2: endX,
648
+ y2: endY,
649
+ holdDuration: holdDuration
650
+ )
651
+ }
561
652
  }
562
653
  if let response = unsupportedResponse(for: outcome) {
563
654
  return response
564
655
  }
565
- return gestureResponse(message: "drag series", timing: timing)
656
+ return gestureResponse(message: "drag series", timing: timing, fallback: fallback)
566
657
  case .remotePress:
567
658
  guard let button = tvRemoteButton(from: command.remoteButton) else {
568
659
  return Response(ok: false, error: ErrorPayload(message: "remotePress requires remoteButton"))
@@ -634,6 +634,42 @@ extension RunnerTests {
634
634
  return performCoordinateDrag(app: app, x: x, y: y, x2: x2, y2: y2, holdDuration: holdDuration)
635
635
  }
636
636
 
637
+ func synthesizedDragAt(
638
+ app: XCUIApplication,
639
+ x: Double,
640
+ y: Double,
641
+ x2: Double,
642
+ y2: Double,
643
+ durationMs: Double
644
+ ) -> RunnerInteractionOutcome {
645
+ #if os(iOS)
646
+ if let message = RunnerSynthesizedGesture.synthesizeSwipe(
647
+ withApplication: app,
648
+ x: x,
649
+ y: y,
650
+ x2: x2,
651
+ y2: y2,
652
+ durationMs: durationMs
653
+ ) {
654
+ return .unsupported(
655
+ message: message,
656
+ hint: "Falling back to XCTest coordinate drag may be slower; update Xcode if this persists."
657
+ )
658
+ }
659
+ return .performed
660
+ #elseif os(tvOS)
661
+ return .unsupported(
662
+ message: "coordinate drag is not supported on tvOS",
663
+ hint: "tvOS has no coordinate input; use remote-driven swipe/scroll to move focus instead."
664
+ )
665
+ #else
666
+ return .unsupported(
667
+ message: "coordinate drag is not supported on macOS",
668
+ hint: "macOS automation has no touchscreen; use mouse-driven interactions instead."
669
+ )
670
+ #endif
671
+ }
672
+
637
673
  func keyboardAvoidingDragPoints(
638
674
  app: XCUIApplication,
639
675
  x: Double,
@@ -147,6 +147,7 @@ struct Command: Codable {
147
147
  let scope: String?
148
148
  let raw: Bool?
149
149
  let fullscreen: Bool?
150
+ let synthesized: Bool?
150
151
  }
151
152
 
152
153
  struct Response: Codable {
@@ -189,6 +190,9 @@ struct DataPayload: Codable {
189
190
  let wasVisible: Bool?
190
191
  let dismissed: Bool?
191
192
  let orientation: String?
193
+ let gestureFallback: String?
194
+ let gestureFallbackMessage: String?
195
+ let gestureFallbackHint: String?
192
196
 
193
197
  init(
194
198
  message: String? = nil,
@@ -217,7 +221,10 @@ struct DataPayload: Codable {
217
221
  visible: Bool? = nil,
218
222
  wasVisible: Bool? = nil,
219
223
  dismissed: Bool? = nil,
220
- orientation: String? = nil
224
+ orientation: String? = nil,
225
+ gestureFallback: String? = nil,
226
+ gestureFallbackMessage: String? = nil,
227
+ gestureFallbackHint: String? = nil
221
228
  ) {
222
229
  self.message = message
223
230
  self.text = text
@@ -246,6 +253,9 @@ struct DataPayload: Codable {
246
253
  self.wasVisible = wasVisible
247
254
  self.dismissed = dismissed
248
255
  self.orientation = orientation
256
+ self.gestureFallback = gestureFallback
257
+ self.gestureFallbackMessage = gestureFallbackMessage
258
+ self.gestureFallbackHint = gestureFallbackHint
249
259
  }
250
260
  }
251
261
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-device",
3
- "version": "0.16.10",
3
+ "version": "0.16.12",
4
4
  "description": "Agent-native CLI for AI mobile testing and app automation across iOS, Android, tvOS, Android TV, macOS, and Linux.",
5
5
  "mcpName": "io.github.callstackincubator/agent-device",
6
6
  "license": "MIT",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/callstackincubator/agent-device",
8
8
  "source": "github"
9
9
  },
10
- "version": "0.16.10",
10
+ "version": "0.16.12",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "agent-device",
15
- "version": "0.16.10",
15
+ "version": "0.16.12",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }
@@ -22,6 +22,6 @@ Read current CLI guidance:
22
22
  agent-device help dogfood
23
23
  ```
24
24
 
25
- Loop: open named session -> snapshot -i + screenshot -> explore flows -> capture evidence per issue -> close.
25
+ Loop: open app -> snapshot -i + screenshot -> explore flows -> capture evidence per issue -> close.
26
26
 
27
27
  Target app is required; infer platform or ask. Findings must come from runtime behavior, not source reads. Let `help dogfood` provide exact report shape, evidence commands, and current workflow guidance.
@@ -1 +0,0 @@
1
- c105a80a1cf81311718d2043e44a0176013e369b8a67ae16ad26c3c9085dd17a agent-device-android-multitouch-helper-0.16.10.apk
@@ -1 +0,0 @@
1
- ee874e75b05245f601bea045d906536f13a1268c945f1fb80baaf798e9f26a07 agent-device-android-snapshot-helper-0.16.10.apk
package/dist/src/2842.js DELETED
@@ -1 +0,0 @@
1
- function e(e){let l=`${e??""}`.toLowerCase();return l.includes("scroll")||l.includes("recyclerview")||l.includes("listview")||l.includes("gridview")||l.includes("collectionview")||"table"===l}function l(l){return!!e(l.type)||`${l.role??""} ${l.subrole??""}`.toLowerCase().includes("scroll")}export{l as isScrollableNodeLike,e as isScrollableType};
package/dist/src/8114.js DELETED
@@ -1,4 +0,0 @@
1
- import e from"node:path";import t from"node:crypto";import n from"node:fs";import{resolveUserPath as r,expandUserHomePath as o}from"./3267.js";import{findProjectRoot as s}from"./9671.js";function i(e,t){let n=[],r=e+t.toString(),o=r.indexOf("\n");for(;-1!==o;){let e=r.slice(0,o).trim();r=r.slice(o+1),e&&n.push(e),o=r.indexOf("\n")}return{lines:n,buffer:r}}function a(t){let n,s=(n=(t??"").trim())?r(n):e.join(o("~"),".agent-device");return{baseDir:s,infoPath:e.join(s,"daemon.json"),lockPath:e.join(s,"daemon.lock"),logPath:e.join(s,"daemon.log"),sessionsDir:e.join(s,"sessions")}}function l(e){let t=(e??"").trim().toLowerCase();return"http"===t?"http":"dual"===t?"dual":"socket"}function u(e){let t=(e??"").trim().toLowerCase();return"auto"===t?"auto":"socket"===t?"socket":"http"===t?"http":"auto"}function p(e){return"tenant"===(e??"").trim().toLowerCase()?"tenant":"none"}function f(e){if(!e)return;let t=e.trim();if(t&&/^[a-zA-Z0-9._-]{1,128}$/.test(t))return t}let m=/(?:^|[^\w$.])(?:import|export)\s+(?:type\s+)?(?:[^'"`]*?\s+from\s+)?['"]([^'"]+)['"]/gm,c=/import\(\s*['"]([^'"]+)['"]\s*\)/gm,d=[".ts",".tsx",".js",".jsx",".mjs",".cjs"];function $(){let e=process.argv[1];return e?g(e):"unknown"}function g(r,o=s()){try{let s=e.resolve(o),i=[e.resolve(r)],a=new Set,l=[];for(;i.length>0;){let t=i.pop();if(!t||a.has(t))continue;a.add(t);let r=n.statSync(t);if(!r.isFile())continue;let o=e.relative(s,t)||t;l.push(`${o}:${r.size}:${Math.trunc(r.mtimeMs)}`);let u=n.readFileSync(t,"utf8");for(let n of function(e){let t=new Set;return h(e,m,t),h(e,c,t),[...t]}(u)){let r=function(t,n){let r=e.resolve(e.dirname(t),n),o=y(r);if(o)return o;for(let e of d){let t=y(`${r}${e}`);if(t)return t}for(let t of d){let n=y(e.join(r,`index${t}`));if(n)return n}return null}(t,n);r&&i.push(r)}}let u=l.sort().join("|"),p=t.createHash("sha1").update(u).digest("hex");return`graph:${l.length}:${p}`}catch{return"unknown"}}function h(e,t,n){t.lastIndex=0;let r=null;for(;null!==(r=t.exec(e));){let e=r[1]?.trim();e?.startsWith(".")&&n.add(e)}}function y(e){try{return n.statSync(e).isFile()?e:null}catch{return null}}function v(e){return e.meta?.requestProgress==="replay-test"}function S(e){return!!e&&"object"==typeof e&&"progress"===e.type&&!!e.event}function x(e){return!!e&&"object"==typeof e&&"response"===e.type&&!!e.response}function j(e){return`${JSON.stringify({type:"progress",event:e})}
2
- `}function P(e){return`${JSON.stringify({type:"response",response:e})}
3
- `}function D(e){return`${JSON.stringify({type:"response",response:e})}
4
- `}function _(t){var n,r,o;let s,i,a;if("replay-test"!==t.type)return;let l=(n=t,(s=n.title?.trim())?JSON.stringify(s):e.basename(n.file)),u=void 0!==t.durationMs?` (${a=(i=Math.max(0,(r=t).durationMs??0)/1e3)>=10?`${i.toFixed(1)}s`:i>=1?`${i.toFixed(2)}s`:`${i.toFixed(3).replace(/0+$/,"").replace(/\.$/,"")}s`,r.attempt&&r.attempt>1&&!r.retrying?`total ${a}`:a})`:"",p=void 0===(o=t).attempt?"":"fail"===o.status&&o.retrying&&void 0!==o.maxAttempts?` attempt ${o.attempt}/${o.maxAttempts} retrying`:o.attempt>1?` after ${o.attempt} attempts`:"",f=t.message?.replace(/\s+/g," ").trim();return"pass"===t.status?`PASS ${l}${p}${u}`:"skip"===t.status?[`SKIP ${l}`,f?` ${f}`:""].filter(Boolean).join("\n"):[`FAIL ${l}${p}${u}`,f?` ${f}`:"",t.artifactsDir?` artifacts: ${t.artifactsDir}`:""].filter(Boolean).join("\n")}export{g as computeDaemonCodeSignature,i as consumeTextLines,_ as formatRequestProgressEvent,S as isDaemonProgressEnvelope,x as isDaemonResponseEnvelope,f as normalizeTenantId,$ as resolveDaemonCodeSignature,a as resolveDaemonPaths,l as resolveDaemonServerMode,u as resolveDaemonTransportPreference,p as resolveSessionIsolationMode,j as serializeDaemonProgressEnvelope,P as serializeDaemonResponseEnvelope,D as serializeDaemonRpcResponseEnvelope,v as shouldStreamRequestProgress};