mobile-debug-mcp 0.34.0 → 0.36.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 (500) hide show
  1. package/.agents/skills/mcp-builder/SKILL.md +44 -64
  2. package/.agents/skills/mcp-builder/references/build-flags.md +44 -43
  3. package/.agents/skills/mcp-builder/references/diagnostics-schema.md +4 -1
  4. package/.agents/skills/mcp-builder/references/toolchain-details.md +49 -62
  5. package/.agents/skills/spec-review/references/spec-review-checklist.md +7 -0
  6. package/.agents/skills/test-authoring/SKILL.md +7 -6
  7. package/.agents/skills/test-authoring/references/repo-test-layout.md +3 -1
  8. package/.agents/skills/test-authoring/references/test-authoring-workflow.md +16 -7
  9. package/.agents/skills/test-authoring/references/test-quality-checklist.md +2 -1
  10. package/.cursor-plugin/marketplace.json +1 -1
  11. package/.github/copilot-instructions.md +14 -36
  12. package/.github/workflows/ci.yml +4 -4
  13. package/AGENTS.md +12 -3
  14. package/CONTRIBUTING.md +79 -0
  15. package/README.md +218 -129
  16. package/agent-plugin/.antigravity-plugin/README.md +48 -0
  17. package/agent-plugin/.antigravity-plugin/plugin.json +18 -0
  18. package/agent-plugin/.claude-plugin/plugin.json +2 -2
  19. package/agent-plugin/.codex-plugin/plugin.json +1 -1
  20. package/agent-plugin/.cursor-plugin/plugin.json +2 -2
  21. package/agent-plugin/.mcp.json +1 -1
  22. package/agent-plugin/README.md +50 -11
  23. package/agent-plugin/cursor/.cursor-plugin/plugin.json +23 -0
  24. package/agent-plugin/cursor/LICENSE +201 -0
  25. package/agent-plugin/cursor/README.md +9 -0
  26. package/agent-plugin/cursor/skills/mobile-debug-mcp/SKILL.md +253 -0
  27. package/agent-plugin/mcp.json +1 -1
  28. package/agent-plugin/mcp_config.json +13 -0
  29. package/agent-plugin/plugin.json +1 -1
  30. package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +62 -17
  31. package/dist/contracts/execution-controls.js +24 -0
  32. package/dist/contracts/selector.js +8 -0
  33. package/dist/contracts/target.js +15 -0
  34. package/dist/contracts/ui.js +1 -0
  35. package/dist/debugger/android.js +2 -1
  36. package/dist/debugger/diagnostics.js +54 -0
  37. package/dist/debugger/guard.js +4 -4
  38. package/dist/debugger/ios-worker.js +62 -0
  39. package/dist/debugger/ios.js +57 -0
  40. package/dist/debugger/protocol.js +33 -0
  41. package/dist/debugger/sessions.js +133 -74
  42. package/dist/debugger/worker.js +59 -46
  43. package/dist/interact/adjustment/adjustment-context.js +41 -0
  44. package/dist/interact/adjustment/adjustment-gestures.js +55 -0
  45. package/dist/interact/adjustment/adjustment-plan.js +18 -0
  46. package/dist/interact/adjustment/adjustment-resolution.js +127 -0
  47. package/dist/interact/adjustment/adjustment-result.js +19 -0
  48. package/dist/interact/adjustment/adjustment-semantic.js +64 -0
  49. package/dist/interact/adjustment/adjustment-verification.js +35 -0
  50. package/dist/interact/adjustment/adjustment.js +52 -0
  51. package/dist/interact/adjustment/control-geometry.js +87 -0
  52. package/dist/interact/adjustment/control-values.js +136 -0
  53. package/dist/interact/adjustment/slider-labels.js +84 -0
  54. package/dist/interact/assertions/screen-assertion.js +37 -0
  55. package/dist/interact/assertions/state-assertion-context.js +35 -0
  56. package/dist/interact/assertions/state-assertion.js +76 -0
  57. package/dist/interact/assertions/state-comparison.js +141 -0
  58. package/dist/interact/assertions/visibility-assertion.js +34 -0
  59. package/dist/interact/conditional-action.js +12 -7
  60. package/dist/interact/index.js +77 -3092
  61. package/dist/interact/input-service.js +1 -0
  62. package/dist/interact/interaction-trace.js +21 -0
  63. package/dist/interact/model.js +1 -0
  64. package/dist/interact/observation.js +1 -0
  65. package/dist/interact/targeting/candidate-ancestor.js +58 -0
  66. package/dist/interact/targeting/candidate-result.js +23 -0
  67. package/dist/interact/targeting/candidate-scoring.js +50 -0
  68. package/dist/interact/targeting/element-helpers.js +216 -0
  69. package/dist/interact/targeting/find-element.js +65 -0
  70. package/dist/interact/targeting/nearby-control.js +56 -0
  71. package/dist/interact/targeting/resolved-elements.js +21 -0
  72. package/dist/interact/targeting/tap-target.js +17 -0
  73. package/dist/interact/targeting/target-scope.js +104 -0
  74. package/dist/interact/waits/legacy-log-wait.js +38 -0
  75. package/dist/interact/waits/legacy-wait-observations.js +103 -0
  76. package/dist/interact/waits/legacy-wait-state.js +34 -0
  77. package/dist/interact/waits/legacy-wait.js +48 -0
  78. package/dist/interact/waits/screen-wait.js +49 -0
  79. package/dist/interact/waits/ui-change-helpers.js +157 -0
  80. package/dist/interact/waits/ui-change-state.js +18 -0
  81. package/dist/interact/waits/ui-change-wait.js +77 -0
  82. package/dist/interact/waits/ui-wait-condition.js +56 -0
  83. package/dist/interact/waits/ui-wait-state.js +38 -0
  84. package/dist/interact/waits/ui-wait.js +106 -0
  85. package/dist/manage/android.js +55 -51
  86. package/dist/manage/index.js +38 -75
  87. package/dist/manage/ios/build-types.js +1 -0
  88. package/dist/manage/ios/build.js +210 -0
  89. package/dist/manage/ios/project-discovery.js +29 -0
  90. package/dist/manage/ios/scheme.js +18 -0
  91. package/dist/manage/ios.js +44 -256
  92. package/dist/observe/android/context.js +1 -0
  93. package/dist/observe/android/current-screen.js +55 -0
  94. package/dist/observe/android/fingerprint.js +13 -0
  95. package/dist/observe/android/log-stream.js +132 -0
  96. package/dist/observe/android/logs.js +107 -0
  97. package/dist/observe/android/screenshot.js +70 -0
  98. package/dist/observe/android/ui-tree.js +107 -0
  99. package/dist/observe/android.js +16 -520
  100. package/dist/observe/evidence.js +114 -75
  101. package/dist/observe/index.js +16 -263
  102. package/dist/observe/ios/context.js +16 -0
  103. package/dist/observe/ios/fingerprint.js +12 -0
  104. package/dist/observe/ios/log-stream.js +105 -0
  105. package/dist/observe/ios/logs.js +168 -0
  106. package/dist/observe/ios/screenshot.js +22 -0
  107. package/dist/observe/ios/ui-elements.js +241 -0
  108. package/dist/observe/ios/ui-tree.js +137 -0
  109. package/dist/observe/ios-trace/artifact.js +63 -0
  110. package/dist/observe/ios-trace/capabilities.js +86 -0
  111. package/dist/observe/ios-trace/native.js +93 -0
  112. package/dist/observe/ios-trace/notification.js +35 -0
  113. package/dist/observe/ios-trace/process.js +98 -0
  114. package/dist/observe/ios-trace/sessions.js +244 -0
  115. package/dist/observe/ios.js +17 -715
  116. package/dist/observe/logs/model.js +1 -0
  117. package/dist/{network → observe/network}/index.js +2 -2
  118. package/dist/observe/readiness-service.js +5 -3
  119. package/dist/observe/readiness.js +33 -14
  120. package/dist/observe/screenshot-encoding.js +41 -0
  121. package/dist/observe/snapshot-collection.js +79 -0
  122. package/dist/observe/snapshot-logs.js +30 -0
  123. package/dist/observe/snapshot-metadata.js +43 -31
  124. package/dist/observe/snapshot-semantic.js +115 -0
  125. package/dist/observe/system-trace-error.js +7 -0
  126. package/dist/observe/system-trace-router.js +81 -0
  127. package/dist/observe/system-trace.js +26 -21
  128. package/dist/runtime/action-results.js +270 -0
  129. package/dist/runtime/clock.js +4 -0
  130. package/dist/server/common.js +1 -256
  131. package/dist/server/definitions/assert.js +162 -0
  132. package/dist/server/definitions/diagnostic.js +118 -0
  133. package/dist/server/definitions/input.js +274 -0
  134. package/dist/server/definitions/manage.js +194 -0
  135. package/dist/server/definitions/observe.js +149 -0
  136. package/dist/server/definitions/target.js +138 -0
  137. package/dist/server/definitions/wait.js +105 -0
  138. package/dist/server/handlers/action-execution.js +163 -0
  139. package/dist/server/handlers/correlation.js +23 -0
  140. package/dist/server/handlers/debugger-handlers.js +67 -0
  141. package/dist/server/handlers/debugger-response.js +9 -0
  142. package/dist/server/handlers/diagnostic.js +77 -0
  143. package/dist/server/handlers/handler-types.js +1 -0
  144. package/dist/server/handlers/input.js +154 -0
  145. package/dist/server/handlers/interact.js +113 -0
  146. package/dist/server/handlers/journey-assertions.js +35 -0
  147. package/dist/server/handlers/journey.js +147 -0
  148. package/dist/server/handlers/manage.js +119 -0
  149. package/dist/server/handlers/observe.js +95 -0
  150. package/dist/server/handlers/payload.js +4 -0
  151. package/dist/server/handlers/tool-handlers.js +170 -0
  152. package/dist/server/schemas/condition-schema.js +2 -0
  153. package/dist/server/{debugger-schema.js → schemas/debugger-schema.js} +20 -12
  154. package/dist/server/{journey-schema.js → schemas/journey-schema.js} +7 -22
  155. package/dist/server/schemas/system-trace-schema.js +22 -0
  156. package/dist/server/tool-definitions.js +58 -1135
  157. package/dist/server-core.js +2 -2
  158. package/dist/server.js +4 -4
  159. package/dist/system/android-status.js +101 -0
  160. package/dist/system/android.js +37 -27
  161. package/dist/system/index.js +13 -439
  162. package/dist/system/ios-status.js +132 -0
  163. package/dist/system/ios.js +11 -8
  164. package/dist/system/model.js +1 -0
  165. package/dist/system/probes.js +105 -0
  166. package/dist/system/status-summary.js +43 -0
  167. package/dist/system/unsupported-status.js +52 -0
  168. package/dist/utils/android/commands.js +89 -0
  169. package/dist/utils/android/gradle.js +139 -0
  170. package/dist/utils/android/logs.js +103 -0
  171. package/dist/utils/android/ui-tree.js +233 -0
  172. package/dist/utils/android/utils.js +6 -564
  173. package/dist/utils/cli/idb/idb-helper.js +4 -6
  174. package/dist/utils/cli/idb/install-idb.js +13 -9
  175. package/dist/utils/cli/ios/preflight-ios.js +42 -38
  176. package/dist/utils/ios/utils.js +48 -46
  177. package/dist/utils/java.js +65 -49
  178. package/dist/utils/resolve-device.js +4 -2
  179. package/dist/utils/ui/index.js +26 -26
  180. package/docs/CHANGELOG.md +67 -1
  181. package/docs/README.md +38 -0
  182. package/docs/agent-plugin-installation-verification.md +39 -0
  183. package/docs/benchmarks/README.md +18 -0
  184. package/docs/benchmarks/interaction-latency/README.md +14 -0
  185. package/docs/benchmarks/interaction-latency/final.md +4 -1
  186. package/docs/benchmarks/interaction-latency/ios-validation.md +2 -0
  187. package/docs/benchmarks/ui-tree-performance/README.md +24 -16
  188. package/docs/benchmarks/ui-tree-performance/comparison.md +11 -10
  189. package/docs/code-structure.md +120 -0
  190. package/docs/specs/001-state-verification/spec.md +16 -14
  191. package/docs/specs/002-richer-element-identity/spec.md +12 -10
  192. package/docs/specs/003-wait-and-synchronization-reliability/spec.md +12 -10
  193. package/docs/specs/004-action-verification-routing/spec.md +3 -3
  194. package/docs/specs/005-unified-action-execution-and-verification-model/spec.md +2 -0
  195. package/docs/specs/006-runtime-action-instrumentation-and-binding-layer/spec.md +2 -0
  196. package/docs/specs/007-actionability-resolution-and-executable-target-selection/spec.md +3 -1
  197. package/docs/specs/008-adjustable-control-support-and-semantic-value-manipulation/spec.md +3 -4
  198. package/docs/specs/009-semantic-control-modeling-for-custom-and-composite-controls/spec.md +2 -0
  199. package/docs/specs/010-verification-stabilization-and-temporal-convergence/spec.md +2 -2
  200. package/docs/specs/011-recovery-and-replanning-for-failed-or-ambiguous-interaction-flows/spec.md +2 -2
  201. package/docs/specs/011.1-recovery-contract-types-and-runtime-wiring-spec/spec.md +2 -0
  202. package/docs/specs/012-action-trace-and-xecution-observability/spec.md +2 -3
  203. package/docs/specs/013-wait-and-synchronization-reliability/spec.md +19 -19
  204. package/docs/specs/014-actionability-resolution/spec.md +20 -18
  205. package/docs/specs/015-adjustable-control-support/spec.md +17 -15
  206. package/docs/specs/016-environment-tools/spec.md +20 -20
  207. package/docs/specs/018-interaction-latency-and-batched-journeys/spec.md +2 -0
  208. package/docs/specs/019-ui-tree-observation-performance/spec.md +3 -1
  209. package/docs/specs/020-conditional-actions/intent.md +5 -3
  210. package/docs/specs/020-conditional-actions/plan.md +8 -9
  211. package/docs/specs/020-conditional-actions/spec.md +4 -2
  212. package/docs/specs/021-app-readiness-signals/intent.md +4 -2
  213. package/docs/specs/021-app-readiness-signals/plan.md +7 -6
  214. package/docs/specs/021-app-readiness-signals/spec.md +3 -1
  215. package/docs/specs/022-correlated-evidence/intent.md +4 -4
  216. package/docs/specs/022-correlated-evidence/plan.md +10 -11
  217. package/docs/specs/022-correlated-evidence/spec.md +3 -1
  218. package/docs/specs/023-android-system-traces/intent.md +3 -2
  219. package/docs/specs/023-android-system-traces/plan.md +5 -7
  220. package/docs/specs/023-android-system-traces/spec.md +3 -1
  221. package/docs/specs/024-android-heap-dump-capture/intent.md +3 -1
  222. package/docs/specs/025-android-runtime-debugger/intent.md +4 -3
  223. package/docs/specs/025-android-runtime-debugger/plan.md +3 -1
  224. package/docs/specs/025-android-runtime-debugger/spec.md +4 -3
  225. package/docs/specs/026-code-structure-and-quality-gates/health-plan.md +88 -0
  226. package/docs/specs/026-code-structure-and-quality-gates/intent.md +47 -0
  227. package/docs/specs/026-code-structure-and-quality-gates/plan.md +191 -0
  228. package/docs/specs/026-code-structure-and-quality-gates/spec.md +138 -0
  229. package/docs/specs/026-code-structure-and-quality-gates/verification-final.json +200 -0
  230. package/docs/specs/026-code-structure-and-quality-gates/verification-thin-facade.json +154 -0
  231. package/docs/specs/026-code-structure-and-quality-gates/verification.json +136 -0
  232. package/docs/specs/027-debugger-failure-diagnostics/intent.md +43 -0
  233. package/docs/specs/027-debugger-failure-diagnostics/plan.md +86 -0
  234. package/docs/specs/027-debugger-failure-diagnostics/spec.md +133 -0
  235. package/docs/specs/028-compact-debugger-responses/intent.md +41 -0
  236. package/docs/specs/028-compact-debugger-responses/plan.md +112 -0
  237. package/docs/specs/028-compact-debugger-responses/spec.md +108 -0
  238. package/docs/specs/029-kotlin-locals-validation/report.md +119 -0
  239. package/docs/specs/030-android-coroutine-validation/evidence.json +475 -0
  240. package/docs/specs/030-android-coroutine-validation/intent.md +47 -0
  241. package/docs/specs/030-android-coroutine-validation/plan.md +147 -0
  242. package/docs/specs/030-android-coroutine-validation/report.md +240 -0
  243. package/docs/specs/030-android-coroutine-validation/spec.md +107 -0
  244. package/docs/specs/031-ios-system-traces/intent.md +38 -0
  245. package/docs/specs/031-ios-system-traces/investigation.md +92 -0
  246. package/docs/specs/031-ios-system-traces/late-run-failure-evidence.json +32 -0
  247. package/docs/specs/031-ios-system-traces/plan.md +138 -0
  248. package/docs/specs/031-ios-system-traces/pr102-monitor-evidence.json +22 -0
  249. package/docs/specs/031-ios-system-traces/simulator-evidence.json +47 -0
  250. package/docs/specs/031-ios-system-traces/spec.md +135 -0
  251. package/docs/specs/032-ios-runtime-debugger/evidence.json +176 -0
  252. package/docs/specs/032-ios-runtime-debugger/intent.md +38 -0
  253. package/docs/specs/032-ios-runtime-debugger/plan.md +95 -0
  254. package/docs/specs/032-ios-runtime-debugger/report.md +205 -0
  255. package/docs/specs/032-ios-runtime-debugger/spec.md +153 -0
  256. package/docs/tools/TOOLS.md +31 -18
  257. package/docs/tools/{evidence.md → correlated-evidence.md} +9 -1
  258. package/docs/tools/debugger.md +120 -4
  259. package/docs/tools/interact.md +42 -20
  260. package/docs/tools/manage.md +25 -44
  261. package/docs/tools/observe.md +55 -23
  262. package/docs/tools/system-traces.md +89 -14
  263. package/docs/tools/system.md +12 -5
  264. package/package.json +12 -8
  265. package/scripts/agent-plugin.mjs +55 -5
  266. package/scripts/architecture-graph.mjs +69 -0
  267. package/scripts/check-architecture.mjs +47 -0
  268. package/scripts/code-quality-baseline.json +1 -0
  269. package/scripts/code-quality.mjs +161 -0
  270. package/src/contracts/execution-controls.ts +26 -0
  271. package/src/contracts/selector.ts +17 -0
  272. package/src/contracts/target.ts +19 -0
  273. package/src/contracts/ui.ts +94 -0
  274. package/src/debugger/android.ts +3 -2
  275. package/src/debugger/diagnostics.ts +43 -0
  276. package/src/debugger/guard.ts +10 -5
  277. package/src/debugger/ios-worker.ts +49 -0
  278. package/src/debugger/ios.ts +45 -0
  279. package/{worker → src/debugger/java}/DebuggerWorker.java +9 -3
  280. package/src/debugger/lldb/breakpoints.py +51 -0
  281. package/src/debugger/lldb/inspection.py +109 -0
  282. package/src/debugger/lldb/worker.py +203 -0
  283. package/src/debugger/protocol.ts +37 -0
  284. package/src/debugger/sessions.ts +326 -155
  285. package/src/debugger/worker.ts +57 -41
  286. package/src/interact/adjustment/adjustment-context.ts +83 -0
  287. package/src/interact/adjustment/adjustment-gestures.ts +48 -0
  288. package/src/interact/adjustment/adjustment-plan.ts +23 -0
  289. package/src/interact/adjustment/adjustment-resolution.ts +104 -0
  290. package/src/interact/adjustment/adjustment-result.ts +34 -0
  291. package/src/interact/adjustment/adjustment-semantic.ts +53 -0
  292. package/src/interact/adjustment/adjustment-verification.ts +60 -0
  293. package/src/interact/adjustment/adjustment.ts +49 -0
  294. package/src/interact/adjustment/control-geometry.ts +120 -0
  295. package/src/interact/adjustment/control-values.ts +141 -0
  296. package/src/interact/adjustment/slider-labels.ts +84 -0
  297. package/src/interact/assertions/screen-assertion.ts +39 -0
  298. package/src/interact/assertions/state-assertion-context.ts +48 -0
  299. package/src/interact/assertions/state-assertion.ts +64 -0
  300. package/src/interact/assertions/state-comparison.ts +168 -0
  301. package/src/interact/assertions/visibility-assertion.ts +41 -0
  302. package/src/interact/conditional-action.ts +18 -12
  303. package/src/interact/index.ts +89 -3494
  304. package/src/interact/input-service.ts +11 -0
  305. package/src/interact/interaction-trace.ts +36 -0
  306. package/src/interact/model.ts +109 -0
  307. package/src/interact/observation.ts +7 -0
  308. package/src/interact/targeting/candidate-ancestor.ts +49 -0
  309. package/src/interact/targeting/candidate-result.ts +24 -0
  310. package/src/interact/targeting/candidate-scoring.ts +42 -0
  311. package/src/interact/targeting/element-helpers.ts +243 -0
  312. package/src/interact/targeting/find-element.ts +47 -0
  313. package/src/interact/targeting/nearby-control.ts +46 -0
  314. package/src/interact/targeting/resolved-elements.ts +20 -0
  315. package/src/interact/targeting/tap-target.ts +22 -0
  316. package/src/interact/targeting/target-scope.ts +121 -0
  317. package/src/interact/waits/legacy-log-wait.ts +30 -0
  318. package/src/interact/waits/legacy-wait-observations.ts +55 -0
  319. package/src/interact/waits/legacy-wait-state.ts +48 -0
  320. package/src/interact/waits/legacy-wait.ts +34 -0
  321. package/src/interact/waits/screen-wait.ts +37 -0
  322. package/src/interact/waits/ui-change-helpers.ts +184 -0
  323. package/src/interact/waits/ui-change-state.ts +26 -0
  324. package/src/interact/waits/ui-change-wait.ts +59 -0
  325. package/src/interact/waits/ui-wait-condition.ts +52 -0
  326. package/src/interact/waits/ui-wait-state.ts +55 -0
  327. package/src/interact/waits/ui-wait.ts +84 -0
  328. package/src/manage/android.ts +56 -50
  329. package/src/manage/index.ts +63 -93
  330. package/src/manage/ios/build-types.ts +14 -0
  331. package/src/manage/ios/build.ts +230 -0
  332. package/src/manage/ios/project-discovery.ts +26 -0
  333. package/src/manage/ios/scheme.ts +16 -0
  334. package/src/manage/ios.ts +67 -298
  335. package/src/observe/android/context.ts +1 -0
  336. package/src/observe/android/current-screen.ts +63 -0
  337. package/src/observe/android/fingerprint.ts +13 -0
  338. package/src/observe/android/log-stream.ts +127 -0
  339. package/src/observe/android/logs.ts +110 -0
  340. package/src/observe/android/screenshot.ts +79 -0
  341. package/src/observe/android/ui-tree.ts +113 -0
  342. package/src/observe/android.ts +17 -531
  343. package/src/observe/evidence.ts +122 -70
  344. package/src/observe/index.ts +24 -286
  345. package/src/observe/ios/context.ts +22 -0
  346. package/src/observe/ios/fingerprint.ts +12 -0
  347. package/src/observe/ios/log-stream.ts +103 -0
  348. package/src/observe/ios/logs.ts +179 -0
  349. package/src/observe/ios/screenshot.ts +26 -0
  350. package/src/observe/ios/ui-elements.ts +266 -0
  351. package/src/observe/ios/ui-tree.ts +143 -0
  352. package/src/observe/ios-trace/artifact.ts +55 -0
  353. package/src/observe/ios-trace/capabilities.ts +74 -0
  354. package/src/observe/ios-trace/native.ts +72 -0
  355. package/src/observe/ios-trace/notification.ts +30 -0
  356. package/src/observe/ios-trace/process.ts +82 -0
  357. package/src/observe/ios-trace/sessions.ts +204 -0
  358. package/src/observe/ios.ts +18 -749
  359. package/src/observe/logs/model.ts +11 -0
  360. package/src/{network → observe/network}/index.ts +2 -2
  361. package/src/observe/readiness-service.ts +6 -4
  362. package/src/observe/readiness.ts +42 -21
  363. package/src/observe/screenshot-encoding.ts +32 -0
  364. package/src/observe/snapshot-collection.ts +69 -0
  365. package/src/observe/snapshot-logs.ts +26 -0
  366. package/src/observe/snapshot-metadata.ts +51 -31
  367. package/src/observe/snapshot-semantic.ts +153 -0
  368. package/src/observe/system-trace-error.ts +3 -0
  369. package/src/observe/system-trace-router.ts +61 -0
  370. package/src/observe/system-trace.ts +28 -19
  371. package/src/runtime/action-results.ts +376 -0
  372. package/src/runtime/clock.ts +9 -0
  373. package/src/server/common.ts +9 -359
  374. package/src/server/definitions/assert.ts +164 -0
  375. package/src/server/definitions/diagnostic.ts +120 -0
  376. package/src/server/definitions/input.ts +276 -0
  377. package/src/server/definitions/manage.ts +196 -0
  378. package/src/server/definitions/observe.ts +151 -0
  379. package/src/server/definitions/target.ts +140 -0
  380. package/src/server/definitions/wait.ts +107 -0
  381. package/src/server/handlers/action-execution.ts +164 -0
  382. package/src/server/handlers/correlation.ts +20 -0
  383. package/src/server/handlers/debugger-handlers.ts +58 -0
  384. package/src/server/handlers/debugger-response.ts +7 -0
  385. package/src/server/handlers/diagnostic.ts +86 -0
  386. package/src/server/handlers/handler-types.ts +7 -0
  387. package/src/server/handlers/input.ts +173 -0
  388. package/src/server/handlers/interact.ts +135 -0
  389. package/src/server/handlers/journey-assertions.ts +39 -0
  390. package/src/server/handlers/journey.ts +132 -0
  391. package/src/server/handlers/manage.ts +141 -0
  392. package/src/server/handlers/observe.ts +116 -0
  393. package/src/server/handlers/payload.ts +36 -0
  394. package/src/server/handlers/tool-handlers.ts +170 -0
  395. package/src/server/schemas/condition-schema.ts +2 -0
  396. package/src/server/schemas/debugger-schema.ts +46 -0
  397. package/src/server/{journey-schema.ts → schemas/journey-schema.ts} +7 -22
  398. package/src/server/schemas/system-trace-schema.ts +23 -0
  399. package/src/server/tool-definitions.ts +67 -1143
  400. package/src/server-core.ts +2 -2
  401. package/src/server.ts +4 -4
  402. package/src/system/android-status.ts +124 -0
  403. package/src/system/android.ts +33 -21
  404. package/src/system/index.ts +21 -525
  405. package/src/system/ios-status.ts +147 -0
  406. package/src/system/ios.ts +14 -10
  407. package/src/system/model.ts +41 -0
  408. package/src/system/probes.ts +114 -0
  409. package/src/system/status-summary.ts +47 -0
  410. package/src/system/unsupported-status.ts +55 -0
  411. package/src/types.ts +16 -106
  412. package/src/utils/android/commands.ts +81 -0
  413. package/src/utils/android/gradle.ts +132 -0
  414. package/src/utils/android/logs.ts +103 -0
  415. package/src/utils/android/ui-tree.ts +239 -0
  416. package/src/utils/android/utils.ts +16 -556
  417. package/src/utils/cli/idb/check-idb.ts +4 -4
  418. package/src/utils/cli/idb/idb-helper.ts +6 -8
  419. package/src/utils/cli/idb/install-idb.ts +15 -9
  420. package/src/utils/cli/ios/preflight-ios.ts +39 -31
  421. package/src/utils/cli/ios/run-ios-ui-tree-tap.ts +4 -4
  422. package/src/utils/ios/utils.ts +60 -61
  423. package/src/utils/java.ts +62 -43
  424. package/src/utils/resolve-device.ts +9 -6
  425. package/src/utils/ui/index.ts +28 -28
  426. package/test/device/automated/debugger/coroutine-lifecycle.ts +27 -0
  427. package/test/device/automated/debugger/coroutine-support.ts +140 -0
  428. package/test/device/automated/debugger/coroutine.android.test.ts +169 -0
  429. package/test/device/automated/debugger/kotlin.android.test.ts +127 -0
  430. package/test/device/automated/debugger/runtime.android.test.ts +19 -3
  431. package/test/device/automated/debugger/runtime.ios.test.ts +221 -0
  432. package/test/device/automated/interact/interaction.android.test.ts +56 -0
  433. package/test/device/automated/observe/ios-system-trace.smoke.ts +119 -0
  434. package/test/device/automated/observe/system-trace.smoke.ts +1 -1
  435. package/test/device/manual/interact/modul8_selector_tap.manual.ts +1 -1
  436. package/test/fixtures/contracts/tool-definitions.json +3696 -0
  437. package/test/fixtures/coroutine-app/MainActivity.kt +100 -0
  438. package/test/fixtures/coroutine-app/README.md +48 -0
  439. package/test/fixtures/coroutine-app/build.ts +35 -0
  440. package/test/fixtures/debugger-app/MainActivity.java +21 -0
  441. package/test/fixtures/debugger-app/MainActivity.kt +32 -0
  442. package/test/fixtures/debugger-app/README.md +52 -0
  443. package/test/fixtures/debugger-app/build.ts +25 -15
  444. package/test/fixtures/ios-debugger-app/Main.swift +95 -0
  445. package/test/fixtures/ios-debugger-app/README.md +27 -0
  446. package/test/fixtures/ios-debugger-app/build.ts +21 -0
  447. package/test/fixtures/latency-journey-app/README.md +2 -0
  448. package/test/fixtures/readiness-app/README.md +2 -0
  449. package/test/helpers/ios-trace-shutdown.ts +29 -0
  450. package/test/unit/debugger/coroutine-lifecycle.test.ts +43 -0
  451. package/test/unit/debugger/diagnostic-sessions.test.ts +67 -0
  452. package/test/unit/debugger/diagnostics.test.ts +80 -0
  453. package/test/unit/debugger/guards.test.ts +4 -0
  454. package/test/unit/debugger/handle-guards.test.ts +88 -0
  455. package/test/unit/debugger/ios-preparation.test.ts +57 -0
  456. package/test/unit/debugger/ios.test.ts +104 -0
  457. package/test/unit/debugger/lldb-worker.py +166 -0
  458. package/test/unit/debugger/lldb-worker.test.ts +10 -0
  459. package/test/unit/debugger/preparation.test.ts +32 -0
  460. package/test/unit/debugger/protocol.test.ts +15 -0
  461. package/test/unit/debugger/sessions.test.ts +1 -1
  462. package/test/unit/interact/adjustment_service.test.ts +42 -0
  463. package/test/unit/interact/adjustment_verification.test.ts +35 -0
  464. package/test/unit/interact/clock_dependencies.test.ts +63 -0
  465. package/test/unit/interact/element_helpers.test.ts +19 -0
  466. package/test/unit/interact/legacy_wait_service.test.ts +17 -0
  467. package/test/unit/interact/state_comparison.test.ts +20 -0
  468. package/test/unit/interact/target_scope.test.ts +35 -0
  469. package/test/unit/network/get_network_activity.test.ts +1 -1
  470. package/test/unit/observe/ios-trace-native.test.ts +90 -0
  471. package/test/unit/observe/ios-trace-sessions.test.ts +131 -0
  472. package/test/unit/observe/readiness.test.ts +1 -1
  473. package/test/unit/observe/screenshot-encoding.test.ts +30 -0
  474. package/test/unit/observe/snapshot-logs.test.ts +14 -0
  475. package/test/unit/observe/system-trace-router.test.ts +49 -0
  476. package/test/unit/quality/agent-plugin-export.test.ts +38 -0
  477. package/test/unit/quality/architecture.test.ts +60 -0
  478. package/test/unit/quality/code-quality.test.ts +58 -0
  479. package/test/unit/quality/interaction_boundaries.test.ts +24 -0
  480. package/test/unit/server/conditional_actions.test.ts +1 -1
  481. package/test/unit/server/conditional_schema.test.ts +2 -2
  482. package/test/unit/server/debugger-response.test.ts +63 -0
  483. package/test/unit/server/system-trace.test.ts +12 -3
  484. package/test/unit/server/tool_definitions_parity.test.ts +8 -0
  485. package/dist/server/debugger-handlers.js +0 -38
  486. package/dist/server/system-trace-schema.js +0 -17
  487. package/dist/server/tool-handlers.js +0 -1000
  488. package/docs/ROADMAP.md +0 -646
  489. package/docs/benchmarks/ui-tree-performance/bridge-probe.json +0 -29
  490. package/docs/benchmarks/ui-tree-performance/initial-baseline.json +0 -59560
  491. package/docs/specs/baseline-spec-v0.md +0 -312
  492. package/docs/specs/mcp-tooling-spec-v1.md +0 -446
  493. package/src/server/debugger-handlers.ts +0 -29
  494. package/src/server/debugger-schema.ts +0 -37
  495. package/src/server/system-trace-schema.ts +0 -17
  496. package/src/server/tool-handlers.ts +0 -1008
  497. /package/dist/{server/condition-schema.js → contracts/condition.js} +0 -0
  498. /package/dist/server/{readiness-schema.js → schemas/readiness-schema.js} +0 -0
  499. /package/src/{server/condition-schema.ts → contracts/condition.ts} +0 -0
  500. /package/src/server/{readiness-schema.ts → schemas/readiness-schema.ts} +0 -0
