mobile-debug-mcp 0.31.0 → 0.32.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (66) hide show
  1. package/dist/interact/android.js +13 -8
  2. package/dist/interact/index.js +33 -22
  3. package/dist/interact/ios.js +5 -2
  4. package/dist/manage/android.js +20 -10
  5. package/dist/manage/ios.js +19 -10
  6. package/dist/observe/android.js +6 -1
  7. package/dist/observe/index.js +22 -5
  8. package/dist/observe/ios.js +7 -2
  9. package/dist/observe/snapshot-metadata.js +94 -15
  10. package/dist/server/common.js +14 -7
  11. package/dist/server/journey-schema.js +60 -0
  12. package/dist/server/tool-definitions.js +59 -6
  13. package/dist/server/tool-handlers.js +358 -55
  14. package/dist/server-core.js +1 -1
  15. package/dist/utils/exec.js +4 -2
  16. package/dist/utils/ios/utils.js +5 -2
  17. package/dist/utils/operation-budget.js +25 -0
  18. package/dist/utils/resolve-device.js +12 -1
  19. package/dist/utils/timing.js +19 -0
  20. package/dist/utils/ui/index.js +2 -0
  21. package/docs/CHANGELOG.md +3 -0
  22. package/docs/benchmarks/interaction-latency/README.md +26 -0
  23. package/docs/benchmarks/interaction-latency/final.json +1810 -0
  24. package/docs/benchmarks/interaction-latency/final.md +17 -0
  25. package/docs/benchmarks/interaction-latency/ios-validation.md +11 -0
  26. package/docs/specs-deltas/018-interaction-latency-and-batched-journeys.md +301 -0
  27. package/docs/tools/interact.md +30 -0
  28. package/package.json +1 -1
  29. package/src/interact/android.ts +13 -8
  30. package/src/interact/index.ts +32 -23
  31. package/src/interact/ios.ts +5 -2
  32. package/src/manage/android.ts +19 -10
  33. package/src/manage/ios.ts +18 -10
  34. package/src/observe/android.ts +5 -1
  35. package/src/observe/index.ts +21 -5
  36. package/src/observe/ios.ts +6 -2
  37. package/src/observe/snapshot-metadata.ts +94 -15
  38. package/src/server/common.ts +13 -6
  39. package/src/server/journey-schema.ts +63 -0
  40. package/src/server/tool-definitions.ts +60 -7
  41. package/src/server/tool-handlers.ts +324 -53
  42. package/src/server-core.ts +1 -1
  43. package/src/types.ts +31 -2
  44. package/src/utils/exec.ts +4 -2
  45. package/src/utils/ios/utils.ts +5 -2
  46. package/src/utils/operation-budget.ts +22 -0
  47. package/src/utils/resolve-device.ts +13 -1
  48. package/src/utils/timing.ts +15 -0
  49. package/src/utils/ui/index.ts +2 -0
  50. package/test/device/automated/latency/benchmark.ts +136 -0
  51. package/test/device/automated/latency/report.ts +6 -0
  52. package/test/fixtures/latency-journey-app/AndroidManifest.xml +6 -0
  53. package/test/fixtures/latency-journey-app/README.md +10 -0
  54. package/test/fixtures/latency-journey-app/build.ts +26 -0
  55. package/test/fixtures/latency-journey-app/src/MainActivity.java +48 -0
  56. package/test/unit/manage/restart_budget.test.ts +37 -0
  57. package/test/unit/observe/capture_debug_snapshot.test.ts +6 -0
  58. package/test/unit/observe/snapshot_metadata.test.ts +20 -1
  59. package/test/unit/observe/state_delta.test.ts +15 -0
  60. package/test/unit/server/benchmark_report.test.ts +4 -0
  61. package/test/unit/server/contract.test.ts +1 -1
  62. package/test/unit/server/interaction_modes.test.ts +60 -0
  63. package/test/unit/server/operation_budget.test.ts +32 -0
  64. package/test/unit/server/response_shapes.test.ts +3 -3
  65. package/test/unit/server/run_journey.test.ts +90 -0
  66. package/test/unit/server/tap_selector.test.ts +68 -0