@@ -1,8 +1,53 @@
1
- import { debuggerTools } from './debugger-schema.js';
2
- import { systemTraceTools } from './system-trace-schema.js';
3
- import { journeyStepsJson } from './journey-schema.js';
4
- import { conditionalTools, expectedStateJson } from './condition-schema.js';
5
- import { readinessPropertiesJson } from './readiness-schema.js';
1
+ import { verificationModeJson, responseModeJson } from '../contracts/execution-controls.js';
2
+ import { manageTools } from './definitions/manage.js';
3
+ import { observeTools } from './definitions/observe.js';
4
+ import { diagnosticTools } from './definitions/diagnostic.js';
5
+ import { waitTools } from './definitions/wait.js';
6
+ import { assertTools } from './definitions/assert.js';
7
+ import { targetTools } from './definitions/target.js';
8
+ import { inputTools } from './definitions/input.js';
9
+ import { debuggerTools } from './schemas/debugger-schema.js';
10
+ import { systemTraceTools } from './schemas/system-trace-schema.js';
11
+ import { journeyStepsJson } from './schemas/journey-schema.js';
12
+ import { conditionalTools, expectedStateJson } from './schemas/condition-schema.js';
13
+ import { readinessPropertiesJson } from './schemas/readiness-schema.js';
14
+ const baseTools = new Map([...manageTools, ...observeTools, ...diagnosticTools, ...waitTools, ...assertTools, ...targetTools, ...inputTools].map(tool => [tool.name, tool]));
15
+ const baseOrder = [
16
+ "start_app",
17
+ "terminate_app",
18
+ "restart_app",
19
+ "reset_app_data",
20
+ "install_app",
21
+ "build_app",
22
+ "get_logs",
23
+ "list_devices",
24
+ "get_system_status",
25
+ "capture_screenshot",
26
+ "capture_debug_snapshot",
27
+ "start_log_stream",
28
+ "read_log_stream",
29
+ "stop_log_stream",
30
+ "get_ui_tree",
31
+ "get_current_screen",
32
+ "get_screen_fingerprint",
33
+ "wait_for_screen_change",
34
+ "wait_for_ui_change",
35
+ "expect_screen",
36
+ "expect_element_visible",
37
+ "expect_state",
38
+ "adjust_control",
39
+ "wait_for_ui",
40
+ "find_element",
41
+ "tap",
42
+ "tap_element",
43
+ "swipe",
44
+ "scroll_to_element",
45
+ "type_text",
46
+ "press_back",
47
+ "classify_action_outcome",
48
+ "run_journey",
49
+ "get_network_activity"
50
+ ];
6
51
  export const toolDefinitions = [
7
52
  ...debuggerTools,
8
53
  ...systemTraceTools,
@@ -15,1134 +60,11 @@ export const toolDefinitions = [
15
60
  ...(name === 'wait_for_app_ready' ? { pollIntervalMs: { type: 'integer', minimum: 100, maximum: 1000, default: 500 } } : {})
16
61
  } }
17
62
  })),
18
- {
19
- name: 'start_app',
20
- description: `Purpose:
21
- Launch a mobile app on Android or iOS.
22
-
23
- Inputs:
24
- - platform
25
- - appId
26
- - deviceId (optional)
27
-
28
- Output Structure:
29
- - action_id, timestamp (ISO 8601), action_type
30
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
31
- - source_module: runtime source of the action envelope
32
- - target.selector = { appId }
33
- - success = true when launch was dispatched successfully
34
- - failure_code/retryable when launch dispatch fails
35
- - ui_fingerprint_before/ui_fingerprint_after when available
36
-
37
- Recommended Usage:
38
- 1. Define the expected landing screen when it is known
39
- 2. Call start_app
40
- 3. If needed, wait for transition using wait_for_*
41
- 4. Verify with expect_screen
42
- 5. If verification fails, retry once or capture a snapshot
43
-
44
- Verification Guidance:
45
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
46
- - expect_screen is the authoritative verification step when the landing screen is known
47
- - Do not treat timing or screen change alone as final verification
48
-
49
- Failure Handling:
50
- - TIMEOUT → retry once
51
- - UNKNOWN → inspect snapshot/logs before retrying`,
52
- inputSchema: {
53
- type: 'object',
54
- properties: {
55
- platform: {
56
- type: 'string',
57
- enum: ['android', 'ios']
58
- },
59
- appId: {
60
- type: 'string',
61
- description: 'Android package name or iOS bundle id'
62
- },
63
- deviceId: {
64
- type: 'string',
65
- description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.'
66
- },
67
- verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
68
- responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
69
- actionTimeoutMs: { type: 'number', minimum: 100, maximum: 30000 },
70
- verificationTimeoutMs: { type: 'number', minimum: 100, maximum: 60000 }
71
- },
72
- required: ['platform', 'appId']
73
- }
74
- },
75
- {
76
- name: 'terminate_app',
77
- description: 'Terminate a mobile app on Android or iOS simulator',
78
- inputSchema: {
79
- type: 'object',
80
- properties: {
81
- platform: {
82
- type: 'string',
83
- enum: ['android', 'ios']
84
- },
85
- appId: {
86
- type: 'string',
87
- description: 'Android package name or iOS bundle id'
88
- },
89
- deviceId: {
90
- type: 'string',
91
- description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.'
92
- }
93
- },
94
- required: ['platform', 'appId']
95
- }
96
- },
97
- {
98
- name: 'restart_app',
99
- description: `Purpose:
100
- Restart a mobile app on Android or iOS.
101
-
102
- Inputs:
103
- - platform
104
- - appId
105
- - deviceId (optional)
106
-
107
- Output Structure:
108
- - action_id, timestamp (ISO 8601), action_type
109
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
110
- - source_module: runtime source of the action envelope
111
- - target.selector = { appId }
112
- - success = true when the restart command completed
113
- - failure_code/retryable when restart dispatch fails
114
- - ui_fingerprint_before/ui_fingerprint_after when available
115
-
116
- Recommended Usage:
117
- 1. Define the expected landing screen when it is known
118
- 2. Call restart_app
119
- 3. If needed, wait for transition using wait_for_*
120
- 4. Verify with expect_screen
121
- 5. If verification fails, retry once or capture a snapshot
122
-
123
- Verification Guidance:
124
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
125
- - expect_screen is the authoritative verification step when the reopened screen is known
126
- - Do not treat timing or screen change alone as final verification
127
-
128
- Failure Handling:
129
- - TIMEOUT → retry once
130
- - UNKNOWN → inspect snapshot/logs before retrying`,
131
- inputSchema: {
132
- type: 'object',
133
- properties: {
134
- platform: {
135
- type: 'string',
136
- enum: ['android', 'ios']
137
- },
138
- appId: {
139
- type: 'string',
140
- description: 'Android package name or iOS bundle id'
141
- },
142
- deviceId: {
143
- type: 'string',
144
- description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.'
145
- }
146
- },
147
- required: ['platform', 'appId']
148
- }
149
- },
150
- {
151
- name: 'reset_app_data',
152
- description: 'Reset app data (clear storage) for a mobile app on Android or iOS simulator',
153
- inputSchema: {
154
- type: 'object',
155
- properties: {
156
- platform: {
157
- type: 'string',
158
- enum: ['android', 'ios']
159
- },
160
- appId: {
161
- type: 'string',
162
- description: 'Android package name or iOS bundle id'
163
- },
164
- deviceId: {
165
- type: 'string',
166
- description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.'
167
- }
168
- },
169
- required: ['platform', 'appId']
170
- }
171
- },
172
- {
173
- name: 'install_app',
174
- description: 'Install an app on Android or iOS. Accepts a built binary (apk/.ipa/.app) or a project directory to build then install. platform and projectType are required.',
175
- inputSchema: {
176
- type: 'object',
177
- properties: {
178
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Platform to install to (required).' },
179
- projectType: { type: 'string', enum: ['native', 'kmp', 'react-native', 'flutter'], description: 'Project type to guide build/install tool selection (required).' },
180
- appPath: { type: 'string', description: 'Path to APK, .app, .ipa, or project directory' },
181
- deviceId: { type: 'string', description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.' }
182
- },
183
- required: ['platform', 'projectType', 'appPath']
184
- }
185
- },
186
- {
187
- name: 'build_app',
188
- description: 'Build a project for Android or iOS and return the built artifact path. Does not install. platform and projectType are required.',
189
- inputSchema: {
190
- type: 'object',
191
- properties: {
192
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Platform to build for (required).' },
193
- projectType: { type: 'string', enum: ['native', 'kmp', 'react-native', 'flutter'], description: 'Project type to guide build tool selection (required).' },
194
- projectPath: { type: 'string', description: 'Path to project directory (contains gradlew or xcodeproj/xcworkspace)' },
195
- variant: { type: 'string', description: 'Optional build variant (e.g., Debug/Release)' }
196
- },
197
- required: ['platform', 'projectType', 'projectPath']
198
- }
199
- },
200
- {
201
- name: 'get_logs',
202
- description: 'Get recent logs from Android or iOS simulator. Returns device metadata and structured logs suitable for AI consumption.',
203
- inputSchema: {
204
- type: 'object',
205
- properties: {
206
- platform: {
207
- type: 'string',
208
- enum: ['android', 'ios']
209
- },
210
- appId: {
211
- type: 'string',
212
- description: 'Filter by Android package name or iOS bundle id'
213
- },
214
- deviceId: {
215
- type: 'string',
216
- description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.'
217
- },
218
- pid: { type: 'number', description: 'Filter by process id' },
219
- tag: { type: 'string', description: 'Filter by tag (Android) or subsystem/category (iOS)' },
220
- level: { type: 'string', description: 'Log level filter (VERBOSE, DEBUG, INFO, WARN, ERROR)' },
221
- contains: { type: 'string', description: 'Substring to match in log message' },
222
- since_seconds: { type: 'number', description: 'Only return logs from the last N seconds' },
223
- limit: { type: 'number', description: 'Override default number of returned lines' },
224
- lines: {
225
- type: 'number',
226
- description: 'Legacy - number of log lines (android only)'
227
- }
228
- },
229
- required: ['platform']
230
- }
231
- },
232
- {
233
- name: 'list_devices',
234
- description: 'List connected devices and their metadata (android + ios).',
235
- inputSchema: {
236
- type: 'object',
237
- properties: {
238
- platform: { type: 'string', enum: ['android', 'ios'] }
239
- }
240
- }
241
- },
242
- {
243
- name: 'get_system_status',
244
- description: 'Quick healthcheck of local mobile debugging environment (adb, devices, logs, env, iOS).',
245
- inputSchema: { type: 'object', properties: {} }
246
- },
247
- {
248
- name: 'capture_screenshot',
249
- description: 'Capture a screenshot from an Android device or iOS simulator. Returns device metadata and the screenshot image.',
250
- inputSchema: {
251
- type: 'object',
252
- properties: {
253
- platform: {
254
- type: 'string',
255
- enum: ['android', 'ios']
256
- },
257
- deviceId: {
258
- type: 'string',
259
- description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.'
260
- }
261
- },
262
- required: ['platform']
263
- }
264
- },
265
- {
266
- name: 'capture_debug_snapshot',
267
- description: 'Capture a complete debug snapshot (raw observation layer plus optional derived semantic layer). Returns structured JSON with snapshot_revision, captured_at_ms, snapshot_delta, and loading_state when detectable.',
268
- inputSchema: {
269
- type: 'object',
270
- properties: {
271
- reason: { type: 'string', description: 'Optional reason for snapshot' },
272
- includeLogs: { type: 'boolean', description: 'Whether to include logs', default: true },
273
- includeScreenshot: { type: 'boolean', description: 'Whether to collect screenshot bytes', default: true },
274
- logLines: { type: 'number', description: 'Maximum number of log lines to include', default: 200 },
275
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
276
- appId: { type: 'string', description: 'Optional appId to scope logs (package/bundle id)' },
277
- deviceId: { type: 'string', description: 'Optional device serial/udid' },
278
- sessionId: { type: 'string', description: 'Optional log stream session id to prefer' }
279
- }
280
- }
281
- },
282
- {
283
- name: 'start_log_stream',
284
- description: 'Start streaming logs for a target application on Android or iOS. For Android this uses adb logcat --pid=<pid>; for iOS it streams `xcrun simctl spawn <device> log stream` with a predicate.',
285
- inputSchema: {
286
- type: 'object',
287
- properties: {
288
- platform: { type: 'string', enum: ['android', 'ios'], default: 'android' },
289
- packageName: { type: 'string', description: 'Android package name or iOS bundle id' },
290
- level: { type: 'string', enum: ['error', 'warn', 'info', 'debug'], default: 'error' },
291
- deviceId: { type: 'string', description: 'Device Serial (Android) or UDID (iOS). Defaults to connected/booted device.' },
292
- sessionId: { type: 'string', description: 'Session identifier for the log stream' }
293
- },
294
- required: ['packageName']
295
- }
296
- },
297
- {
298
- name: 'read_log_stream',
299
- description: 'Read accumulated log stream entries for the active session.',
300
- inputSchema: {
301
- type: 'object',
302
- properties: {
303
- sessionId: { type: 'string' }
304
- }
305
- }
306
- },
307
- {
308
- name: 'stop_log_stream',
309
- description: 'Stop an active log stream for the session.',
310
- inputSchema: {
311
- type: 'object',
312
- properties: {
313
- sessionId: { type: 'string' }
314
- }
315
- }
316
- },
317
- {
318
- name: 'get_ui_tree',
319
- description: 'Get the current UI hierarchy from an Android device or iOS simulator. Returns a structured JSON representation of the screen content with snapshot metadata and incremental delta signals when available.',
320
- inputSchema: {
321
- type: 'object',
322
- properties: {
323
- platform: {
324
- type: 'string',
325
- enum: ['android', 'ios'],
326
- description: 'Platform to get UI tree for'
327
- },
328
- deviceId: {
329
- type: 'string',
330
- description: 'Device Serial (Android) or UDID (iOS). Defaults to connected/booted device.'
331
- },
332
- responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
333
- sinceSnapshotRevision: { type: 'number', minimum: 1 }
334
- },
335
- required: ['platform']
336
- }
337
- },
338
- {
339
- name: 'get_current_screen',
340
- description: 'Get the currently visible activity on an Android device. Returns package and activity name.',
341
- inputSchema: {
342
- type: 'object',
343
- properties: {
344
- deviceId: {
345
- type: 'string',
346
- description: 'Device Serial (Android). Defaults to connected/booted device.'
347
- }
348
- }
349
- }
350
- },
351
- {
352
- name: 'get_screen_fingerprint',
353
- description: 'Generate a stable fingerprint representing the current visible screen (activity + visible UI elements).',
354
- inputSchema: {
355
- type: 'object',
356
- properties: {
357
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override (android|ios)' },
358
- deviceId: { type: 'string', description: 'Optional device id/udid to target' }
359
- }
360
- }
361
- },
362
- {
363
- name: 'wait_for_screen_change',
364
- description: `Purpose:
365
- Detect that a screen transition has occurred by waiting for the current fingerprint to differ from a previous fingerprint.
366
-
367
- Capabilities:
368
- - Synchronization for uncertain navigation timing
369
- - Detection that something changed on screen
370
-
371
- Constraints:
372
- - Does not verify correctness of the resulting state
373
- - Must not be used alone to confirm action success when an applicable expect_* tool exists
374
- - For backend/API activity without a visible UI change, pass the runtime action_type into classify_action_outcome and collect network evidence only if the result remains ambiguous
375
-
376
- Recommended Usage:
377
- 1. Capture or define the expected outcome
378
- 2. Call an action tool
379
- 3. Use wait_for_screen_change when transition timing is uncertain
380
- 4. Follow with expect_screen when the expected destination is known`,
381
- inputSchema: {
382
- type: 'object',
383
- properties: {
384
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override (android|ios)' },
385
- previousFingerprint: { type: 'string', description: 'The fingerprint to compare against (required)' },
386
- timeoutMs: { type: 'number', description: 'Timeout in ms to wait for change (default 5000)', default: 5000 },
387
- pollIntervalMs: { type: 'number', description: 'Polling interval in ms (default 300)', default: 300 },
388
- deviceId: { type: 'string', description: 'Optional device id/udid to target' }
389
- },
390
- required: ['previousFingerprint']
391
- }
392
- },
393
- {
394
- name: 'wait_for_ui_change',
395
- description: `Purpose:
396
- Wait for a non-navigation UI mutation or in-place update to become stable.
397
-
398
- Inputs:
399
- - expected_change (optional): hierarchy_diff, text_change, or state_change
400
- - timeout_ms (optional)
401
- - stability_window_ms (optional)
402
- - scope (optional): screen or subtree
403
- - target (optional): element_id when scope=subtree
404
-
405
- Guidance:
406
- - Prefer wait_for_screen_change for navigation transitions.
407
- - Prefer wait_for_ui_change for in-place mutations and non-navigation updates.
408
- - Use the returned snapshot_revision as the observed synchronization point when available.
409
- - Scoped waits return scope-aware stability metadata and a lightweight change summary.
410
-
411
- Failure Handling:
412
- - TIMEOUT means the UI did not change in a stable way within the allotted time.`,
413
- inputSchema: {
414
- type: 'object',
415
- properties: {
416
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override (android|ios)' },
417
- deviceId: { type: 'string', description: 'Optional device id/udid to target' },
418
- expected_change: { type: 'string', enum: ['hierarchy_diff', 'text_change', 'state_change'], description: 'Optional type of UI change to wait for' },
419
- scope: { type: 'string', enum: ['screen', 'subtree'], default: 'screen', description: 'Synchronization scope for the wait' },
420
- target: { type: 'string', description: 'Target element_id when scope is subtree' },
421
- timeout_ms: { type: 'number', description: 'Timeout in ms to wait for change (default 60000)', default: 60000 },
422
- stability_window_ms: { type: 'number', description: 'How long the change must remain stable before success (default 300)', default: 300 }
423
- }
424
- }
425
- },
426
- {
427
- name: 'expect_screen',
428
- description: `Purpose:
429
- Deterministically verify that the intended navigation outcome of an action has occurred.
430
-
431
- Inputs:
432
- - fingerprint: preferred exact-match screen fingerprint
433
- - screen: exact semantic screen identifier when a fingerprint is not available
434
-
435
- Output Structure:
436
- - success: true when the expected screen matches the observed screen
437
- - observed_screen: current fingerprint and screen identifier
438
- - expected_screen: the expected fingerprint and/or screen identifier
439
- - confidence: 1 for an exact match, otherwise 0
440
-
441
- Recommended Usage:
442
- 1. Define the expected screen before executing the action
443
- 2. Resolve the target element or screen state
444
- 3. Call an action tool such as tap_element
445
- 4. If needed, wait for transition using wait_for_*
446
- 5. Call expect_screen as the final verification step
447
- 6. If success=false, treat the outcome as unverified and follow the action tool retry guidance
448
-
449
- Verification Guidance:
450
- - Primary and authoritative verification tool for navigation outcomes
451
- - Prefer fingerprint whenever you have one
452
- - Use screen only as a fallback exact match against known identifiers
453
- - Works best when the expected screen identifier is known ahead of time
454
- - If the expected screen is not already known, capture or define it before executing the action
455
-
456
- Constraints:
457
- - Returns structured binary success/failure only
458
- - Must not rely on natural-language interpretation or reasoning
459
-
460
- Failure Handling:
461
- - success=false means the expected screen was not reached; retry or recover using the action tool's failure strategy`,
462
- inputSchema: {
463
- type: 'object',
464
- properties: {
465
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override (android|ios)' },
466
- fingerprint: { type: 'string', description: 'Expected screen fingerprint. Preferred verification mechanism.' },
467
- screen: { type: 'string', description: 'Expected exact screen identifier when no fingerprint is available.' },
468
- deviceId: { type: 'string', description: 'Optional device id/udid to target' }
469
- }
470
- }
471
- },
472
- {
473
- name: 'expect_element_visible',
474
- description: `Purpose:
475
- Deterministically verify that the intended UI outcome of an action has occurred by confirming a target element is visible.
476
-
477
- Inputs:
478
- - selector: required selector used to resolve the target element
479
- - element_id: optional previously resolved element identifier used only as context
480
-
481
- Output Structure:
482
- - success: true when the element is visible
483
- - selector: selector used for verification
484
- - element_id: resolved element identifier when available
485
- - element: minimal resolved element info when visible
486
- - failure_code: TIMEOUT or UNKNOWN when verification fails
487
- - retryable: true when failure_code=TIMEOUT
488
-
489
- Recommended Usage:
490
- 1. Define the expected element state before executing the action
491
- 2. Resolve the target element or triggering control
492
- 3. Call an action tool such as tap_element
493
- 4. If needed, wait for UI availability using wait_for_*
494
- 5. Call expect_element_visible as the final verification step
495
- 6. If success=false, follow the action tool retry guidance
496
-
497
- Verification Guidance:
498
- - Primary and authoritative verification tool for expected element appearance or visibility
499
- - Use this when the screen should stay the same but the UI should reveal or update a specific element
500
- - selector is the primary input; element_id is an optional optimization only
501
- - The tool resolves the selector internally when needed
502
-
503
- Constraints:
504
- - Returns structured binary success/failure only
505
- - Must not rely on natural-language interpretation or reasoning
506
-
507
- Failure Handling:
508
- - TIMEOUT → retry verification once or retry the action after re-resolving
509
- - UNKNOWN → capture a snapshot and stop`,
510
- inputSchema: {
511
- type: 'object',
512
- properties: {
513
- selector: {
514
- type: 'object',
515
- properties: {
516
- text: { type: 'string' },
517
- resource_id: { type: 'string' },
518
- accessibility_id: { type: 'string' },
519
- contains: { type: 'boolean', default: false }
520
- }
521
- },
522
- element_id: { type: 'string', description: 'Optional previously resolved element identifier.' },
523
- timeout_ms: { type: 'number', default: 5000 },
524
- poll_interval_ms: { type: 'number', default: 300 },
525
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
526
- deviceId: { type: 'string', description: 'Optional device serial/udid' }
527
- },
528
- required: ['selector']
529
- }
530
- },
531
- {
532
- name: 'expect_state',
533
- description: `Purpose:
534
- Verify a readable UI state property on the currently visible element.
535
-
536
- Inputs:
537
- - selector or element_id
538
- - property
539
- - expected
540
- - platform/deviceId (optional)
541
-
542
- Supported properties:
543
- - checked, selected, focused, expanded, enabled, text_value, value, raw_value
544
-
545
- Verification Guidance:
546
- - Use this when the UI element is visible but its state must also be confirmed
547
- - Prefer the canonical property names above
548
- - The tool compares the normalized readable state and returns the observed value when available
549
-
550
- Constraints:
551
- - Returns structured success/failure only
552
- - Does not infer a state when the property is unavailable
553
-
554
- Failure Handling:
555
- - ELEMENT_NOT_FOUND → re-resolve the element or wait for UI stabilization
556
- - UNKNOWN → capture a snapshot and stop`,
557
- inputSchema: {
558
- type: 'object',
559
- properties: {
560
- selector: {
561
- type: 'object',
562
- properties: {
563
- text: { type: 'string' },
564
- resource_id: { type: 'string' },
565
- accessibility_id: { type: 'string' },
566
- contains: { type: 'boolean', default: false }
567
- }
568
- },
569
- element_id: { type: 'string', description: 'Optional previously resolved element identifier.' },
570
- property: { type: 'string', description: 'Readable state property to verify.' },
571
- expected: {
572
- description: 'Expected normalized state value.',
573
- oneOf: [
574
- { type: 'boolean' },
575
- { type: 'number' },
576
- { type: 'string' },
577
- { type: 'object' }
578
- ]
579
- },
580
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
581
- deviceId: { type: 'string', description: 'Optional device serial/udid' }
582
- },
583
- required: ['property', 'expected']
584
- }
585
- },
586
- {
587
- name: 'adjust_control',
588
- description: `Purpose:
589
- Adjust a numeric control value with verification.
590
-
591
- This is the initial adjustable-control surface for slider-like controls and other controls that expose a numeric value or value_range.
592
-
593
- Inputs:
594
- - exactly one of selector or element_id
595
- - property (defaults to "value")
596
- - targetValue
597
- - tolerance (optional; discrete default is 0, continuous default is max(step / 2, 1% of range) when omitted)
598
- - maxAttempts (optional; defaults to 5)
599
- - platform/deviceId (optional)
600
-
601
- Output Structure:
602
- - action_id, timestamp (ISO 8601), action_type
603
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
604
- - source_module: runtime source of the action envelope
605
- - target_state / actual_state / within_tolerance / converged / attempts / adjustment_mode
606
- - target.selector = original selector or element handle
607
- - success = true when the control converges within tolerance
608
-
609
- Verification Guidance:
610
- - Prefer direct platform adjustment when the runtime exposes it; then verified increment/decrement actions; use coordinate fallback only as degraded mode
611
- - Use expect_state for the control value readback
612
- - Do not use derived semantic metadata as proof of success
613
-
614
- Failure Handling:
615
- - ELEMENT_NOT_FOUND → re-resolve the control
616
- - ELEMENT_NOT_INTERACTABLE → the control cannot be adjusted through the current runtime
617
- - CONTROL_CONVERGENCE_FAILED → the control did not converge within bounded retries or the requested value is out of range
618
- - UNKNOWN → capture a snapshot and stop`,
619
- inputSchema: {
620
- type: 'object',
621
- properties: {
622
- selector: {
623
- type: 'object',
624
- properties: {
625
- text: { type: 'string' },
626
- resource_id: { type: 'string' },
627
- accessibility_id: { type: 'string' },
628
- contains: { type: 'boolean', default: false }
629
- }
630
- },
631
- element_id: { type: 'string', description: 'Optional previously resolved element identifier.' },
632
- property: { type: 'string', description: 'Readable numeric state property to adjust.', default: 'value' },
633
- targetValue: { type: 'number', description: 'Target numeric value.' },
634
- tolerance: { type: 'number', description: 'Accepted numeric tolerance around the target value. Defaults are derived from the readable control domain.' },
635
- maxAttempts: { type: 'number', description: 'Maximum adjustment attempts.', default: 5 },
636
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
637
- deviceId: { type: 'string', description: 'Optional device serial/udid' }
638
- },
639
- required: ['targetValue'],
640
- oneOf: [
641
- { required: ['selector'] },
642
- { required: ['element_id'] }
643
- ]
644
- }
645
- },
646
- {
647
- name: 'wait_for_ui',
648
- description: `Purpose:
649
- Resolve elements and/or detect that a UI transition or availability condition has occurred.
650
-
651
- Capabilities:
652
- - Deterministic element resolution
653
- - Synchronization when element timing or availability is uncertain
654
-
655
- Constraints:
656
- - Does not verify correctness of the resulting state
657
- - Must not be used alone to confirm action success when an applicable expect_* tool exists
658
-
659
- Recommended Usage:
660
- 1. Use wait_for_ui to resolve an element before acting or to wait for UI readiness
661
- 2. Call the action tool
662
- 3. If the expected outcome is known, follow with expect_* as final verification`,
663
- inputSchema: {
664
- type: 'object',
665
- properties: {
666
- selector: {
667
- type: 'object',
668
- properties: {
669
- text: { type: 'string' },
670
- resource_id: { type: 'string' },
671
- accessibility_id: { type: 'string' },
672
- contains: { type: 'boolean', description: 'When true, perform substring matching', default: false }
673
- }
674
- },
675
- condition: { type: 'string', enum: ['exists', 'not_exists', 'visible', 'clickable'], default: 'exists' },
676
- timeout_ms: { type: 'number', default: 60000 },
677
- poll_interval_ms: { type: 'number', default: 300 },
678
- match: { type: 'object', properties: { index: { type: 'number' } } },
679
- retry: { type: 'object', properties: { max_attempts: { type: 'number', default: 1 }, backoff_ms: { type: 'number', default: 0 } } },
680
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
681
- deviceId: { type: 'string', description: 'Optional device serial/udid' }
682
- }
683
- }
684
- },
685
- {
686
- name: 'find_element',
687
- description: `Find a UI element by semantic query (text, content-desc, resource-id, class).
688
-
689
- Returns the best match plus resolution metadata when available, including confidence, selection reason, and fallback alternates.`,
690
- inputSchema: {
691
- type: 'object',
692
- properties: {
693
- query: { type: 'string', description: 'Search query (text or label)' },
694
- exact: { type: 'boolean', description: 'Require exact match (true/false)', default: false },
695
- timeoutMs: { type: 'number', description: 'Timeout in ms to keep searching', default: 3000 },
696
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Optional platform override' },
697
- deviceId: { type: 'string', description: 'Optional device serial/udid' }
698
- },
699
- required: ['query']
700
- }
701
- },
702
- {
703
- name: 'tap',
704
- description: `Purpose:
705
- Dispatch a tap at specific screen coordinates.
706
-
707
- Inputs:
708
- - x, y coordinates
709
- - platform (optional)
710
- - deviceId (optional)
711
-
712
- Output Structure:
713
- - action_id, timestamp (ISO 8601), action_type
714
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
715
- - source_module: runtime source of the action envelope
716
- - target.selector = { x, y }
717
- - success = true when the tap was dispatched
718
- - failure_code/retryable when dispatch fails
719
- - ui_fingerprint_before/ui_fingerprint_after when available
720
-
721
- Recommended Usage:
722
- 1. Resolve coordinates deterministically
723
- 2. Call tap
724
- 3. If needed, wait for transition using wait_for_*
725
- 4. Verify with expect_screen or expect_element_visible depending on the intended outcome
726
-
727
- Verification Guidance:
728
- - Prefer tap_element over tap when an element can be resolved
729
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
730
- - Use expect_screen for navigation and expect_element_visible for local UI changes
731
- - Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
732
-
733
- Failure Handling:
734
- - TIMEOUT → retry once
735
- - UNKNOWN → capture a snapshot and stop`,
736
- inputSchema: {
737
- type: 'object',
738
- properties: {
739
- platform: {
740
- type: 'string',
741
- enum: ['android', 'ios'],
742
- description: 'Platform to tap on'
743
- },
744
- x: {
745
- type: 'number',
746
- description: 'X coordinate'
747
- },
748
- y: {
749
- type: 'number',
750
- description: 'Y coordinate'
751
- },
752
- deviceId: {
753
- type: 'string',
754
- description: 'Device Serial/UDID. Defaults to connected/booted device.'
755
- },
756
- verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
757
- responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
758
- actionTimeoutMs: { type: 'number', minimum: 100, maximum: 30000 },
759
- verificationTimeoutMs: { type: 'number', minimum: 100, maximum: 60000 }
760
- },
761
- required: ['x', 'y']
762
- }
763
- },
764
- {
765
- name: 'tap_element',
766
- description: `Purpose:
767
- Tap a previously resolved UI element using its elementId.
768
-
769
- Inputs:
770
- - elementId: a resolved UI element identifier returned by wait_for_ui
771
-
772
- Output Structure:
773
- - action_id: unique timestamp-based action identifier
774
- - timestamp: ISO 8601 timestamp for the action attempt
775
- - action_type: "tap_element"
776
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
777
- - source_module: runtime source of the action envelope
778
- - target.selector: original target handle ({ elementId })
779
- - target.resolved: minimal resolved element info used for the tap
780
- - success: true when the tap was dispatched
781
- - failure_code: present when success=false
782
- - retryable: present when failure_code exists
783
- - ui_fingerprint_before/ui_fingerprint_after: optional fingerprints captured around the action
784
-
785
- Recommended Usage:
786
- 1. Resolve the target with wait_for_ui or another deterministic resolver
787
- 2. Call tap_element
788
- 3. If needed, wait for transition using wait_for_*
789
- 4. Verify outcome using expect_*
790
- - use expect_screen when navigation is expected
791
- - use expect_element_visible when the UI change is local
792
- 5. If verification fails, inspect failure_code and follow the retry strategy below
793
-
794
- Verification Guidance:
795
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
796
- - Prefer expect_screen for navigation or modal transitions
797
- - Prefer expect_element_visible when the tap should reveal or update a specific element
798
- - wait_for_* may be used for resolution and synchronization, but not as the final verification step when an applicable expect_* tool exists
799
- - Do not treat tap_element.success as outcome success; it only means the tap was executed
800
-
801
- Failure Handling:
802
- - STALE_REFERENCE → re-resolve the element, then retry
803
- - ELEMENT_NOT_INTERACTABLE → wait or refine the target, then retry
804
- - UNKNOWN → capture a snapshot and stop
805
-
806
- This tool reports execution success only. Verification must be done with a separate expect_* tool.`,
807
- inputSchema: {
808
- type: 'object',
809
- properties: {
810
- elementId: {
811
- type: 'string',
812
- description: 'A unique element identifier returned by wait_for_ui'
813
- },
814
- selector: { type: 'object', properties: { text: { type: 'string' }, resource_id: { type: 'string' }, accessibility_id: { type: 'string' }, contains: { type: 'boolean' } } },
815
- 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' } } } } },
816
- platform: { type: 'string', enum: ['android', 'ios'] },
817
- deviceId: { type: 'string' },
818
- verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
819
- responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' }
820
- }
821
- }
822
- },
823
- {
824
- name: 'swipe',
825
- description: `Purpose:
826
- Dispatch a swipe gesture on Android or iOS.
827
-
828
- Inputs:
829
- - start and end coordinates
830
- - duration
831
- - platform/deviceId (optional)
832
-
833
- Output Structure:
834
- - action_id, timestamp (ISO 8601), action_type
835
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
836
- - source_module: runtime source of the action envelope
837
- - target.selector = { x1, y1, x2, y2, duration }
838
- - success = true when the swipe was dispatched
839
- - failure_code/retryable when dispatch fails
840
- - ui_fingerprint_before/ui_fingerprint_after when available
841
-
842
- Recommended Usage:
843
- 1. Determine swipe coordinates
844
- 2. Call swipe
845
- 3. If needed, wait for transition using wait_for_*
846
- 4. Verify with expect_screen or expect_element_visible when a deterministic outcome is expected
847
-
848
- Verification Guidance:
849
- - Swipe outcomes are less predictable; choose the most specific verifier available for the intended effect
850
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
851
- - Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
852
-
853
- Failure Handling:
854
- - TIMEOUT → retry once
855
- - UNKNOWN → capture a snapshot and stop`,
856
- inputSchema: {
857
- type: 'object',
858
- properties: {
859
- platform: {
860
- type: 'string',
861
- enum: ['android', 'ios'],
862
- description: 'Platform to swipe on (android or ios)'
863
- },
864
- x1: { type: 'number', description: 'Start X coordinate' },
865
- y1: { type: 'number', description: 'Start Y coordinate' },
866
- x2: { type: 'number', description: 'End X coordinate' },
867
- y2: { type: 'number', description: 'End Y coordinate' },
868
- duration: { type: 'number', description: 'Duration in ms' },
869
- deviceId: {
870
- type: 'string',
871
- description: 'Device Serial/UDID. Defaults to connected/booted device.'
872
- }
873
- },
874
- required: ['x1', 'y1', 'x2', 'y2', 'duration']
875
- }
876
- },
877
- {
878
- name: 'scroll_to_element',
879
- description: `Purpose:
880
- Scroll until a target element becomes visible.
881
-
882
- Inputs:
883
- - platform
884
- - selector
885
- - direction, maxScrolls, scrollAmount, deviceId (optional)
886
-
887
- Output Structure:
888
- - action_id, timestamp (ISO 8601), action_type
889
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
890
- - source_module: runtime source of the action envelope
891
- - target.selector = original selector
892
- - target.resolved = minimal resolved element info when found
893
- - success = true when scrolling produced a visible target element
894
- - failure_code/retryable when the target was not reached
895
- - ui_fingerprint_before/ui_fingerprint_after when available
896
-
897
- Recommended Usage:
898
- 1. Resolve the target selector
899
- 2. Call scroll_to_element
900
- 3. If needed, wait for UI stabilization using wait_for_*
901
- 4. Verify with expect_element_visible when the expected element visibility is known
902
- 5. If success=false, follow failure handling before retrying
903
-
904
- Verification Guidance:
905
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
906
- - Use expect_element_visible when you need an explicit post-scroll confirmation
907
- - Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
908
-
909
- Failure Handling:
910
- - NAVIGATION_NO_CHANGE → adjust scroll direction or stop
911
- - TIMEOUT → retry with refined selector or larger scroll budget
912
- - UNKNOWN → capture a snapshot and stop`,
913
- inputSchema: {
914
- type: 'object',
915
- properties: {
916
- platform: { type: 'string', enum: ['android', 'ios'], description: 'Platform to operate on (required)' },
917
- selector: {
918
- type: 'object',
919
- properties: {
920
- text: { type: 'string' },
921
- resourceId: { type: 'string' },
922
- contentDesc: { type: 'string' },
923
- className: { type: 'string' }
924
- }
925
- },
926
- direction: { type: 'string', enum: ['down', 'up'], default: 'down' },
927
- maxScrolls: { type: 'number', default: 10 },
928
- scrollAmount: { type: 'number', default: 0.7 },
929
- deviceId: { type: 'string', description: 'Device UDID (iOS) or Serial (Android). Defaults to booted/connected.' }
930
- },
931
- required: ['platform', 'selector']
932
- }
933
- },
934
- {
935
- name: 'type_text',
936
- description: `Purpose:
937
- Type text into the currently focused Android input field.
938
-
939
- Inputs:
940
- - text
941
- - platform/deviceId (optional)
942
-
943
- Output Structure:
944
- - action_id, timestamp (ISO 8601), action_type
945
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
946
- - source_module: runtime source of the action envelope
947
- - target.selector = { text }
948
- - success = true when text input was dispatched
949
- - failure_code/retryable when dispatch fails
950
- - ui_fingerprint_before/ui_fingerprint_after when available
951
-
952
- Recommended Usage:
953
- 1. Resolve or focus the target input first
954
- 2. Call type_text
955
- 3. If needed, wait for UI stabilization using wait_for_*
956
- 4. Verify with expect_element_visible or expect_screen, depending on the intended outcome
957
-
958
- Verification Guidance:
959
- - Prefer verifying the next expected element or screen state instead of inferring success from the text action alone
960
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
961
- - Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
962
-
963
- Failure Handling:
964
- - TIMEOUT → retry once
965
- - UNKNOWN → re-focus the input or capture a snapshot`,
966
- inputSchema: {
967
- type: 'object',
968
- properties: {
969
- platform: {
970
- type: 'string',
971
- enum: ['android'],
972
- description: 'Platform to type on (currently only android supported)'
973
- },
974
- text: {
975
- type: 'string',
976
- description: 'The text to type'
977
- },
978
- deviceId: {
979
- type: 'string',
980
- description: 'Device Serial/UDID. Defaults to connected/booted device.'
981
- }
982
- },
983
- required: ['text']
984
- }
985
- },
986
- {
987
- name: 'press_back',
988
- description: `Purpose:
989
- Dispatch the Android Back action.
990
-
991
- Inputs:
992
- - platform/deviceId (optional)
993
-
994
- Output Structure:
995
- - action_id, timestamp (ISO 8601), action_type
996
- - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)
997
- - source_module: runtime source of the action envelope
998
- - target.selector = { key: "back" }
999
- - success = true when the back action was dispatched
1000
- - failure_code/retryable when dispatch fails
1001
- - ui_fingerprint_before/ui_fingerprint_after when available
1002
-
1003
- Recommended Usage:
1004
- 1. Call press_back
1005
- 2. If needed, wait for transition using wait_for_*
1006
- 3. Verify with expect_screen when a known destination is expected
1007
- 4. If verification fails, retry once or recover explicitly
1008
-
1009
- Verification Guidance:
1010
- - Back outcomes can vary by screen, so verify against the intended destination when possible
1011
- - Follow RESOLVE → ACT → WAIT (if needed) → EXPECT
1012
- - Do not use wait_for_* alone as final verification when an applicable expect_* tool exists
1013
-
1014
- Failure Handling:
1015
- - TIMEOUT → retry once
1016
- - UNKNOWN → capture a snapshot and stop`,
1017
- inputSchema: {
1018
- type: 'object',
1019
- properties: {
1020
- platform: {
1021
- type: 'string',
1022
- enum: ['android'],
1023
- description: 'Platform (currently only android supported)'
1024
- },
1025
- deviceId: {
1026
- type: 'string',
1027
- description: 'Device Serial/UDID. Defaults to connected/booted device.'
1028
- }
1029
- }
1030
- }
1031
- },
1032
- {
1033
- name: 'classify_action_outcome',
1034
- description: `Classify the outcome of the most recent action into exactly one of: success, no_op, backend_failure, ui_failure, unknown.
1035
-
1036
- Use the runtime action result's \`action_type\` as \`actionType\` so the classifier can distinguish local-state actions from side-effect actions.
1037
- Use this when the intended outcome is not already fully verified by the UI signal alone.
1038
- For backend/API activity, compare get_screen_fingerprint before and after the action and call get_network_activity immediately after the action if the outcome is still ambiguous.
1039
-
1040
- HOW TO GATHER INPUTS before calling:
1041
- 1. Call wait_for_screen_change or compare get_screen_fingerprint before/after — set uiChanged accordingly.
1042
- 2. If you checked for a specific element with wait_for_ui, set expectedElementVisible.
1043
- 3. Pass actionType from the action response when available.
1044
- 4. Only provide networkRequests if you already collected them or want to classify a side-effect action with backend evidence.
1045
-
1046
- RULES (applied in order — stop at first match):
1047
- 1. If uiChanged=true OR expectedElementVisible=true → outcome=success
1048
- 2. If actionType is missing → outcome=unknown
1049
- 3. If any request has status=failure or retryable → outcome=backend_failure
1050
- 4. If actionType maps to a local-state action → outcome=no_op; prefer state-based verification and avoid default network fallback
1051
- 5. If actionType maps to a side-effect action and no networkRequests were supplied → outcome=unknown
1052
- 6. If no requests returned → outcome=no_op
1053
- 7. If all requests succeeded → outcome=ui_failure
1054
- 8. Otherwise → outcome=unknown
1055
-
1056
- BEHAVIOUR after outcome:
1057
- - success → continue
1058
- - no_op → retry with richer state verification or re-resolve the element
1059
- - backend_failure → stop and report the failing endpoint
1060
- - ui_failure → stop and report failure
1061
- - unknown → take one recovery step (e.g. capture_debug_snapshot), then stop`,
1062
- inputSchema: {
1063
- type: 'object',
1064
- properties: {
1065
- uiChanged: {
1066
- type: 'boolean',
1067
- description: 'true if the screen fingerprint or activity changed after the action. Use wait_for_screen_change or compare get_screen_fingerprint before and after.'
1068
- },
1069
- expectedElementVisible: {
1070
- type: 'boolean',
1071
- description: 'true if the element you expected to appear is now visible (from wait_for_ui). Omit if you did not check for a specific element.'
1072
- },
1073
- actionType: {
1074
- type: 'string',
1075
- description: 'The runtime action_type from the action response (for example tap, tap_element, swipe, type_text, press_back, start_app).'
1076
- },
1077
- networkRequests: {
1078
- type: 'array',
1079
- description: 'Optional network evidence collected after the action. Use it when the expected outcome is backend/API activity or when the UI signal is ambiguous.',
1080
- items: {
1081
- type: 'object',
1082
- properties: {
1083
- endpoint: { type: 'string', description: 'Request endpoint or full URL' },
1084
- status: { type: 'string', enum: ['success', 'failure', 'retryable'], description: 'Outcome of the request' }
1085
- },
1086
- required: ['endpoint', 'status']
1087
- }
1088
- },
1089
- hasLogErrors: {
1090
- type: 'boolean',
1091
- description: 'true if structured log errors were observed (e.g. from read_log_stream). Optional — include if you have already read logs.'
1092
- }
1093
- },
1094
- required: ['uiChanged']
1095
- }
1096
- },
1097
- {
1098
- name: 'run_journey',
1099
- description: 'Run an ordered, bounded sequence of start_app, tap, wait, and deterministic assertion steps against one device. Stops after the first failed step.',
1100
- inputSchema: {
1101
- type: 'object',
1102
- properties: {
1103
- platform: { type: 'string', enum: ['android', 'ios'] },
1104
- deviceId: { type: 'string' },
1105
- responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'compact' },
1106
- 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'] } }
1107
- },
1108
- required: ['platform', 'steps']
1109
- }
1110
- },
1111
- {
1112
- name: 'get_network_activity',
1113
- description: `Returns structured network events captured from platform logs since the last action.
1114
-
1115
- Call this immediately after an action when you want backend evidence for a side-effect flow, only if the result is still ambiguous.
1116
- Do not call more than once per action.
1117
-
1118
- Events are filtered to significant (non-background) requests only.
1119
- Each event includes endpoint, method, statusCode, networkError, status, and durationMs.
1120
-
1121
- status values:
1122
- - success: HTTP 2xx or request detected with no error signal
1123
- - failure: HTTP 4xx
1124
- - retryable: HTTP 5xx, network error (timeout, dns_error, tls_error, etc.)
1125
-
1126
- Returns { requests: [], count: 0 } when no credible network signals are found.`,
1127
- inputSchema: {
1128
- type: 'object',
1129
- properties: {
1130
- platform: {
1131
- type: 'string',
1132
- enum: ['android', 'ios'],
1133
- description: 'Platform to read network logs from'
1134
- },
1135
- deviceId: {
1136
- type: 'string',
1137
- description: 'Device Serial (Android) or UDID (iOS). Defaults to connected/booted device.'
1138
- }
1139
- },
1140
- required: ['platform']
1141
- }
1142
- }
63
+ ...baseOrder.map(name => baseTools.get(name))
1143
64
  ];