@@ -1,4 +1,6 @@
1
- export const toolDefinitions = [
1
+ import { journeyStepsJson } from './journey-schema.js'
2
+
3
+ export const toolDefinitions: any[] = [
2
4
  {
3
5
  name: 'start_app',
4
6
  description: `Purpose:
@@ -47,7 +49,11 @@ Failure Handling:
47
49
  deviceId: {
48
50
  type: 'string',
49
51
  description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.'
50
- }
52
+ },
53
+ verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
54
+ responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
55
+ actionTimeoutMs: { type: 'number', minimum: 100, maximum: 30000 },
56
+ verificationTimeoutMs: { type: 'number', minimum: 100, maximum: 60000 }
51
57
  },
52
58
  required: ['platform', 'appId']
53
59
  }
@@ -250,6 +256,7 @@ Failure Handling:
250
256
  properties: {
251
257
  reason: { type: 'string', description: 'Optional reason for snapshot' },
252
258
  includeLogs: { type: 'boolean', description: 'Whether to include logs', default: true },
259
+ includeScreenshot: { type: 'boolean', description: 'Whether to collect screenshot bytes', default: true },
253
260
  logLines: { type: 'number', description: 'Maximum number of log lines to include', default: 200 },
254
261
  platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
255
262
  appId: { type: 'string', description: 'Optional appId to scope logs (package/bundle id)' },
@@ -307,7 +314,9 @@ Failure Handling:
307
314
  deviceId: {
308
315
  type: 'string',
309
316
  description: 'Device Serial (Android) or UDID (iOS). Defaults to connected/booted device.'
310
- }
317
+ },
318
+ responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
319
+ sinceSnapshotRevision: { type: 'number', minimum: 1 }
311
320
  },
312
321
  required: ['platform']
313
322
  }
@@ -729,7 +738,11 @@ Failure Handling:
729
738
  deviceId: {
730
739
  type: 'string',
731
740
  description: 'Device Serial/UDID. Defaults to connected/booted device.'
732
- }
741
+ },
742
+ verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
743
+ responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
744
+ actionTimeoutMs: { type: 'number', minimum: 100, maximum: 30000 },
745
+ verificationTimeoutMs: { type: 'number', minimum: 100, maximum: 60000 }
733
746
  },
734
747
  required: ['x', 'y']
735
748
  }
@@ -783,9 +796,14 @@ This tool reports execution success only. Verification must be done with a separ
783
796
  elementId: {
784
797
  type: 'string',
785
798
  description: 'A unique element identifier returned by wait_for_ui'
786
- }
787
- },
788
- required: ['elementId']
799
+ },
800
+ selector: { type: 'object', properties: { text: { type: 'string' }, resource_id: { type: 'string' }, accessibility_id: { type: 'string' }, contains: { type: 'boolean' } } },
801
+ waitFor: { type: 'object', properties: { condition: { type: 'string', enum: ['exists', 'visible', 'clickable'] }, timeoutMs: { type: 'number', minimum: 100, maximum: 10000 }, pollIntervalMs: { type: 'number', minimum: 50, maximum: 1000 }, match: { type: 'object', properties: { index: { type: 'number' } } } } },
802
+ platform: { type: 'string', enum: ['android', 'ios'] },
803
+ deviceId: { type: 'string' },
804
+ verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
805
+ responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' }
806
+ }
789
807
  }
790
808
  },
791
809
  {
@@ -1062,6 +1080,20 @@ BEHAVIOUR after outcome:
1062
1080
  required: ['uiChanged']
1063
1081
  }
1064
1082
  },
1083
+ {
1084
+ name: 'run_journey',
1085
+ description: 'Run an ordered, bounded sequence of start_app, tap, wait, and deterministic assertion steps against one device. Stops after the first failed step.',
1086
+ inputSchema: {
1087
+ type: 'object',
1088
+ properties: {
1089
+ platform: { type: 'string', enum: ['android', 'ios'] },
1090
+ deviceId: { type: 'string' },
1091
+ responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'compact' },
1092
+ steps: { type: 'array', minItems: 1, maxItems: 50, items: { type: 'object', properties: { id: { type: 'string' }, type: { type: 'string', enum: ['start_app', 'tap', 'wait', 'assert'] } }, required: ['id', 'type'] } }
1093
+ },
1094
+ required: ['platform', 'steps']
1095
+ }
1096
+ },
1065
1097
  {
1066
1098
  name: 'get_network_activity',
1067
1099
  description: `Returns structured network events captured from platform logs since the last action.
@@ -1095,3 +1127,24 @@ Returns { requests: [], count: 0 } when no credible network signals are found.`,
1095
1127
  }
1096
1128
  }
1097
1129
  ]
1130
+
1131
+ // Keep the additive execution controls consistent across all action tools.
1132
+ for (const tool of toolDefinitions) {
1133
+ if (['start_app', 'restart_app', 'tap', 'tap_element', 'swipe', 'scroll_to_element', 'type_text', 'press_back'].includes(tool.name)) {
1134
+ Object.assign(tool.inputSchema.properties, {
1135
+ verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
1136
+ responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
1137
+ actionTimeoutMs: { type: 'integer', description: 'Dispatch budget in milliseconds, clamped to 100–30000.' },
1138
+ verificationTimeoutMs: { type: 'integer', description: 'Light observation budget in milliseconds, clamped to 100–60000.' }
1139
+ })
1140
+ }
1141
+ if (tool.name === 'tap_element') Object.assign(tool.inputSchema, { oneOf: [{ required: ['elementId'], not: { required: ['selector'] } }, { required: ['selector'], not: { required: ['elementId'] } }] })
1142
+ if (tool.name === 'run_journey') Object.assign(tool.inputSchema.properties, {
1143
+ steps: journeyStepsJson,
1144
+ captureOnFailure: { type: 'boolean', default: false },
1145
+ defaults: { type: 'object', additionalProperties: false, properties: {
1146
+ verificationMode: { type: 'string', enum: ['none', 'light', 'full'] },
1147
+ actionTimeoutMs: { type: 'integer' }, verificationTimeoutMs: { type: 'integer' }
1148
+ } }
1149
+ })
1150
+ }