1144
65
  // Keep the additive execution controls consistent across all action tools.
1145
66
  for (const tool of toolDefinitions) {
67
+ tool.inputSchema.properties ??= {};
1146
68
  if (['wait_for_ui', 'wait_for_ui_change'].includes(tool.name)) {
1147
69
  tool.inputSchema.properties.requireReady = { type: 'boolean', default: false };
1148
70
  tool.description += '\nSet requireReady=true to require both the existing predicate and settled UI readiness, using the same fresh samples and one timeout budget. The readiness summary explains uncertainty. Default predicate semantics are unchanged.';
@@ -1154,7 +76,7 @@ for (const tool of toolDefinitions) {
1154
76
  if (conditionalTools.has(tool.name)) {
1155
77
  tool.inputSchema.properties.expectedState = expectedStateJson;
1156
78
  tool.inputSchema.properties.platform ??= { type: 'string', enum: ['android'] };
1157
- tool.inputSchema.allOf = [...(tool.inputSchema.allOf ?? []), {
79
+ tool.inputSchema.allOf = [...(Array.isArray(tool.inputSchema.allOf) ? tool.inputSchema.allOf : []), {
1158
80
  if: { required: ['expectedState'] },
1159
81
  then: { required: ['platform', 'deviceId'], properties: {
1160
82
  platform: { enum: ['type_text', 'press_back'].includes(tool.name) ? ['android'] : ['android', 'ios'] },
@@ -1164,12 +86,12 @@ for (const tool of toolDefinitions) {
1164
86
  tool.description += '\n\nConditional input: optionally supply expectedState { snapshotSessionId, snapshotRevision, timeoutMs? } from a successful get_ui_tree on the same explicit platform/deviceId. A fresh normalized UI-tree check runs immediately before input, even with verification disabled. PRECONDITION_FAILED or PRECONDITION_UNAVAILABLE means no input was dispatched; inspect condition evidence and re-observe before deciding what to do next. Compact failures include the fresh UI tree. This is not atomic with OS input delivery.';
1165
87
  }
1166
88
  else {
1167
- tool.inputSchema.allOf = [...(tool.inputSchema.allOf ?? []), { not: { required: ['expectedState'] } }];
89
+ tool.inputSchema.allOf = [...(Array.isArray(tool.inputSchema.allOf) ? tool.inputSchema.allOf : []), { not: { required: ['expectedState'] } }];
1168
90
  }
1169
91
  if (['start_app', 'restart_app', 'tap', 'tap_element', 'swipe', 'scroll_to_element', 'type_text', 'press_back'].includes(tool.name)) {
1170
92
  Object.assign(tool.inputSchema.properties, {
1171
- verificationMode: { type: 'string', enum: ['none', 'light', 'full'], default: 'full' },
1172
- responseMode: { type: 'string', enum: ['compact', 'debug'], default: 'debug' },
93
+ verificationMode: { ...verificationModeJson, default: 'full' },
94
+ responseMode: { ...responseModeJson, default: 'debug' },
1173
95
  actionTimeoutMs: { type: 'integer', description: 'Dispatch budget in milliseconds, clamped to 100–30000.' },
1174
96
  verificationTimeoutMs: { type: 'integer', description: 'Light observation budget in milliseconds, clamped to 100–60000.' }
1175
97
  });
@@ -1182,13 +104,14 @@ for (const tool of toolDefinitions) {
1182
104
  systemTraceId: { type: 'string', format: 'uuid', description: 'Explicit active same-device system trace. Invalid references prevent all journey input. Capture lifetime is controlled separately.' },
1183
105
  captureOnFailure: { type: 'boolean', default: false },
1184
106
  defaults: { type: 'object', additionalProperties: false, properties: {
1185
- verificationMode: { type: 'string', enum: ['none', 'light', 'full'] },
107
+ verificationMode: verificationModeJson,
1186
108
  actionTimeoutMs: { type: 'integer' }, verificationTimeoutMs: { type: 'integer' }
1187
109
  } }
1188
110
  });
1189
111
  }
1190
112
  // Correlation is explicit; an omitted reference creates an independent observation.
1191
113
  for (const tool of toolDefinitions) {
114
+ tool.inputSchema.properties ??= {};
1192
115
  if (['capture_screenshot', 'get_ui_tree', 'get_screen_fingerprint', 'capture_debug_snapshot', 'get_logs', 'read_log_stream'].includes(tool.name)) {
1193
116
  Object.assign(tool.inputSchema.properties, { actionRef: {
1194
117
  type: 'object', additionalProperties: false, required: ['sessionId', 'actionId'], properties: {