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
@@ -0,0 +1,3696 @@
1
+ [
2
+ {
3
+ "name": "get_debugger_capabilities",
4
+ "description": "Probe optional platform debugger prerequisites and matching running debuggable processes; does not attach.",
5
+ "inputSchema": {
6
+ "type": "object",
7
+ "additionalProperties": false,
8
+ "allOf": [
9
+ {
10
+ "if": {
11
+ "properties": {
12
+ "platform": {
13
+ "const": "ios"
14
+ }
15
+ }
16
+ },
17
+ "then": {
18
+ "properties": {
19
+ "deviceId": {
20
+ "pattern": "^[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}$"
21
+ }
22
+ }
23
+ }
24
+ },
25
+ {
26
+ "not": {
27
+ "required": [
28
+ "expectedState"
29
+ ]
30
+ }
31
+ }
32
+ ],
33
+ "required": [
34
+ "platform",
35
+ "deviceId",
36
+ "appId"
37
+ ],
38
+ "properties": {
39
+ "responseMode": {
40
+ "type": "string",
41
+ "enum": [
42
+ "compact",
43
+ "debug"
44
+ ],
45
+ "default": "debug"
46
+ },
47
+ "platform": {
48
+ "type": "string",
49
+ "enum": [
50
+ "android",
51
+ "ios"
52
+ ]
53
+ },
54
+ "deviceId": {
55
+ "type": "string",
56
+ "minLength": 1,
57
+ "maxLength": 512
58
+ },
59
+ "appId": {
60
+ "type": "string",
61
+ "minLength": 1,
62
+ "maxLength": 512,
63
+ "pattern": "^[A-Za-z][\\w-]*(?:\\.[A-Za-z][\\w-]*)+$"
64
+ },
65
+ "processId": {
66
+ "type": "integer",
67
+ "minimum": 0,
68
+ "maximum": 9007199254740991
69
+ },
70
+ "timeoutMs": {
71
+ "type": "integer",
72
+ "minimum": 100,
73
+ "maximum": 30000,
74
+ "default": 10000
75
+ }
76
+ }
77
+ }
78
+ },
79
+ {
80
+ "name": "attach_debugger",
81
+ "description": "Attach an owned Android JDI or iOS simulator LLDB session. Requires an explicit device and debuggable app; choose processId when ambiguous. Stops suspend all app threads. Auto-detach: 60s paused, 5m idle, 30m total.",
82
+ "inputSchema": {
83
+ "type": "object",
84
+ "additionalProperties": false,
85
+ "allOf": [
86
+ {
87
+ "if": {
88
+ "properties": {
89
+ "platform": {
90
+ "const": "ios"
91
+ }
92
+ }
93
+ },
94
+ "then": {
95
+ "properties": {
96
+ "deviceId": {
97
+ "pattern": "^[A-Fa-f0-9]{8}(?:-[A-Fa-f0-9]{4}){3}-[A-Fa-f0-9]{12}$"
98
+ }
99
+ }
100
+ }
101
+ },
102
+ {
103
+ "not": {
104
+ "required": [
105
+ "expectedState"
106
+ ]
107
+ }
108
+ }
109
+ ],
110
+ "required": [
111
+ "platform",
112
+ "deviceId",
113
+ "appId"
114
+ ],
115
+ "properties": {
116
+ "responseMode": {
117
+ "type": "string",
118
+ "enum": [
119
+ "compact",
120
+ "debug"
121
+ ],
122
+ "default": "debug"
123
+ },
124
+ "platform": {
125
+ "type": "string",
126
+ "enum": [
127
+ "android",
128
+ "ios"
129
+ ]
130
+ },
131
+ "deviceId": {
132
+ "type": "string",
133
+ "minLength": 1,
134
+ "maxLength": 512
135
+ },
136
+ "appId": {
137
+ "type": "string",
138
+ "minLength": 1,
139
+ "maxLength": 512,
140
+ "pattern": "^[A-Za-z][\\w-]*(?:\\.[A-Za-z][\\w-]*)+$"
141
+ },
142
+ "processId": {
143
+ "type": "integer",
144
+ "minimum": 0,
145
+ "maximum": 9007199254740991
146
+ },
147
+ "timeoutMs": {
148
+ "type": "integer",
149
+ "minimum": 100,
150
+ "maximum": 30000,
151
+ "default": 10000
152
+ }
153
+ }
154
+ }
155
+ },
156
+ {
157
+ "name": "get_debugger_state",
158
+ "description": "Read debugger state, current stop and breakpoint/cleanup status.",
159
+ "inputSchema": {
160
+ "type": "object",
161
+ "additionalProperties": false,
162
+ "required": [
163
+ "debugSessionId"
164
+ ],
165
+ "properties": {
166
+ "responseMode": {
167
+ "type": "string",
168
+ "enum": [
169
+ "compact",
170
+ "debug"
171
+ ],
172
+ "default": "debug"
173
+ },
174
+ "debugSessionId": {
175
+ "type": "string",
176
+ "minLength": 1,
177
+ "maxLength": 512
178
+ },
179
+ "timeoutMs": {
180
+ "type": "integer",
181
+ "minimum": 100,
182
+ "maximum": 30000,
183
+ "default": 10000
184
+ }
185
+ },
186
+ "allOf": [
187
+ {
188
+ "not": {
189
+ "required": [
190
+ "expectedState"
191
+ ]
192
+ }
193
+ }
194
+ ]
195
+ }
196
+ },
197
+ {
198
+ "name": "set_debugger_breakpoint",
199
+ "description": "Set an exact source breakpoint: Android className or iOS absolute sourceFile (exactly one), plus line; unloaded classes/images remain pending. No silent line relocation.",
200
+ "inputSchema": {
201
+ "type": "object",
202
+ "additionalProperties": false,
203
+ "oneOf": [
204
+ {
205
+ "required": [
206
+ "className"
207
+ ],
208
+ "not": {
209
+ "required": [
210
+ "sourceFile"
211
+ ]
212
+ }
213
+ },
214
+ {
215
+ "required": [
216
+ "sourceFile"
217
+ ],
218
+ "not": {
219
+ "required": [
220
+ "className"
221
+ ]
222
+ }
223
+ }
224
+ ],
225
+ "required": [
226
+ "debugSessionId",
227
+ "line"
228
+ ],
229
+ "properties": {
230
+ "responseMode": {
231
+ "type": "string",
232
+ "enum": [
233
+ "compact",
234
+ "debug"
235
+ ],
236
+ "default": "debug"
237
+ },
238
+ "debugSessionId": {
239
+ "type": "string",
240
+ "minLength": 1,
241
+ "maxLength": 512
242
+ },
243
+ "className": {
244
+ "type": "string",
245
+ "minLength": 1,
246
+ "maxLength": 512,
247
+ "pattern": "^[A-Za-z_$][\\w$]*(?:\\.[A-Za-z_$][\\w$]*)*$"
248
+ },
249
+ "sourceFile": {
250
+ "type": "string",
251
+ "minLength": 1,
252
+ "maxLength": 512,
253
+ "pattern": "^\\/[^\\0\\r\\n]+$"
254
+ },
255
+ "line": {
256
+ "type": "integer",
257
+ "minimum": 0,
258
+ "maximum": 9007199254740991
259
+ },
260
+ "timeoutMs": {
261
+ "type": "integer",
262
+ "minimum": 100,
263
+ "maximum": 30000,
264
+ "default": 10000
265
+ }
266
+ },
267
+ "allOf": [
268
+ {
269
+ "not": {
270
+ "required": [
271
+ "expectedState"
272
+ ]
273
+ }
274
+ }
275
+ ]
276
+ }
277
+ },
278
+ {
279
+ "name": "remove_debugger_breakpoint",
280
+ "description": "Remove an owned breakpoint; repeated removal succeeds.",
281
+ "inputSchema": {
282
+ "type": "object",
283
+ "additionalProperties": false,
284
+ "required": [
285
+ "debugSessionId",
286
+ "breakpointId"
287
+ ],
288
+ "properties": {
289
+ "responseMode": {
290
+ "type": "string",
291
+ "enum": [
292
+ "compact",
293
+ "debug"
294
+ ],
295
+ "default": "debug"
296
+ },
297
+ "debugSessionId": {
298
+ "type": "string",
299
+ "minLength": 1,
300
+ "maxLength": 512
301
+ },
302
+ "breakpointId": {
303
+ "type": "string",
304
+ "minLength": 1,
305
+ "maxLength": 512
306
+ },
307
+ "timeoutMs": {
308
+ "type": "integer",
309
+ "minimum": 100,
310
+ "maximum": 30000,
311
+ "default": 10000
312
+ }
313
+ },
314
+ "allOf": [
315
+ {
316
+ "not": {
317
+ "required": [
318
+ "expectedState"
319
+ ]
320
+ }
321
+ }
322
+ ]
323
+ }
324
+ },
325
+ {
326
+ "name": "wait_for_debugger_event",
327
+ "description": "Wait for bounded debugger events after a sequence cursor. Empty timeout does not affect execution; overflow is explicit.",
328
+ "inputSchema": {
329
+ "type": "object",
330
+ "additionalProperties": false,
331
+ "required": [
332
+ "debugSessionId"
333
+ ],
334
+ "properties": {
335
+ "responseMode": {
336
+ "type": "string",
337
+ "enum": [
338
+ "compact",
339
+ "debug"
340
+ ],
341
+ "default": "debug"
342
+ },
343
+ "debugSessionId": {
344
+ "type": "string",
345
+ "minLength": 1,
346
+ "maxLength": 512
347
+ },
348
+ "afterSequence": {
349
+ "type": "integer",
350
+ "minimum": 0,
351
+ "maximum": 9007199254740991
352
+ },
353
+ "timeoutMs": {
354
+ "type": "integer",
355
+ "minimum": 100,
356
+ "maximum": 30000,
357
+ "default": 1000
358
+ }
359
+ },
360
+ "allOf": [
361
+ {
362
+ "not": {
363
+ "required": [
364
+ "expectedState"
365
+ ]
366
+ }
367
+ }
368
+ ]
369
+ }
370
+ },
371
+ {
372
+ "name": "get_debugger_stack",
373
+ "description": "Read bounded stack frames for a stopped thread; IDs expire on resume.",
374
+ "inputSchema": {
375
+ "type": "object",
376
+ "additionalProperties": false,
377
+ "required": [
378
+ "debugSessionId",
379
+ "stopId",
380
+ "threadId"
381
+ ],
382
+ "properties": {
383
+ "responseMode": {
384
+ "type": "string",
385
+ "enum": [
386
+ "compact",
387
+ "debug"
388
+ ],
389
+ "default": "debug"
390
+ },
391
+ "debugSessionId": {
392
+ "type": "string",
393
+ "minLength": 1,
394
+ "maxLength": 512
395
+ },
396
+ "stopId": {
397
+ "type": "string",
398
+ "minLength": 1,
399
+ "maxLength": 512
400
+ },
401
+ "threadId": {
402
+ "type": "string",
403
+ "minLength": 1,
404
+ "maxLength": 512
405
+ },
406
+ "offset": {
407
+ "type": "integer",
408
+ "minimum": 0,
409
+ "maximum": 999
410
+ },
411
+ "limit": {
412
+ "type": "integer",
413
+ "minimum": 1,
414
+ "maximum": 100
415
+ },
416
+ "timeoutMs": {
417
+ "type": "integer",
418
+ "minimum": 100,
419
+ "maximum": 30000,
420
+ "default": 10000
421
+ }
422
+ },
423
+ "allOf": [
424
+ {
425
+ "not": {
426
+ "required": [
427
+ "expectedState"
428
+ ]
429
+ }
430
+ }
431
+ ]
432
+ }
433
+ },
434
+ {
435
+ "name": "get_debugger_locals",
436
+ "description": "Read at most 100 shallow locals. Sensitive values returned only on request; strings truncate at 256 characters; iOS aggregates return type summaries. No evaluation or field traversal.",
437
+ "inputSchema": {
438
+ "type": "object",
439
+ "additionalProperties": false,
440
+ "required": [
441
+ "debugSessionId",
442
+ "stopId",
443
+ "frameId"
444
+ ],
445
+ "properties": {
446
+ "responseMode": {
447
+ "type": "string",
448
+ "enum": [
449
+ "compact",
450
+ "debug"
451
+ ],
452
+ "default": "debug"
453
+ },
454
+ "debugSessionId": {
455
+ "type": "string",
456
+ "minLength": 1,
457
+ "maxLength": 512
458
+ },
459
+ "stopId": {
460
+ "type": "string",
461
+ "minLength": 1,
462
+ "maxLength": 512
463
+ },
464
+ "frameId": {
465
+ "type": "string",
466
+ "minLength": 1,
467
+ "maxLength": 512
468
+ },
469
+ "timeoutMs": {
470
+ "type": "integer",
471
+ "minimum": 100,
472
+ "maximum": 30000,
473
+ "default": 10000
474
+ }
475
+ },
476
+ "allOf": [
477
+ {
478
+ "not": {
479
+ "required": [
480
+ "expectedState"
481
+ ]
482
+ }
483
+ }
484
+ ]
485
+ }
486
+ },
487
+ {
488
+ "name": "step_debugger",
489
+ "description": "Acknowledge one-shot line stepping and resume. Wait for a subsequent stop event separately.",
490
+ "inputSchema": {
491
+ "type": "object",
492
+ "additionalProperties": false,
493
+ "required": [
494
+ "debugSessionId",
495
+ "stopId",
496
+ "threadId",
497
+ "kind"
498
+ ],
499
+ "properties": {
500
+ "responseMode": {
501
+ "type": "string",
502
+ "enum": [
503
+ "compact",
504
+ "debug"
505
+ ],
506
+ "default": "debug"
507
+ },
508
+ "debugSessionId": {
509
+ "type": "string",
510
+ "minLength": 1,
511
+ "maxLength": 512
512
+ },
513
+ "stopId": {
514
+ "type": "string",
515
+ "minLength": 1,
516
+ "maxLength": 512
517
+ },
518
+ "threadId": {
519
+ "type": "string",
520
+ "minLength": 1,
521
+ "maxLength": 512
522
+ },
523
+ "kind": {
524
+ "type": "string",
525
+ "enum": [
526
+ "into",
527
+ "over",
528
+ "out"
529
+ ]
530
+ },
531
+ "timeoutMs": {
532
+ "type": "integer",
533
+ "minimum": 100,
534
+ "maximum": 30000,
535
+ "default": 10000
536
+ }
537
+ },
538
+ "allOf": [
539
+ {
540
+ "not": {
541
+ "required": [
542
+ "expectedState"
543
+ ]
544
+ }
545
+ }
546
+ ]
547
+ }
548
+ },
549
+ {
550
+ "name": "resume_debugger",
551
+ "description": "Resume owned debugger suspension and immediately expire stopped references.",
552
+ "inputSchema": {
553
+ "type": "object",
554
+ "additionalProperties": false,
555
+ "required": [
556
+ "debugSessionId",
557
+ "stopId"
558
+ ],
559
+ "properties": {
560
+ "responseMode": {
561
+ "type": "string",
562
+ "enum": [
563
+ "compact",
564
+ "debug"
565
+ ],
566
+ "default": "debug"
567
+ },
568
+ "debugSessionId": {
569
+ "type": "string",
570
+ "minLength": 1,
571
+ "maxLength": 512
572
+ },
573
+ "stopId": {
574
+ "type": "string",
575
+ "minLength": 1,
576
+ "maxLength": 512
577
+ },
578
+ "timeoutMs": {
579
+ "type": "integer",
580
+ "minimum": 100,
581
+ "maximum": 30000,
582
+ "default": 10000
583
+ }
584
+ },
585
+ "allOf": [
586
+ {
587
+ "not": {
588
+ "required": [
589
+ "expectedState"
590
+ ]
591
+ }
592
+ }
593
+ ]
594
+ }
595
+ },
596
+ {
597
+ "name": "detach_debugger",
598
+ "description": "Dispose the owned debugger connection, release owned suspension and remove its owned transport. Idempotent; retries incomplete cleanup.",
599
+ "inputSchema": {
600
+ "type": "object",
601
+ "additionalProperties": false,
602
+ "required": [
603
+ "debugSessionId"
604
+ ],
605
+ "properties": {
606
+ "responseMode": {
607
+ "type": "string",
608
+ "enum": [
609
+ "compact",
610
+ "debug"
611
+ ],
612
+ "default": "debug"
613
+ },
614
+ "debugSessionId": {
615
+ "type": "string",
616
+ "minLength": 1,
617
+ "maxLength": 512
618
+ },
619
+ "timeoutMs": {
620
+ "type": "integer",
621
+ "minimum": 100,
622
+ "maximum": 30000,
623
+ "default": 10000
624
+ }
625
+ },
626
+ "allOf": [
627
+ {
628
+ "not": {
629
+ "required": [
630
+ "expectedState"
631
+ ]
632
+ }
633
+ }
634
+ ]
635
+ }
636
+ },
637
+ {
638
+ "name": "get_system_trace_capabilities",
639
+ "description": "Probe Android Perfetto or iOS Instruments prerequisites without recording. iOS requires explicit booted simulator deviceId; reports template matrix and unknown profiling permissions.",
640
+ "inputSchema": {
641
+ "type": "object",
642
+ "additionalProperties": false,
643
+ "required": [
644
+ "platform"
645
+ ],
646
+ "properties": {
647
+ "platform": {
648
+ "type": "string",
649
+ "enum": [
650
+ "android",
651
+ "ios"
652
+ ]
653
+ },
654
+ "deviceId": {
655
+ "type": "string",
656
+ "minLength": 1
657
+ },
658
+ "appId": {
659
+ "type": "string",
660
+ "minLength": 1,
661
+ "pattern": "^[a-zA-Z0-9._-]+$",
662
+ "description": "iOS only: running development app bundle identifier; required for iOS start."
663
+ },
664
+ "template": {
665
+ "type": "string",
666
+ "enum": [
667
+ "System Trace",
668
+ "Time Profiler",
669
+ "Animation Hitches",
670
+ "Hangs"
671
+ ],
672
+ "description": "iOS only. Default Time Profiler; initial simulator support is Time Profiler only."
673
+ }
674
+ },
675
+ "oneOf": [
676
+ {
677
+ "properties": {
678
+ "platform": {
679
+ "const": "android"
680
+ }
681
+ },
682
+ "not": {
683
+ "anyOf": [
684
+ {
685
+ "required": [
686
+ "appId"
687
+ ]
688
+ },
689
+ {
690
+ "required": [
691
+ "template"
692
+ ]
693
+ }
694
+ ]
695
+ }
696
+ },
697
+ {
698
+ "properties": {
699
+ "platform": {
700
+ "const": "ios"
701
+ }
702
+ },
703
+ "required": [
704
+ "deviceId"
705
+ ]
706
+ }
707
+ ],
708
+ "allOf": [
709
+ {
710
+ "not": {
711
+ "required": [
712
+ "expectedState"
713
+ ]
714
+ }
715
+ }
716
+ ]
717
+ }
718
+ },
719
+ {
720
+ "name": "start_system_trace",
721
+ "description": "Start bounded Android Perfetto or iOS simulator Time Profiler recording, returning an owned trace_id after readiness. iOS requires explicit deviceId and running appId. Run an existing journey with systemTraceId, then stop to retrieve a local artifact or cancel to discard. Traces can contain sensitive system metadata, logs and paths; local user-managed retention, no upload.",
722
+ "inputSchema": {
723
+ "type": "object",
724
+ "additionalProperties": false,
725
+ "required": [
726
+ "platform"
727
+ ],
728
+ "properties": {
729
+ "platform": {
730
+ "type": "string",
731
+ "enum": [
732
+ "android",
733
+ "ios"
734
+ ]
735
+ },
736
+ "deviceId": {
737
+ "type": "string",
738
+ "minLength": 1
739
+ },
740
+ "appId": {
741
+ "type": "string",
742
+ "minLength": 1,
743
+ "pattern": "^[a-zA-Z0-9._-]+$",
744
+ "description": "iOS only: running development app bundle identifier; required for iOS start."
745
+ },
746
+ "template": {
747
+ "type": "string",
748
+ "enum": [
749
+ "System Trace",
750
+ "Time Profiler",
751
+ "Animation Hitches",
752
+ "Hangs"
753
+ ],
754
+ "description": "iOS only. Default Time Profiler; initial simulator support is Time Profiler only."
755
+ },
756
+ "durationMs": {
757
+ "type": "integer",
758
+ "minimum": 1000,
759
+ "maximum": 120000,
760
+ "default": 30000
761
+ }
762
+ },
763
+ "oneOf": [
764
+ {
765
+ "properties": {
766
+ "platform": {
767
+ "const": "android"
768
+ }
769
+ },
770
+ "not": {
771
+ "anyOf": [
772
+ {
773
+ "required": [
774
+ "appId"
775
+ ]
776
+ },
777
+ {
778
+ "required": [
779
+ "template"
780
+ ]
781
+ }
782
+ ]
783
+ }
784
+ },
785
+ {
786
+ "properties": {
787
+ "platform": {
788
+ "const": "ios"
789
+ }
790
+ },
791
+ "required": [
792
+ "deviceId",
793
+ "appId"
794
+ ]
795
+ }
796
+ ],
797
+ "allOf": [
798
+ {
799
+ "not": {
800
+ "required": [
801
+ "expectedState"
802
+ ]
803
+ }
804
+ }
805
+ ]
806
+ }
807
+ },
808
+ {
809
+ "name": "get_system_trace_status",
810
+ "description": "Reconcile an owned trace and retrieve its state; finalise duration-completed capture.",
811
+ "inputSchema": {
812
+ "type": "object",
813
+ "additionalProperties": false,
814
+ "required": [
815
+ "traceId"
816
+ ],
817
+ "properties": {
818
+ "traceId": {
819
+ "type": "string",
820
+ "format": "uuid"
821
+ }
822
+ },
823
+ "allOf": [
824
+ {
825
+ "not": {
826
+ "required": [
827
+ "expectedState"
828
+ ]
829
+ }
830
+ }
831
+ ]
832
+ }
833
+ },
834
+ {
835
+ "name": "stop_system_trace",
836
+ "description": "Stop owned capture gracefully and retrieve a local Perfetto file or validated Instruments .trace bundle. Retry after a transfer/cleanup failure.",
837
+ "inputSchema": {
838
+ "type": "object",
839
+ "additionalProperties": false,
840
+ "required": [
841
+ "traceId"
842
+ ],
843
+ "properties": {
844
+ "traceId": {
845
+ "type": "string",
846
+ "format": "uuid"
847
+ }
848
+ },
849
+ "allOf": [
850
+ {
851
+ "not": {
852
+ "required": [
853
+ "expectedState"
854
+ ]
855
+ }
856
+ }
857
+ ]
858
+ }
859
+ },
860
+ {
861
+ "name": "cancel_system_trace",
862
+ "description": "Stop owned capture and discard partial files. Already completed local artifacts are retained.",
863
+ "inputSchema": {
864
+ "type": "object",
865
+ "additionalProperties": false,
866
+ "required": [
867
+ "traceId"
868
+ ],
869
+ "properties": {
870
+ "traceId": {
871
+ "type": "string",
872
+ "format": "uuid"
873
+ }
874
+ },
875
+ "allOf": [
876
+ {
877
+ "not": {
878
+ "required": [
879
+ "expectedState"
880
+ ]
881
+ }
882
+ }
883
+ ]
884
+ }
885
+ },
886
+ {
887
+ "name": "get_app_readiness",
888
+ "description": "Observe readiness with at most two fresh UI-tree samples. Reports loading, transitioning, settled or unknown with evidence and limitations. Managed Android debugger pauses are reported from debugger evidence; unresponsive detection remains unsupported. Settled normalized foreground UI is not proof of app identity, responsiveness or backend completion.",
889
+ "inputSchema": {
890
+ "type": "object",
891
+ "additionalProperties": false,
892
+ "required": [
893
+ "platform"
894
+ ],
895
+ "properties": {
896
+ "platform": {
897
+ "type": "string",
898
+ "enum": [
899
+ "android",
900
+ "ios"
901
+ ]
902
+ },
903
+ "deviceId": {
904
+ "type": "string",
905
+ "minLength": 1
906
+ },
907
+ "timeoutMs": {
908
+ "type": "integer",
909
+ "minimum": 100,
910
+ "maximum": 60000,
911
+ "default": 15000
912
+ },
913
+ "stabilityMs": {
914
+ "type": "integer",
915
+ "minimum": 100,
916
+ "maximum": 10000,
917
+ "default": 500
918
+ }
919
+ },
920
+ "allOf": [
921
+ {
922
+ "not": {
923
+ "required": [
924
+ "expectedState"
925
+ ]
926
+ }
927
+ }
928
+ ]
929
+ }
930
+ },
931
+ {
932
+ "name": "wait_for_app_ready",
933
+ "description": "Wait within a single bounded budget for settled UI evidence. Reports loading, transitioning, settled or unknown with evidence and limitations. Managed Android debugger pauses are reported from debugger evidence; unresponsive detection remains unsupported. Settled normalized foreground UI is not proof of app identity, responsiveness or backend completion.",
934
+ "inputSchema": {
935
+ "type": "object",
936
+ "additionalProperties": false,
937
+ "required": [
938
+ "platform"
939
+ ],
940
+ "properties": {
941
+ "platform": {
942
+ "type": "string",
943
+ "enum": [
944
+ "android",
945
+ "ios"
946
+ ]
947
+ },
948
+ "deviceId": {
949
+ "type": "string",
950
+ "minLength": 1
951
+ },
952
+ "timeoutMs": {
953
+ "type": "integer",
954
+ "minimum": 100,
955
+ "maximum": 60000,
956
+ "default": 30000
957
+ },
958
+ "stabilityMs": {
959
+ "type": "integer",
960
+ "minimum": 100,
961
+ "maximum": 10000,
962
+ "default": 500
963
+ },
964
+ "pollIntervalMs": {
965
+ "type": "integer",
966
+ "minimum": 100,
967
+ "maximum": 1000,
968
+ "default": 500
969
+ }
970
+ },
971
+ "allOf": [
972
+ {
973
+ "not": {
974
+ "required": [
975
+ "expectedState"
976
+ ]
977
+ }
978
+ }
979
+ ]
980
+ }
981
+ },
982
+ {
983
+ "name": "start_app",
984
+ "description": "Purpose:\nLaunch a mobile app on Android or iOS.\n\nInputs:\n- platform\n- appId\n- deviceId (optional)\n\nOutput Structure:\n - action_id, timestamp (ISO 8601), action_type\n - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n - source_module: runtime source of the action envelope\n - target.selector = { appId }\n- success = true when launch was dispatched successfully\n- failure_code/retryable when launch dispatch fails\n- ui_fingerprint_before/ui_fingerprint_after when available\n\nRecommended Usage:\n1. Define the expected landing screen when it is known\n2. Call start_app\n3. If needed, wait for transition using wait_for_*\n4. Verify with expect_screen\n5. If verification fails, retry once or capture a snapshot\n\nVerification Guidance:\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- expect_screen is the authoritative verification step when the landing screen is known\n- Do not treat timing or screen change alone as final verification\n\nFailure Handling:\n- TIMEOUT → retry once\n- UNKNOWN → inspect snapshot/logs before retrying",
985
+ "inputSchema": {
986
+ "type": "object",
987
+ "properties": {
988
+ "platform": {
989
+ "type": "string",
990
+ "enum": [
991
+ "android",
992
+ "ios"
993
+ ]
994
+ },
995
+ "appId": {
996
+ "type": "string",
997
+ "description": "Android package name or iOS bundle id"
998
+ },
999
+ "deviceId": {
1000
+ "type": "string",
1001
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
1002
+ },
1003
+ "verificationMode": {
1004
+ "type": "string",
1005
+ "enum": [
1006
+ "none",
1007
+ "light",
1008
+ "full"
1009
+ ],
1010
+ "default": "full"
1011
+ },
1012
+ "responseMode": {
1013
+ "type": "string",
1014
+ "enum": [
1015
+ "compact",
1016
+ "debug"
1017
+ ],
1018
+ "default": "debug"
1019
+ },
1020
+ "actionTimeoutMs": {
1021
+ "type": "integer",
1022
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
1023
+ },
1024
+ "verificationTimeoutMs": {
1025
+ "type": "integer",
1026
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
1027
+ }
1028
+ },
1029
+ "required": [
1030
+ "platform",
1031
+ "appId"
1032
+ ],
1033
+ "allOf": [
1034
+ {
1035
+ "not": {
1036
+ "required": [
1037
+ "expectedState"
1038
+ ]
1039
+ }
1040
+ }
1041
+ ]
1042
+ }
1043
+ },
1044
+ {
1045
+ "name": "terminate_app",
1046
+ "description": "Terminate a mobile app on Android or iOS simulator",
1047
+ "inputSchema": {
1048
+ "type": "object",
1049
+ "properties": {
1050
+ "platform": {
1051
+ "type": "string",
1052
+ "enum": [
1053
+ "android",
1054
+ "ios"
1055
+ ]
1056
+ },
1057
+ "appId": {
1058
+ "type": "string",
1059
+ "description": "Android package name or iOS bundle id"
1060
+ },
1061
+ "deviceId": {
1062
+ "type": "string",
1063
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
1064
+ }
1065
+ },
1066
+ "required": [
1067
+ "platform",
1068
+ "appId"
1069
+ ],
1070
+ "allOf": [
1071
+ {
1072
+ "not": {
1073
+ "required": [
1074
+ "expectedState"
1075
+ ]
1076
+ }
1077
+ }
1078
+ ]
1079
+ }
1080
+ },
1081
+ {
1082
+ "name": "restart_app",
1083
+ "description": "Purpose:\nRestart a mobile app on Android or iOS.\n\nInputs:\n- platform\n- appId\n- deviceId (optional)\n\nOutput Structure:\n - action_id, timestamp (ISO 8601), action_type\n - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n - source_module: runtime source of the action envelope\n - target.selector = { appId }\n- success = true when the restart command completed\n- failure_code/retryable when restart dispatch fails\n- ui_fingerprint_before/ui_fingerprint_after when available\n\nRecommended Usage:\n1. Define the expected landing screen when it is known\n2. Call restart_app\n3. If needed, wait for transition using wait_for_*\n4. Verify with expect_screen\n5. If verification fails, retry once or capture a snapshot\n\nVerification Guidance:\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- expect_screen is the authoritative verification step when the reopened screen is known\n- Do not treat timing or screen change alone as final verification\n\nFailure Handling:\n- TIMEOUT → retry once\n- UNKNOWN → inspect snapshot/logs before retrying",
1084
+ "inputSchema": {
1085
+ "type": "object",
1086
+ "properties": {
1087
+ "platform": {
1088
+ "type": "string",
1089
+ "enum": [
1090
+ "android",
1091
+ "ios"
1092
+ ]
1093
+ },
1094
+ "appId": {
1095
+ "type": "string",
1096
+ "description": "Android package name or iOS bundle id"
1097
+ },
1098
+ "deviceId": {
1099
+ "type": "string",
1100
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
1101
+ },
1102
+ "verificationMode": {
1103
+ "type": "string",
1104
+ "enum": [
1105
+ "none",
1106
+ "light",
1107
+ "full"
1108
+ ],
1109
+ "default": "full"
1110
+ },
1111
+ "responseMode": {
1112
+ "type": "string",
1113
+ "enum": [
1114
+ "compact",
1115
+ "debug"
1116
+ ],
1117
+ "default": "debug"
1118
+ },
1119
+ "actionTimeoutMs": {
1120
+ "type": "integer",
1121
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
1122
+ },
1123
+ "verificationTimeoutMs": {
1124
+ "type": "integer",
1125
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
1126
+ }
1127
+ },
1128
+ "required": [
1129
+ "platform",
1130
+ "appId"
1131
+ ],
1132
+ "allOf": [
1133
+ {
1134
+ "not": {
1135
+ "required": [
1136
+ "expectedState"
1137
+ ]
1138
+ }
1139
+ }
1140
+ ]
1141
+ }
1142
+ },
1143
+ {
1144
+ "name": "reset_app_data",
1145
+ "description": "Reset app data (clear storage) for a mobile app on Android or iOS simulator",
1146
+ "inputSchema": {
1147
+ "type": "object",
1148
+ "properties": {
1149
+ "platform": {
1150
+ "type": "string",
1151
+ "enum": [
1152
+ "android",
1153
+ "ios"
1154
+ ]
1155
+ },
1156
+ "appId": {
1157
+ "type": "string",
1158
+ "description": "Android package name or iOS bundle id"
1159
+ },
1160
+ "deviceId": {
1161
+ "type": "string",
1162
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
1163
+ }
1164
+ },
1165
+ "required": [
1166
+ "platform",
1167
+ "appId"
1168
+ ],
1169
+ "allOf": [
1170
+ {
1171
+ "not": {
1172
+ "required": [
1173
+ "expectedState"
1174
+ ]
1175
+ }
1176
+ }
1177
+ ]
1178
+ }
1179
+ },
1180
+ {
1181
+ "name": "install_app",
1182
+ "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.",
1183
+ "inputSchema": {
1184
+ "type": "object",
1185
+ "properties": {
1186
+ "platform": {
1187
+ "type": "string",
1188
+ "enum": [
1189
+ "android",
1190
+ "ios"
1191
+ ],
1192
+ "description": "Platform to install to (required)."
1193
+ },
1194
+ "projectType": {
1195
+ "type": "string",
1196
+ "enum": [
1197
+ "native",
1198
+ "kmp",
1199
+ "react-native",
1200
+ "flutter"
1201
+ ],
1202
+ "description": "Project type to guide build/install tool selection (required)."
1203
+ },
1204
+ "appPath": {
1205
+ "type": "string",
1206
+ "description": "Path to APK, .app, .ipa, or project directory"
1207
+ },
1208
+ "deviceId": {
1209
+ "type": "string",
1210
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
1211
+ }
1212
+ },
1213
+ "required": [
1214
+ "platform",
1215
+ "projectType",
1216
+ "appPath"
1217
+ ],
1218
+ "allOf": [
1219
+ {
1220
+ "not": {
1221
+ "required": [
1222
+ "expectedState"
1223
+ ]
1224
+ }
1225
+ }
1226
+ ]
1227
+ }
1228
+ },
1229
+ {
1230
+ "name": "build_app",
1231
+ "description": "Build a project for Android or iOS and return the built artifact path. Does not install. platform and projectType are required.",
1232
+ "inputSchema": {
1233
+ "type": "object",
1234
+ "properties": {
1235
+ "platform": {
1236
+ "type": "string",
1237
+ "enum": [
1238
+ "android",
1239
+ "ios"
1240
+ ],
1241
+ "description": "Platform to build for (required)."
1242
+ },
1243
+ "projectType": {
1244
+ "type": "string",
1245
+ "enum": [
1246
+ "native",
1247
+ "kmp",
1248
+ "react-native",
1249
+ "flutter"
1250
+ ],
1251
+ "description": "Project type to guide build tool selection (required)."
1252
+ },
1253
+ "projectPath": {
1254
+ "type": "string",
1255
+ "description": "Path to project directory (contains gradlew or xcodeproj/xcworkspace)"
1256
+ },
1257
+ "variant": {
1258
+ "type": "string",
1259
+ "description": "Optional build variant (e.g., Debug/Release)"
1260
+ }
1261
+ },
1262
+ "required": [
1263
+ "platform",
1264
+ "projectType",
1265
+ "projectPath"
1266
+ ],
1267
+ "allOf": [
1268
+ {
1269
+ "not": {
1270
+ "required": [
1271
+ "expectedState"
1272
+ ]
1273
+ }
1274
+ }
1275
+ ]
1276
+ }
1277
+ },
1278
+ {
1279
+ "name": "get_logs",
1280
+ "description": "Get recent logs from Android or iOS simulator. Returns device metadata and structured logs suitable for AI consumption.\nReturns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.",
1281
+ "inputSchema": {
1282
+ "type": "object",
1283
+ "properties": {
1284
+ "platform": {
1285
+ "type": "string",
1286
+ "enum": [
1287
+ "android",
1288
+ "ios"
1289
+ ]
1290
+ },
1291
+ "appId": {
1292
+ "type": "string",
1293
+ "description": "Filter by Android package name or iOS bundle id"
1294
+ },
1295
+ "deviceId": {
1296
+ "type": "string",
1297
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
1298
+ },
1299
+ "pid": {
1300
+ "type": "number",
1301
+ "description": "Filter by process id"
1302
+ },
1303
+ "tag": {
1304
+ "type": "string",
1305
+ "description": "Filter by tag (Android) or subsystem/category (iOS)"
1306
+ },
1307
+ "level": {
1308
+ "type": "string",
1309
+ "description": "Log level filter (VERBOSE, DEBUG, INFO, WARN, ERROR)"
1310
+ },
1311
+ "contains": {
1312
+ "type": "string",
1313
+ "description": "Substring to match in log message"
1314
+ },
1315
+ "since_seconds": {
1316
+ "type": "number",
1317
+ "description": "Only return logs from the last N seconds"
1318
+ },
1319
+ "limit": {
1320
+ "type": "number",
1321
+ "description": "Override default number of returned lines"
1322
+ },
1323
+ "lines": {
1324
+ "type": "number",
1325
+ "description": "Legacy - number of log lines (android only)"
1326
+ },
1327
+ "actionRef": {
1328
+ "type": "object",
1329
+ "additionalProperties": false,
1330
+ "required": [
1331
+ "sessionId",
1332
+ "actionId"
1333
+ ],
1334
+ "properties": {
1335
+ "sessionId": {
1336
+ "type": "string",
1337
+ "minLength": 1,
1338
+ "maxLength": 128
1339
+ },
1340
+ "actionId": {
1341
+ "type": "string",
1342
+ "minLength": 1,
1343
+ "maxLength": 128
1344
+ }
1345
+ }
1346
+ }
1347
+ },
1348
+ "required": [
1349
+ "platform"
1350
+ ],
1351
+ "allOf": [
1352
+ {
1353
+ "not": {
1354
+ "required": [
1355
+ "expectedState"
1356
+ ]
1357
+ }
1358
+ }
1359
+ ]
1360
+ }
1361
+ },
1362
+ {
1363
+ "name": "list_devices",
1364
+ "description": "List connected devices and their metadata (android + ios).",
1365
+ "inputSchema": {
1366
+ "type": "object",
1367
+ "properties": {
1368
+ "platform": {
1369
+ "type": "string",
1370
+ "enum": [
1371
+ "android",
1372
+ "ios"
1373
+ ]
1374
+ }
1375
+ },
1376
+ "allOf": [
1377
+ {
1378
+ "not": {
1379
+ "required": [
1380
+ "expectedState"
1381
+ ]
1382
+ }
1383
+ }
1384
+ ]
1385
+ }
1386
+ },
1387
+ {
1388
+ "name": "get_system_status",
1389
+ "description": "Quick healthcheck of local mobile debugging environment (adb, devices, logs, env, iOS).",
1390
+ "inputSchema": {
1391
+ "type": "object",
1392
+ "properties": {},
1393
+ "allOf": [
1394
+ {
1395
+ "not": {
1396
+ "required": [
1397
+ "expectedState"
1398
+ ]
1399
+ }
1400
+ }
1401
+ ]
1402
+ }
1403
+ },
1404
+ {
1405
+ "name": "capture_screenshot",
1406
+ "description": "Capture a screenshot from an Android device or iOS simulator. Returns device metadata and the screenshot image.\nReturns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.",
1407
+ "inputSchema": {
1408
+ "type": "object",
1409
+ "properties": {
1410
+ "platform": {
1411
+ "type": "string",
1412
+ "enum": [
1413
+ "android",
1414
+ "ios"
1415
+ ]
1416
+ },
1417
+ "deviceId": {
1418
+ "type": "string",
1419
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
1420
+ },
1421
+ "actionRef": {
1422
+ "type": "object",
1423
+ "additionalProperties": false,
1424
+ "required": [
1425
+ "sessionId",
1426
+ "actionId"
1427
+ ],
1428
+ "properties": {
1429
+ "sessionId": {
1430
+ "type": "string",
1431
+ "minLength": 1,
1432
+ "maxLength": 128
1433
+ },
1434
+ "actionId": {
1435
+ "type": "string",
1436
+ "minLength": 1,
1437
+ "maxLength": 128
1438
+ }
1439
+ }
1440
+ }
1441
+ },
1442
+ "required": [
1443
+ "platform"
1444
+ ],
1445
+ "allOf": [
1446
+ {
1447
+ "not": {
1448
+ "required": [
1449
+ "expectedState"
1450
+ ]
1451
+ }
1452
+ }
1453
+ ]
1454
+ }
1455
+ },
1456
+ {
1457
+ "name": "capture_debug_snapshot",
1458
+ "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.\nReturns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.",
1459
+ "inputSchema": {
1460
+ "type": "object",
1461
+ "properties": {
1462
+ "reason": {
1463
+ "type": "string",
1464
+ "description": "Optional reason for snapshot"
1465
+ },
1466
+ "includeLogs": {
1467
+ "type": "boolean",
1468
+ "description": "Whether to include logs",
1469
+ "default": true
1470
+ },
1471
+ "includeScreenshot": {
1472
+ "type": "boolean",
1473
+ "description": "Whether to collect screenshot bytes",
1474
+ "default": true
1475
+ },
1476
+ "logLines": {
1477
+ "type": "number",
1478
+ "description": "Maximum number of log lines to include",
1479
+ "default": 200
1480
+ },
1481
+ "platform": {
1482
+ "type": "string",
1483
+ "enum": [
1484
+ "android",
1485
+ "ios"
1486
+ ],
1487
+ "description": "Optional platform override"
1488
+ },
1489
+ "appId": {
1490
+ "type": "string",
1491
+ "description": "Optional appId to scope logs (package/bundle id)"
1492
+ },
1493
+ "deviceId": {
1494
+ "type": "string",
1495
+ "description": "Optional device serial/udid"
1496
+ },
1497
+ "sessionId": {
1498
+ "type": "string",
1499
+ "description": "Optional log stream session id to prefer"
1500
+ },
1501
+ "actionRef": {
1502
+ "type": "object",
1503
+ "additionalProperties": false,
1504
+ "required": [
1505
+ "sessionId",
1506
+ "actionId"
1507
+ ],
1508
+ "properties": {
1509
+ "sessionId": {
1510
+ "type": "string",
1511
+ "minLength": 1,
1512
+ "maxLength": 128
1513
+ },
1514
+ "actionId": {
1515
+ "type": "string",
1516
+ "minLength": 1,
1517
+ "maxLength": 128
1518
+ }
1519
+ }
1520
+ }
1521
+ },
1522
+ "allOf": [
1523
+ {
1524
+ "not": {
1525
+ "required": [
1526
+ "expectedState"
1527
+ ]
1528
+ }
1529
+ }
1530
+ ]
1531
+ }
1532
+ },
1533
+ {
1534
+ "name": "start_log_stream",
1535
+ "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.",
1536
+ "inputSchema": {
1537
+ "type": "object",
1538
+ "properties": {
1539
+ "platform": {
1540
+ "type": "string",
1541
+ "enum": [
1542
+ "android",
1543
+ "ios"
1544
+ ],
1545
+ "default": "android"
1546
+ },
1547
+ "packageName": {
1548
+ "type": "string",
1549
+ "description": "Android package name or iOS bundle id"
1550
+ },
1551
+ "level": {
1552
+ "type": "string",
1553
+ "enum": [
1554
+ "error",
1555
+ "warn",
1556
+ "info",
1557
+ "debug"
1558
+ ],
1559
+ "default": "error"
1560
+ },
1561
+ "deviceId": {
1562
+ "type": "string",
1563
+ "description": "Device Serial (Android) or UDID (iOS). Defaults to connected/booted device."
1564
+ },
1565
+ "sessionId": {
1566
+ "type": "string",
1567
+ "description": "Session identifier for the log stream"
1568
+ }
1569
+ },
1570
+ "required": [
1571
+ "packageName"
1572
+ ],
1573
+ "allOf": [
1574
+ {
1575
+ "not": {
1576
+ "required": [
1577
+ "expectedState"
1578
+ ]
1579
+ }
1580
+ }
1581
+ ]
1582
+ }
1583
+ },
1584
+ {
1585
+ "name": "read_log_stream",
1586
+ "description": "Read accumulated log stream entries for the active session.\nReturns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.",
1587
+ "inputSchema": {
1588
+ "type": "object",
1589
+ "properties": {
1590
+ "sessionId": {
1591
+ "type": "string"
1592
+ },
1593
+ "actionRef": {
1594
+ "type": "object",
1595
+ "additionalProperties": false,
1596
+ "required": [
1597
+ "sessionId",
1598
+ "actionId"
1599
+ ],
1600
+ "properties": {
1601
+ "sessionId": {
1602
+ "type": "string",
1603
+ "minLength": 1,
1604
+ "maxLength": 128
1605
+ },
1606
+ "actionId": {
1607
+ "type": "string",
1608
+ "minLength": 1,
1609
+ "maxLength": 128
1610
+ }
1611
+ }
1612
+ }
1613
+ },
1614
+ "allOf": [
1615
+ {
1616
+ "not": {
1617
+ "required": [
1618
+ "expectedState"
1619
+ ]
1620
+ }
1621
+ }
1622
+ ]
1623
+ }
1624
+ },
1625
+ {
1626
+ "name": "stop_log_stream",
1627
+ "description": "Stop an active log stream for the session.",
1628
+ "inputSchema": {
1629
+ "type": "object",
1630
+ "properties": {
1631
+ "sessionId": {
1632
+ "type": "string"
1633
+ }
1634
+ },
1635
+ "allOf": [
1636
+ {
1637
+ "not": {
1638
+ "required": [
1639
+ "expectedState"
1640
+ ]
1641
+ }
1642
+ }
1643
+ ]
1644
+ }
1645
+ },
1646
+ {
1647
+ "name": "get_ui_tree",
1648
+ "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.\nSuccessful observations include snapshot_session_id and snapshot_revision for same-device conditional input. Compact errors preserve the error and cannot authorize an expectation.\nReturns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.",
1649
+ "inputSchema": {
1650
+ "type": "object",
1651
+ "properties": {
1652
+ "platform": {
1653
+ "type": "string",
1654
+ "enum": [
1655
+ "android",
1656
+ "ios"
1657
+ ],
1658
+ "description": "Platform to get UI tree for"
1659
+ },
1660
+ "deviceId": {
1661
+ "type": "string",
1662
+ "description": "Device Serial (Android) or UDID (iOS). Defaults to connected/booted device."
1663
+ },
1664
+ "responseMode": {
1665
+ "type": "string",
1666
+ "enum": [
1667
+ "compact",
1668
+ "debug"
1669
+ ],
1670
+ "default": "debug"
1671
+ },
1672
+ "sinceSnapshotRevision": {
1673
+ "type": "number",
1674
+ "minimum": 1
1675
+ },
1676
+ "actionRef": {
1677
+ "type": "object",
1678
+ "additionalProperties": false,
1679
+ "required": [
1680
+ "sessionId",
1681
+ "actionId"
1682
+ ],
1683
+ "properties": {
1684
+ "sessionId": {
1685
+ "type": "string",
1686
+ "minLength": 1,
1687
+ "maxLength": 128
1688
+ },
1689
+ "actionId": {
1690
+ "type": "string",
1691
+ "minLength": 1,
1692
+ "maxLength": 128
1693
+ }
1694
+ }
1695
+ }
1696
+ },
1697
+ "required": [
1698
+ "platform"
1699
+ ],
1700
+ "allOf": [
1701
+ {
1702
+ "not": {
1703
+ "required": [
1704
+ "expectedState"
1705
+ ]
1706
+ }
1707
+ }
1708
+ ]
1709
+ }
1710
+ },
1711
+ {
1712
+ "name": "get_current_screen",
1713
+ "description": "Get the currently visible activity on an Android device. Returns package and activity name.",
1714
+ "inputSchema": {
1715
+ "type": "object",
1716
+ "properties": {
1717
+ "deviceId": {
1718
+ "type": "string",
1719
+ "description": "Device Serial (Android). Defaults to connected/booted device."
1720
+ }
1721
+ },
1722
+ "allOf": [
1723
+ {
1724
+ "not": {
1725
+ "required": [
1726
+ "expectedState"
1727
+ ]
1728
+ }
1729
+ }
1730
+ ]
1731
+ }
1732
+ },
1733
+ {
1734
+ "name": "get_screen_fingerprint",
1735
+ "description": "Generate a stable fingerprint representing the current visible screen (activity + visible UI elements).\nReturns evidence metadata with acquisition intervals and conservative freshness. Optional actionRef links a known same-session/device action; unavailable references collect independently. Device log times are not comparable with host dispatch times.",
1736
+ "inputSchema": {
1737
+ "type": "object",
1738
+ "properties": {
1739
+ "platform": {
1740
+ "type": "string",
1741
+ "enum": [
1742
+ "android",
1743
+ "ios"
1744
+ ],
1745
+ "description": "Optional platform override (android|ios)"
1746
+ },
1747
+ "deviceId": {
1748
+ "type": "string",
1749
+ "description": "Optional device id/udid to target"
1750
+ },
1751
+ "actionRef": {
1752
+ "type": "object",
1753
+ "additionalProperties": false,
1754
+ "required": [
1755
+ "sessionId",
1756
+ "actionId"
1757
+ ],
1758
+ "properties": {
1759
+ "sessionId": {
1760
+ "type": "string",
1761
+ "minLength": 1,
1762
+ "maxLength": 128
1763
+ },
1764
+ "actionId": {
1765
+ "type": "string",
1766
+ "minLength": 1,
1767
+ "maxLength": 128
1768
+ }
1769
+ }
1770
+ }
1771
+ },
1772
+ "allOf": [
1773
+ {
1774
+ "not": {
1775
+ "required": [
1776
+ "expectedState"
1777
+ ]
1778
+ }
1779
+ }
1780
+ ]
1781
+ }
1782
+ },
1783
+ {
1784
+ "name": "wait_for_screen_change",
1785
+ "description": "Purpose:\nDetect that a screen transition has occurred by waiting for the current fingerprint to differ from a previous fingerprint.\n\nCapabilities:\n- Synchronization for uncertain navigation timing\n- Detection that something changed on screen\n\nConstraints:\n- Does not verify correctness of the resulting state\n- Must not be used alone to confirm action success when an applicable expect_* tool exists\n- 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\n\nRecommended Usage:\n1. Capture or define the expected outcome\n2. Call an action tool\n3. Use wait_for_screen_change when transition timing is uncertain\n4. Follow with expect_screen when the expected destination is known",
1786
+ "inputSchema": {
1787
+ "type": "object",
1788
+ "properties": {
1789
+ "platform": {
1790
+ "type": "string",
1791
+ "enum": [
1792
+ "android",
1793
+ "ios"
1794
+ ],
1795
+ "description": "Optional platform override (android|ios)"
1796
+ },
1797
+ "previousFingerprint": {
1798
+ "type": "string",
1799
+ "description": "The fingerprint to compare against (required)"
1800
+ },
1801
+ "timeoutMs": {
1802
+ "type": "number",
1803
+ "description": "Timeout in ms to wait for change (default 5000)",
1804
+ "default": 5000
1805
+ },
1806
+ "pollIntervalMs": {
1807
+ "type": "number",
1808
+ "description": "Polling interval in ms (default 300)",
1809
+ "default": 300
1810
+ },
1811
+ "deviceId": {
1812
+ "type": "string",
1813
+ "description": "Optional device id/udid to target"
1814
+ }
1815
+ },
1816
+ "required": [
1817
+ "previousFingerprint"
1818
+ ],
1819
+ "allOf": [
1820
+ {
1821
+ "not": {
1822
+ "required": [
1823
+ "expectedState"
1824
+ ]
1825
+ }
1826
+ }
1827
+ ]
1828
+ }
1829
+ },
1830
+ {
1831
+ "name": "wait_for_ui_change",
1832
+ "description": "Purpose:\nWait for a non-navigation UI mutation or in-place update to become stable.\n\nInputs:\n- expected_change (optional): hierarchy_diff, text_change, or state_change\n- timeout_ms (optional)\n- stability_window_ms (optional)\n- scope (optional): screen or subtree\n- target (optional): element_id when scope=subtree\n\nGuidance:\n- Prefer wait_for_screen_change for navigation transitions.\n- Prefer wait_for_ui_change for in-place mutations and non-navigation updates.\n- Use the returned snapshot_revision as the observed synchronization point when available.\n- Scoped waits return scope-aware stability metadata and a lightweight change summary.\n\nFailure Handling:\n- TIMEOUT means the UI did not change in a stable way within the allotted time.\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.",
1833
+ "inputSchema": {
1834
+ "type": "object",
1835
+ "properties": {
1836
+ "platform": {
1837
+ "type": "string",
1838
+ "enum": [
1839
+ "android",
1840
+ "ios"
1841
+ ],
1842
+ "description": "Optional platform override (android|ios)"
1843
+ },
1844
+ "deviceId": {
1845
+ "type": "string",
1846
+ "description": "Optional device id/udid to target"
1847
+ },
1848
+ "expected_change": {
1849
+ "type": "string",
1850
+ "enum": [
1851
+ "hierarchy_diff",
1852
+ "text_change",
1853
+ "state_change"
1854
+ ],
1855
+ "description": "Optional type of UI change to wait for"
1856
+ },
1857
+ "scope": {
1858
+ "type": "string",
1859
+ "enum": [
1860
+ "screen",
1861
+ "subtree"
1862
+ ],
1863
+ "default": "screen",
1864
+ "description": "Synchronization scope for the wait"
1865
+ },
1866
+ "target": {
1867
+ "type": "string",
1868
+ "description": "Target element_id when scope is subtree"
1869
+ },
1870
+ "timeout_ms": {
1871
+ "type": "number",
1872
+ "description": "Timeout in ms to wait for change (default 60000)",
1873
+ "default": 60000
1874
+ },
1875
+ "stability_window_ms": {
1876
+ "type": "number",
1877
+ "description": "How long the change must remain stable before success (default 300)",
1878
+ "default": 300
1879
+ },
1880
+ "requireReady": {
1881
+ "type": "boolean",
1882
+ "default": false
1883
+ }
1884
+ },
1885
+ "allOf": [
1886
+ {
1887
+ "not": {
1888
+ "required": [
1889
+ "expectedState"
1890
+ ]
1891
+ }
1892
+ }
1893
+ ]
1894
+ }
1895
+ },
1896
+ {
1897
+ "name": "expect_screen",
1898
+ "description": "Purpose:\nDeterministically verify that the intended navigation outcome of an action has occurred.\n\nInputs:\n- fingerprint: preferred exact-match screen fingerprint\n- screen: exact semantic screen identifier when a fingerprint is not available\n\nOutput Structure:\n- success: true when the expected screen matches the observed screen\n- observed_screen: current fingerprint and screen identifier\n- expected_screen: the expected fingerprint and/or screen identifier\n- confidence: 1 for an exact match, otherwise 0\n\nRecommended Usage:\n1. Define the expected screen before executing the action\n2. Resolve the target element or screen state\n3. Call an action tool such as tap_element\n4. If needed, wait for transition using wait_for_*\n5. Call expect_screen as the final verification step\n6. If success=false, treat the outcome as unverified and follow the action tool retry guidance\n\nVerification Guidance:\n- Primary and authoritative verification tool for navigation outcomes\n- Prefer fingerprint whenever you have one\n- Use screen only as a fallback exact match against known identifiers\n- Works best when the expected screen identifier is known ahead of time\n- If the expected screen is not already known, capture or define it before executing the action\n\nConstraints:\n- Returns structured binary success/failure only\n- Must not rely on natural-language interpretation or reasoning\n\nFailure Handling:\n- success=false means the expected screen was not reached; retry or recover using the action tool's failure strategy",
1899
+ "inputSchema": {
1900
+ "type": "object",
1901
+ "properties": {
1902
+ "platform": {
1903
+ "type": "string",
1904
+ "enum": [
1905
+ "android",
1906
+ "ios"
1907
+ ],
1908
+ "description": "Optional platform override (android|ios)"
1909
+ },
1910
+ "fingerprint": {
1911
+ "type": "string",
1912
+ "description": "Expected screen fingerprint. Preferred verification mechanism."
1913
+ },
1914
+ "screen": {
1915
+ "type": "string",
1916
+ "description": "Expected exact screen identifier when no fingerprint is available."
1917
+ },
1918
+ "deviceId": {
1919
+ "type": "string",
1920
+ "description": "Optional device id/udid to target"
1921
+ }
1922
+ },
1923
+ "allOf": [
1924
+ {
1925
+ "not": {
1926
+ "required": [
1927
+ "expectedState"
1928
+ ]
1929
+ }
1930
+ }
1931
+ ]
1932
+ }
1933
+ },
1934
+ {
1935
+ "name": "expect_element_visible",
1936
+ "description": "Purpose:\nDeterministically verify that the intended UI outcome of an action has occurred by confirming a target element is visible.\n\nInputs:\n- selector: required selector used to resolve the target element\n- element_id: optional previously resolved element identifier used only as context\n\nOutput Structure:\n- success: true when the element is visible\n- selector: selector used for verification\n- element_id: resolved element identifier when available\n- element: minimal resolved element info when visible\n- failure_code: TIMEOUT or UNKNOWN when verification fails\n- retryable: true when failure_code=TIMEOUT\n\nRecommended Usage:\n1. Define the expected element state before executing the action\n2. Resolve the target element or triggering control\n3. Call an action tool such as tap_element\n4. If needed, wait for UI availability using wait_for_*\n5. Call expect_element_visible as the final verification step\n6. If success=false, follow the action tool retry guidance\n\nVerification Guidance:\n- Primary and authoritative verification tool for expected element appearance or visibility\n- Use this when the screen should stay the same but the UI should reveal or update a specific element\n- selector is the primary input; element_id is an optional optimization only\n- The tool resolves the selector internally when needed\n\nConstraints:\n- Returns structured binary success/failure only\n- Must not rely on natural-language interpretation or reasoning\n\nFailure Handling:\n- TIMEOUT → retry verification once or retry the action after re-resolving\n- UNKNOWN → capture a snapshot and stop",
1937
+ "inputSchema": {
1938
+ "type": "object",
1939
+ "properties": {
1940
+ "selector": {
1941
+ "type": "object",
1942
+ "properties": {
1943
+ "text": {
1944
+ "type": "string"
1945
+ },
1946
+ "resource_id": {
1947
+ "type": "string"
1948
+ },
1949
+ "accessibility_id": {
1950
+ "type": "string"
1951
+ },
1952
+ "contains": {
1953
+ "type": "boolean",
1954
+ "default": false
1955
+ }
1956
+ }
1957
+ },
1958
+ "element_id": {
1959
+ "type": "string",
1960
+ "description": "Optional previously resolved element identifier."
1961
+ },
1962
+ "timeout_ms": {
1963
+ "type": "number",
1964
+ "default": 5000
1965
+ },
1966
+ "poll_interval_ms": {
1967
+ "type": "number",
1968
+ "default": 300
1969
+ },
1970
+ "platform": {
1971
+ "type": "string",
1972
+ "enum": [
1973
+ "android",
1974
+ "ios"
1975
+ ],
1976
+ "description": "Optional platform override"
1977
+ },
1978
+ "deviceId": {
1979
+ "type": "string",
1980
+ "description": "Optional device serial/udid"
1981
+ }
1982
+ },
1983
+ "required": [
1984
+ "selector"
1985
+ ],
1986
+ "allOf": [
1987
+ {
1988
+ "not": {
1989
+ "required": [
1990
+ "expectedState"
1991
+ ]
1992
+ }
1993
+ }
1994
+ ]
1995
+ }
1996
+ },
1997
+ {
1998
+ "name": "expect_state",
1999
+ "description": "Purpose:\nVerify a readable UI state property on the currently visible element.\n\nInputs:\n- selector or element_id\n- property\n- expected\n- platform/deviceId (optional)\n\nSupported properties:\n- checked, selected, focused, expanded, enabled, text_value, value, raw_value\n\nVerification Guidance:\n- Use this when the UI element is visible but its state must also be confirmed\n- Prefer the canonical property names above\n- The tool compares the normalized readable state and returns the observed value when available\n\nConstraints:\n- Returns structured success/failure only\n- Does not infer a state when the property is unavailable\n\nFailure Handling:\n- ELEMENT_NOT_FOUND → re-resolve the element or wait for UI stabilization\n- UNKNOWN → capture a snapshot and stop",
2000
+ "inputSchema": {
2001
+ "type": "object",
2002
+ "properties": {
2003
+ "selector": {
2004
+ "type": "object",
2005
+ "properties": {
2006
+ "text": {
2007
+ "type": "string"
2008
+ },
2009
+ "resource_id": {
2010
+ "type": "string"
2011
+ },
2012
+ "accessibility_id": {
2013
+ "type": "string"
2014
+ },
2015
+ "contains": {
2016
+ "type": "boolean",
2017
+ "default": false
2018
+ }
2019
+ }
2020
+ },
2021
+ "element_id": {
2022
+ "type": "string",
2023
+ "description": "Optional previously resolved element identifier."
2024
+ },
2025
+ "property": {
2026
+ "type": "string",
2027
+ "description": "Readable state property to verify."
2028
+ },
2029
+ "expected": {
2030
+ "description": "Expected normalized state value.",
2031
+ "oneOf": [
2032
+ {
2033
+ "type": "boolean"
2034
+ },
2035
+ {
2036
+ "type": "number"
2037
+ },
2038
+ {
2039
+ "type": "string"
2040
+ },
2041
+ {
2042
+ "type": "object"
2043
+ }
2044
+ ]
2045
+ },
2046
+ "platform": {
2047
+ "type": "string",
2048
+ "enum": [
2049
+ "android",
2050
+ "ios"
2051
+ ],
2052
+ "description": "Optional platform override"
2053
+ },
2054
+ "deviceId": {
2055
+ "type": "string",
2056
+ "description": "Optional device serial/udid"
2057
+ }
2058
+ },
2059
+ "required": [
2060
+ "property",
2061
+ "expected"
2062
+ ],
2063
+ "allOf": [
2064
+ {
2065
+ "not": {
2066
+ "required": [
2067
+ "expectedState"
2068
+ ]
2069
+ }
2070
+ }
2071
+ ]
2072
+ }
2073
+ },
2074
+ {
2075
+ "name": "adjust_control",
2076
+ "description": "Purpose:\nAdjust a numeric control value with verification.\n\nThis is the initial adjustable-control surface for slider-like controls and other controls that expose a numeric value or value_range.\n\nInputs:\n- exactly one of selector or element_id\n- property (defaults to \"value\")\n- targetValue\n- tolerance (optional; discrete default is 0, continuous default is max(step / 2, 1% of range) when omitted)\n- maxAttempts (optional; defaults to 5)\n- platform/deviceId (optional)\n\nOutput Structure:\n- action_id, timestamp (ISO 8601), action_type\n- lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n- source_module: runtime source of the action envelope\n- target_state / actual_state / within_tolerance / converged / attempts / adjustment_mode\n- target.selector = original selector or element handle\n- success = true when the control converges within tolerance\n\nVerification Guidance:\n- Prefer direct platform adjustment when the runtime exposes it; then verified increment/decrement actions; use coordinate fallback only as degraded mode\n- Use expect_state for the control value readback\n- Do not use derived semantic metadata as proof of success\n\nFailure Handling:\n- ELEMENT_NOT_FOUND → re-resolve the control\n- ELEMENT_NOT_INTERACTABLE → the control cannot be adjusted through the current runtime\n- CONTROL_CONVERGENCE_FAILED → the control did not converge within bounded retries or the requested value is out of range\n- UNKNOWN → capture a snapshot and stop",
2077
+ "inputSchema": {
2078
+ "type": "object",
2079
+ "properties": {
2080
+ "selector": {
2081
+ "type": "object",
2082
+ "properties": {
2083
+ "text": {
2084
+ "type": "string"
2085
+ },
2086
+ "resource_id": {
2087
+ "type": "string"
2088
+ },
2089
+ "accessibility_id": {
2090
+ "type": "string"
2091
+ },
2092
+ "contains": {
2093
+ "type": "boolean",
2094
+ "default": false
2095
+ }
2096
+ }
2097
+ },
2098
+ "element_id": {
2099
+ "type": "string",
2100
+ "description": "Optional previously resolved element identifier."
2101
+ },
2102
+ "property": {
2103
+ "type": "string",
2104
+ "description": "Readable numeric state property to adjust.",
2105
+ "default": "value"
2106
+ },
2107
+ "targetValue": {
2108
+ "type": "number",
2109
+ "description": "Target numeric value."
2110
+ },
2111
+ "tolerance": {
2112
+ "type": "number",
2113
+ "description": "Accepted numeric tolerance around the target value. Defaults are derived from the readable control domain."
2114
+ },
2115
+ "maxAttempts": {
2116
+ "type": "number",
2117
+ "description": "Maximum adjustment attempts.",
2118
+ "default": 5
2119
+ },
2120
+ "platform": {
2121
+ "type": "string",
2122
+ "enum": [
2123
+ "android",
2124
+ "ios"
2125
+ ],
2126
+ "description": "Optional platform override"
2127
+ },
2128
+ "deviceId": {
2129
+ "type": "string",
2130
+ "description": "Optional device serial/udid"
2131
+ }
2132
+ },
2133
+ "required": [
2134
+ "targetValue"
2135
+ ],
2136
+ "oneOf": [
2137
+ {
2138
+ "required": [
2139
+ "selector"
2140
+ ]
2141
+ },
2142
+ {
2143
+ "required": [
2144
+ "element_id"
2145
+ ]
2146
+ }
2147
+ ],
2148
+ "allOf": [
2149
+ {
2150
+ "not": {
2151
+ "required": [
2152
+ "expectedState"
2153
+ ]
2154
+ }
2155
+ }
2156
+ ]
2157
+ }
2158
+ },
2159
+ {
2160
+ "name": "wait_for_ui",
2161
+ "description": "Purpose:\nResolve elements and/or detect that a UI transition or availability condition has occurred.\n\nCapabilities:\n- Deterministic element resolution\n- Synchronization when element timing or availability is uncertain\n\nConstraints:\n- Does not verify correctness of the resulting state\n- Must not be used alone to confirm action success when an applicable expect_* tool exists\n\nRecommended Usage:\n1. Use wait_for_ui to resolve an element before acting or to wait for UI readiness\n2. Call the action tool\n3. If the expected outcome is known, follow with expect_* as final verification\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.",
2162
+ "inputSchema": {
2163
+ "type": "object",
2164
+ "properties": {
2165
+ "selector": {
2166
+ "type": "object",
2167
+ "properties": {
2168
+ "text": {
2169
+ "type": "string"
2170
+ },
2171
+ "resource_id": {
2172
+ "type": "string"
2173
+ },
2174
+ "accessibility_id": {
2175
+ "type": "string"
2176
+ },
2177
+ "contains": {
2178
+ "type": "boolean",
2179
+ "description": "When true, perform substring matching",
2180
+ "default": false
2181
+ }
2182
+ }
2183
+ },
2184
+ "condition": {
2185
+ "type": "string",
2186
+ "enum": [
2187
+ "exists",
2188
+ "not_exists",
2189
+ "visible",
2190
+ "clickable"
2191
+ ],
2192
+ "default": "exists"
2193
+ },
2194
+ "timeout_ms": {
2195
+ "type": "number",
2196
+ "default": 60000
2197
+ },
2198
+ "poll_interval_ms": {
2199
+ "type": "number",
2200
+ "default": 300
2201
+ },
2202
+ "match": {
2203
+ "type": "object",
2204
+ "properties": {
2205
+ "index": {
2206
+ "type": "number"
2207
+ }
2208
+ }
2209
+ },
2210
+ "retry": {
2211
+ "type": "object",
2212
+ "properties": {
2213
+ "max_attempts": {
2214
+ "type": "number",
2215
+ "default": 1
2216
+ },
2217
+ "backoff_ms": {
2218
+ "type": "number",
2219
+ "default": 0
2220
+ }
2221
+ }
2222
+ },
2223
+ "platform": {
2224
+ "type": "string",
2225
+ "enum": [
2226
+ "android",
2227
+ "ios"
2228
+ ],
2229
+ "description": "Optional platform override"
2230
+ },
2231
+ "deviceId": {
2232
+ "type": "string",
2233
+ "description": "Optional device serial/udid"
2234
+ },
2235
+ "requireReady": {
2236
+ "type": "boolean",
2237
+ "default": false
2238
+ }
2239
+ },
2240
+ "allOf": [
2241
+ {
2242
+ "not": {
2243
+ "required": [
2244
+ "expectedState"
2245
+ ]
2246
+ }
2247
+ }
2248
+ ]
2249
+ }
2250
+ },
2251
+ {
2252
+ "name": "find_element",
2253
+ "description": "Find a UI element by semantic query (text, content-desc, resource-id, class).\n\nReturns the best match plus resolution metadata when available, including confidence, selection reason, and fallback alternates.",
2254
+ "inputSchema": {
2255
+ "type": "object",
2256
+ "properties": {
2257
+ "query": {
2258
+ "type": "string",
2259
+ "description": "Search query (text or label)"
2260
+ },
2261
+ "exact": {
2262
+ "type": "boolean",
2263
+ "description": "Require exact match (true/false)",
2264
+ "default": false
2265
+ },
2266
+ "timeoutMs": {
2267
+ "type": "number",
2268
+ "description": "Timeout in ms to keep searching",
2269
+ "default": 3000
2270
+ },
2271
+ "platform": {
2272
+ "type": "string",
2273
+ "enum": [
2274
+ "android",
2275
+ "ios"
2276
+ ],
2277
+ "description": "Optional platform override"
2278
+ },
2279
+ "deviceId": {
2280
+ "type": "string",
2281
+ "description": "Optional device serial/udid"
2282
+ }
2283
+ },
2284
+ "required": [
2285
+ "query"
2286
+ ],
2287
+ "allOf": [
2288
+ {
2289
+ "not": {
2290
+ "required": [
2291
+ "expectedState"
2292
+ ]
2293
+ }
2294
+ }
2295
+ ]
2296
+ }
2297
+ },
2298
+ {
2299
+ "name": "tap",
2300
+ "description": "Purpose:\nDispatch a tap at specific screen coordinates.\n\nInputs:\n- x, y coordinates\n- platform (optional)\n- deviceId (optional)\n\nOutput Structure:\n - action_id, timestamp (ISO 8601), action_type\n - lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n - source_module: runtime source of the action envelope\n - target.selector = { x, y }\n- success = true when the tap was dispatched\n- failure_code/retryable when dispatch fails\n- ui_fingerprint_before/ui_fingerprint_after when available\n\nRecommended Usage:\n1. Resolve coordinates deterministically\n2. Call tap\n3. If needed, wait for transition using wait_for_*\n4. Verify with expect_screen or expect_element_visible depending on the intended outcome\n\nVerification Guidance:\n- Prefer tap_element over tap when an element can be resolved\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- Use expect_screen for navigation and expect_element_visible for local UI changes\n- Do not use wait_for_* alone as final verification when an applicable expect_* tool exists\n\nFailure Handling:\n- TIMEOUT → retry once\n- UNKNOWN → capture a snapshot and stop\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.",
2301
+ "inputSchema": {
2302
+ "type": "object",
2303
+ "properties": {
2304
+ "platform": {
2305
+ "type": "string",
2306
+ "enum": [
2307
+ "android",
2308
+ "ios"
2309
+ ],
2310
+ "description": "Platform to tap on"
2311
+ },
2312
+ "x": {
2313
+ "type": "number",
2314
+ "description": "X coordinate"
2315
+ },
2316
+ "y": {
2317
+ "type": "number",
2318
+ "description": "Y coordinate"
2319
+ },
2320
+ "deviceId": {
2321
+ "type": "string",
2322
+ "description": "Device Serial/UDID. Defaults to connected/booted device."
2323
+ },
2324
+ "verificationMode": {
2325
+ "type": "string",
2326
+ "enum": [
2327
+ "none",
2328
+ "light",
2329
+ "full"
2330
+ ],
2331
+ "default": "full"
2332
+ },
2333
+ "responseMode": {
2334
+ "type": "string",
2335
+ "enum": [
2336
+ "compact",
2337
+ "debug"
2338
+ ],
2339
+ "default": "debug"
2340
+ },
2341
+ "actionTimeoutMs": {
2342
+ "type": "integer",
2343
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
2344
+ },
2345
+ "verificationTimeoutMs": {
2346
+ "type": "integer",
2347
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
2348
+ },
2349
+ "expectedState": {
2350
+ "type": "object",
2351
+ "additionalProperties": false,
2352
+ "properties": {
2353
+ "snapshotSessionId": {
2354
+ "type": "string",
2355
+ "minLength": 1
2356
+ },
2357
+ "snapshotRevision": {
2358
+ "type": "integer",
2359
+ "minimum": 1,
2360
+ "maximum": 9007199254740991
2361
+ },
2362
+ "timeoutMs": {
2363
+ "type": "integer",
2364
+ "minimum": 100,
2365
+ "maximum": 60000,
2366
+ "default": 15000
2367
+ }
2368
+ },
2369
+ "required": [
2370
+ "snapshotSessionId",
2371
+ "snapshotRevision"
2372
+ ]
2373
+ }
2374
+ },
2375
+ "required": [
2376
+ "x",
2377
+ "y"
2378
+ ],
2379
+ "allOf": [
2380
+ {
2381
+ "if": {
2382
+ "required": [
2383
+ "expectedState"
2384
+ ]
2385
+ },
2386
+ "then": {
2387
+ "required": [
2388
+ "platform",
2389
+ "deviceId"
2390
+ ],
2391
+ "properties": {
2392
+ "platform": {
2393
+ "enum": [
2394
+ "android",
2395
+ "ios"
2396
+ ]
2397
+ },
2398
+ "deviceId": {
2399
+ "type": "string",
2400
+ "minLength": 1,
2401
+ "pattern": "\\S",
2402
+ "not": {
2403
+ "enum": [
2404
+ "booted",
2405
+ "default"
2406
+ ]
2407
+ }
2408
+ }
2409
+ }
2410
+ }
2411
+ }
2412
+ ]
2413
+ }
2414
+ },
2415
+ {
2416
+ "name": "tap_element",
2417
+ "description": "Purpose:\nTap a previously resolved UI element using its elementId.\n\nInputs:\n- elementId: a resolved UI element identifier returned by wait_for_ui\n\nOutput Structure:\n- action_id: unique timestamp-based action identifier\n- timestamp: ISO 8601 timestamp for the action attempt\n- action_type: \"tap_element\"\n- lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n- source_module: runtime source of the action envelope\n- target.selector: original target handle ({ elementId })\n- target.resolved: minimal resolved element info used for the tap\n- success: true when the tap was dispatched\n- failure_code: present when success=false\n- retryable: present when failure_code exists\n- ui_fingerprint_before/ui_fingerprint_after: optional fingerprints captured around the action\n\nRecommended Usage:\n1. Resolve the target with wait_for_ui or another deterministic resolver\n2. Call tap_element\n3. If needed, wait for transition using wait_for_*\n4. Verify outcome using expect_*\n - use expect_screen when navigation is expected\n - use expect_element_visible when the UI change is local\n5. If verification fails, inspect failure_code and follow the retry strategy below\n\nVerification Guidance:\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- Prefer expect_screen for navigation or modal transitions\n- Prefer expect_element_visible when the tap should reveal or update a specific element\n- wait_for_* may be used for resolution and synchronization, but not as the final verification step when an applicable expect_* tool exists\n- Do not treat tap_element.success as outcome success; it only means the tap was executed\n\nFailure Handling:\n- STALE_REFERENCE → re-resolve the element, then retry\n- ELEMENT_NOT_INTERACTABLE → wait or refine the target, then retry\n- UNKNOWN → capture a snapshot and stop\n\nThis tool reports execution success only. Verification must be done with a separate expect_* tool.\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.",
2418
+ "inputSchema": {
2419
+ "type": "object",
2420
+ "properties": {
2421
+ "elementId": {
2422
+ "type": "string",
2423
+ "description": "A unique element identifier returned by wait_for_ui"
2424
+ },
2425
+ "selector": {
2426
+ "type": "object",
2427
+ "properties": {
2428
+ "text": {
2429
+ "type": "string"
2430
+ },
2431
+ "resource_id": {
2432
+ "type": "string"
2433
+ },
2434
+ "accessibility_id": {
2435
+ "type": "string"
2436
+ },
2437
+ "contains": {
2438
+ "type": "boolean"
2439
+ }
2440
+ }
2441
+ },
2442
+ "waitFor": {
2443
+ "type": "object",
2444
+ "properties": {
2445
+ "condition": {
2446
+ "type": "string",
2447
+ "enum": [
2448
+ "exists",
2449
+ "visible",
2450
+ "clickable"
2451
+ ]
2452
+ },
2453
+ "timeoutMs": {
2454
+ "type": "number",
2455
+ "minimum": 100,
2456
+ "maximum": 10000
2457
+ },
2458
+ "pollIntervalMs": {
2459
+ "type": "number",
2460
+ "minimum": 50,
2461
+ "maximum": 1000
2462
+ },
2463
+ "match": {
2464
+ "type": "object",
2465
+ "properties": {
2466
+ "index": {
2467
+ "type": "number"
2468
+ }
2469
+ }
2470
+ }
2471
+ }
2472
+ },
2473
+ "platform": {
2474
+ "type": "string",
2475
+ "enum": [
2476
+ "android",
2477
+ "ios"
2478
+ ]
2479
+ },
2480
+ "deviceId": {
2481
+ "type": "string"
2482
+ },
2483
+ "verificationMode": {
2484
+ "type": "string",
2485
+ "enum": [
2486
+ "none",
2487
+ "light",
2488
+ "full"
2489
+ ],
2490
+ "default": "full"
2491
+ },
2492
+ "responseMode": {
2493
+ "type": "string",
2494
+ "enum": [
2495
+ "compact",
2496
+ "debug"
2497
+ ],
2498
+ "default": "debug"
2499
+ },
2500
+ "expectedState": {
2501
+ "type": "object",
2502
+ "additionalProperties": false,
2503
+ "properties": {
2504
+ "snapshotSessionId": {
2505
+ "type": "string",
2506
+ "minLength": 1
2507
+ },
2508
+ "snapshotRevision": {
2509
+ "type": "integer",
2510
+ "minimum": 1,
2511
+ "maximum": 9007199254740991
2512
+ },
2513
+ "timeoutMs": {
2514
+ "type": "integer",
2515
+ "minimum": 100,
2516
+ "maximum": 60000,
2517
+ "default": 15000
2518
+ }
2519
+ },
2520
+ "required": [
2521
+ "snapshotSessionId",
2522
+ "snapshotRevision"
2523
+ ]
2524
+ },
2525
+ "actionTimeoutMs": {
2526
+ "type": "integer",
2527
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
2528
+ },
2529
+ "verificationTimeoutMs": {
2530
+ "type": "integer",
2531
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
2532
+ }
2533
+ },
2534
+ "allOf": [
2535
+ {
2536
+ "if": {
2537
+ "required": [
2538
+ "expectedState"
2539
+ ]
2540
+ },
2541
+ "then": {
2542
+ "required": [
2543
+ "platform",
2544
+ "deviceId"
2545
+ ],
2546
+ "properties": {
2547
+ "platform": {
2548
+ "enum": [
2549
+ "android",
2550
+ "ios"
2551
+ ]
2552
+ },
2553
+ "deviceId": {
2554
+ "type": "string",
2555
+ "minLength": 1,
2556
+ "pattern": "\\S",
2557
+ "not": {
2558
+ "enum": [
2559
+ "booted",
2560
+ "default"
2561
+ ]
2562
+ }
2563
+ }
2564
+ }
2565
+ }
2566
+ }
2567
+ ],
2568
+ "oneOf": [
2569
+ {
2570
+ "required": [
2571
+ "elementId"
2572
+ ],
2573
+ "not": {
2574
+ "required": [
2575
+ "selector"
2576
+ ]
2577
+ }
2578
+ },
2579
+ {
2580
+ "required": [
2581
+ "selector"
2582
+ ],
2583
+ "not": {
2584
+ "required": [
2585
+ "elementId"
2586
+ ]
2587
+ }
2588
+ }
2589
+ ]
2590
+ }
2591
+ },
2592
+ {
2593
+ "name": "swipe",
2594
+ "description": "Purpose:\nDispatch a swipe gesture on Android or iOS.\n\nInputs:\n- start and end coordinates\n- duration\n- platform/deviceId (optional)\n\nOutput Structure:\n- action_id, timestamp (ISO 8601), action_type\n- lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n- source_module: runtime source of the action envelope\n- target.selector = { x1, y1, x2, y2, duration }\n- success = true when the swipe was dispatched\n- failure_code/retryable when dispatch fails\n- ui_fingerprint_before/ui_fingerprint_after when available\n\nRecommended Usage:\n1. Determine swipe coordinates\n2. Call swipe\n3. If needed, wait for transition using wait_for_*\n4. Verify with expect_screen or expect_element_visible when a deterministic outcome is expected\n\nVerification Guidance:\n- Swipe outcomes are less predictable; choose the most specific verifier available for the intended effect\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- Do not use wait_for_* alone as final verification when an applicable expect_* tool exists\n\nFailure Handling:\n- TIMEOUT → retry once\n- UNKNOWN → capture a snapshot and stop\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.",
2595
+ "inputSchema": {
2596
+ "type": "object",
2597
+ "properties": {
2598
+ "platform": {
2599
+ "type": "string",
2600
+ "enum": [
2601
+ "android",
2602
+ "ios"
2603
+ ],
2604
+ "description": "Platform to swipe on (android or ios)"
2605
+ },
2606
+ "x1": {
2607
+ "type": "number",
2608
+ "description": "Start X coordinate"
2609
+ },
2610
+ "y1": {
2611
+ "type": "number",
2612
+ "description": "Start Y coordinate"
2613
+ },
2614
+ "x2": {
2615
+ "type": "number",
2616
+ "description": "End X coordinate"
2617
+ },
2618
+ "y2": {
2619
+ "type": "number",
2620
+ "description": "End Y coordinate"
2621
+ },
2622
+ "duration": {
2623
+ "type": "number",
2624
+ "description": "Duration in ms"
2625
+ },
2626
+ "deviceId": {
2627
+ "type": "string",
2628
+ "description": "Device Serial/UDID. Defaults to connected/booted device."
2629
+ },
2630
+ "expectedState": {
2631
+ "type": "object",
2632
+ "additionalProperties": false,
2633
+ "properties": {
2634
+ "snapshotSessionId": {
2635
+ "type": "string",
2636
+ "minLength": 1
2637
+ },
2638
+ "snapshotRevision": {
2639
+ "type": "integer",
2640
+ "minimum": 1,
2641
+ "maximum": 9007199254740991
2642
+ },
2643
+ "timeoutMs": {
2644
+ "type": "integer",
2645
+ "minimum": 100,
2646
+ "maximum": 60000,
2647
+ "default": 15000
2648
+ }
2649
+ },
2650
+ "required": [
2651
+ "snapshotSessionId",
2652
+ "snapshotRevision"
2653
+ ]
2654
+ },
2655
+ "verificationMode": {
2656
+ "type": "string",
2657
+ "enum": [
2658
+ "none",
2659
+ "light",
2660
+ "full"
2661
+ ],
2662
+ "default": "full"
2663
+ },
2664
+ "responseMode": {
2665
+ "type": "string",
2666
+ "enum": [
2667
+ "compact",
2668
+ "debug"
2669
+ ],
2670
+ "default": "debug"
2671
+ },
2672
+ "actionTimeoutMs": {
2673
+ "type": "integer",
2674
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
2675
+ },
2676
+ "verificationTimeoutMs": {
2677
+ "type": "integer",
2678
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
2679
+ }
2680
+ },
2681
+ "required": [
2682
+ "x1",
2683
+ "y1",
2684
+ "x2",
2685
+ "y2",
2686
+ "duration"
2687
+ ],
2688
+ "allOf": [
2689
+ {
2690
+ "if": {
2691
+ "required": [
2692
+ "expectedState"
2693
+ ]
2694
+ },
2695
+ "then": {
2696
+ "required": [
2697
+ "platform",
2698
+ "deviceId"
2699
+ ],
2700
+ "properties": {
2701
+ "platform": {
2702
+ "enum": [
2703
+ "android",
2704
+ "ios"
2705
+ ]
2706
+ },
2707
+ "deviceId": {
2708
+ "type": "string",
2709
+ "minLength": 1,
2710
+ "pattern": "\\S",
2711
+ "not": {
2712
+ "enum": [
2713
+ "booted",
2714
+ "default"
2715
+ ]
2716
+ }
2717
+ }
2718
+ }
2719
+ }
2720
+ }
2721
+ ]
2722
+ }
2723
+ },
2724
+ {
2725
+ "name": "scroll_to_element",
2726
+ "description": "Purpose:\nScroll until a target element becomes visible.\n\nInputs:\n- platform\n- selector\n- direction, maxScrolls, scrollAmount, deviceId (optional)\n\nOutput Structure:\n- action_id, timestamp (ISO 8601), action_type\n- lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n- source_module: runtime source of the action envelope\n- target.selector = original selector\n- target.resolved = minimal resolved element info when found\n- success = true when scrolling produced a visible target element\n- failure_code/retryable when the target was not reached\n- ui_fingerprint_before/ui_fingerprint_after when available\n\nRecommended Usage:\n1. Resolve the target selector\n2. Call scroll_to_element\n3. If needed, wait for UI stabilization using wait_for_*\n4. Verify with expect_element_visible when the expected element visibility is known\n5. If success=false, follow failure handling before retrying\n\nVerification Guidance:\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- Use expect_element_visible when you need an explicit post-scroll confirmation\n- Do not use wait_for_* alone as final verification when an applicable expect_* tool exists\n\nFailure Handling:\n- NAVIGATION_NO_CHANGE → adjust scroll direction or stop\n- TIMEOUT → retry with refined selector or larger scroll budget\n- UNKNOWN → capture a snapshot and stop",
2727
+ "inputSchema": {
2728
+ "type": "object",
2729
+ "properties": {
2730
+ "platform": {
2731
+ "type": "string",
2732
+ "enum": [
2733
+ "android",
2734
+ "ios"
2735
+ ],
2736
+ "description": "Platform to operate on (required)"
2737
+ },
2738
+ "selector": {
2739
+ "type": "object",
2740
+ "properties": {
2741
+ "text": {
2742
+ "type": "string"
2743
+ },
2744
+ "resourceId": {
2745
+ "type": "string"
2746
+ },
2747
+ "contentDesc": {
2748
+ "type": "string"
2749
+ },
2750
+ "className": {
2751
+ "type": "string"
2752
+ }
2753
+ }
2754
+ },
2755
+ "direction": {
2756
+ "type": "string",
2757
+ "enum": [
2758
+ "down",
2759
+ "up"
2760
+ ],
2761
+ "default": "down"
2762
+ },
2763
+ "maxScrolls": {
2764
+ "type": "number",
2765
+ "default": 10
2766
+ },
2767
+ "scrollAmount": {
2768
+ "type": "number",
2769
+ "default": 0.7
2770
+ },
2771
+ "deviceId": {
2772
+ "type": "string",
2773
+ "description": "Device UDID (iOS) or Serial (Android). Defaults to booted/connected."
2774
+ },
2775
+ "verificationMode": {
2776
+ "type": "string",
2777
+ "enum": [
2778
+ "none",
2779
+ "light",
2780
+ "full"
2781
+ ],
2782
+ "default": "full"
2783
+ },
2784
+ "responseMode": {
2785
+ "type": "string",
2786
+ "enum": [
2787
+ "compact",
2788
+ "debug"
2789
+ ],
2790
+ "default": "debug"
2791
+ },
2792
+ "actionTimeoutMs": {
2793
+ "type": "integer",
2794
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
2795
+ },
2796
+ "verificationTimeoutMs": {
2797
+ "type": "integer",
2798
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
2799
+ }
2800
+ },
2801
+ "required": [
2802
+ "platform",
2803
+ "selector"
2804
+ ],
2805
+ "allOf": [
2806
+ {
2807
+ "not": {
2808
+ "required": [
2809
+ "expectedState"
2810
+ ]
2811
+ }
2812
+ }
2813
+ ]
2814
+ }
2815
+ },
2816
+ {
2817
+ "name": "type_text",
2818
+ "description": "Purpose:\nType text into the currently focused Android input field.\n\nInputs:\n- text\n- platform/deviceId (optional)\n\nOutput Structure:\n- action_id, timestamp (ISO 8601), action_type\n- lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n- source_module: runtime source of the action envelope\n- target.selector = { text }\n- success = true when text input was dispatched\n- failure_code/retryable when dispatch fails\n- ui_fingerprint_before/ui_fingerprint_after when available\n\nRecommended Usage:\n1. Resolve or focus the target input first\n2. Call type_text\n3. If needed, wait for UI stabilization using wait_for_*\n4. Verify with expect_element_visible or expect_screen, depending on the intended outcome\n\nVerification Guidance:\n- Prefer verifying the next expected element or screen state instead of inferring success from the text action alone\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- Do not use wait_for_* alone as final verification when an applicable expect_* tool exists\n\nFailure Handling:\n- TIMEOUT → retry once\n- UNKNOWN → re-focus the input or capture a snapshot\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.",
2819
+ "inputSchema": {
2820
+ "type": "object",
2821
+ "properties": {
2822
+ "platform": {
2823
+ "type": "string",
2824
+ "enum": [
2825
+ "android"
2826
+ ],
2827
+ "description": "Platform to type on (currently only android supported)"
2828
+ },
2829
+ "text": {
2830
+ "type": "string",
2831
+ "description": "The text to type"
2832
+ },
2833
+ "deviceId": {
2834
+ "type": "string",
2835
+ "description": "Device Serial/UDID. Defaults to connected/booted device."
2836
+ },
2837
+ "expectedState": {
2838
+ "type": "object",
2839
+ "additionalProperties": false,
2840
+ "properties": {
2841
+ "snapshotSessionId": {
2842
+ "type": "string",
2843
+ "minLength": 1
2844
+ },
2845
+ "snapshotRevision": {
2846
+ "type": "integer",
2847
+ "minimum": 1,
2848
+ "maximum": 9007199254740991
2849
+ },
2850
+ "timeoutMs": {
2851
+ "type": "integer",
2852
+ "minimum": 100,
2853
+ "maximum": 60000,
2854
+ "default": 15000
2855
+ }
2856
+ },
2857
+ "required": [
2858
+ "snapshotSessionId",
2859
+ "snapshotRevision"
2860
+ ]
2861
+ },
2862
+ "verificationMode": {
2863
+ "type": "string",
2864
+ "enum": [
2865
+ "none",
2866
+ "light",
2867
+ "full"
2868
+ ],
2869
+ "default": "full"
2870
+ },
2871
+ "responseMode": {
2872
+ "type": "string",
2873
+ "enum": [
2874
+ "compact",
2875
+ "debug"
2876
+ ],
2877
+ "default": "debug"
2878
+ },
2879
+ "actionTimeoutMs": {
2880
+ "type": "integer",
2881
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
2882
+ },
2883
+ "verificationTimeoutMs": {
2884
+ "type": "integer",
2885
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
2886
+ }
2887
+ },
2888
+ "required": [
2889
+ "text"
2890
+ ],
2891
+ "allOf": [
2892
+ {
2893
+ "if": {
2894
+ "required": [
2895
+ "expectedState"
2896
+ ]
2897
+ },
2898
+ "then": {
2899
+ "required": [
2900
+ "platform",
2901
+ "deviceId"
2902
+ ],
2903
+ "properties": {
2904
+ "platform": {
2905
+ "enum": [
2906
+ "android"
2907
+ ]
2908
+ },
2909
+ "deviceId": {
2910
+ "type": "string",
2911
+ "minLength": 1,
2912
+ "pattern": "\\S",
2913
+ "not": {
2914
+ "enum": [
2915
+ "booted",
2916
+ "default"
2917
+ ]
2918
+ }
2919
+ }
2920
+ }
2921
+ }
2922
+ }
2923
+ ]
2924
+ }
2925
+ },
2926
+ {
2927
+ "name": "press_back",
2928
+ "description": "Purpose:\nDispatch the Android Back action.\n\nInputs:\n- platform/deviceId (optional)\n\nOutput Structure:\n- action_id, timestamp (ISO 8601), action_type\n- lifecycle_state: post-dispatch lifecycle state (pending_verification or failed)\n- source_module: runtime source of the action envelope\n- target.selector = { key: \"back\" }\n- success = true when the back action was dispatched\n- failure_code/retryable when dispatch fails\n- ui_fingerprint_before/ui_fingerprint_after when available\n\nRecommended Usage:\n1. Call press_back\n2. If needed, wait for transition using wait_for_*\n3. Verify with expect_screen when a known destination is expected\n4. If verification fails, retry once or recover explicitly\n\nVerification Guidance:\n- Back outcomes can vary by screen, so verify against the intended destination when possible\n- Follow RESOLVE → ACT → WAIT (if needed) → EXPECT\n- Do not use wait_for_* alone as final verification when an applicable expect_* tool exists\n\nFailure Handling:\n- TIMEOUT → retry once\n- UNKNOWN → capture a snapshot and stop\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.",
2929
+ "inputSchema": {
2930
+ "type": "object",
2931
+ "properties": {
2932
+ "platform": {
2933
+ "type": "string",
2934
+ "enum": [
2935
+ "android"
2936
+ ],
2937
+ "description": "Platform (currently only android supported)"
2938
+ },
2939
+ "deviceId": {
2940
+ "type": "string",
2941
+ "description": "Device Serial/UDID. Defaults to connected/booted device."
2942
+ },
2943
+ "expectedState": {
2944
+ "type": "object",
2945
+ "additionalProperties": false,
2946
+ "properties": {
2947
+ "snapshotSessionId": {
2948
+ "type": "string",
2949
+ "minLength": 1
2950
+ },
2951
+ "snapshotRevision": {
2952
+ "type": "integer",
2953
+ "minimum": 1,
2954
+ "maximum": 9007199254740991
2955
+ },
2956
+ "timeoutMs": {
2957
+ "type": "integer",
2958
+ "minimum": 100,
2959
+ "maximum": 60000,
2960
+ "default": 15000
2961
+ }
2962
+ },
2963
+ "required": [
2964
+ "snapshotSessionId",
2965
+ "snapshotRevision"
2966
+ ]
2967
+ },
2968
+ "verificationMode": {
2969
+ "type": "string",
2970
+ "enum": [
2971
+ "none",
2972
+ "light",
2973
+ "full"
2974
+ ],
2975
+ "default": "full"
2976
+ },
2977
+ "responseMode": {
2978
+ "type": "string",
2979
+ "enum": [
2980
+ "compact",
2981
+ "debug"
2982
+ ],
2983
+ "default": "debug"
2984
+ },
2985
+ "actionTimeoutMs": {
2986
+ "type": "integer",
2987
+ "description": "Dispatch budget in milliseconds, clamped to 100–30000."
2988
+ },
2989
+ "verificationTimeoutMs": {
2990
+ "type": "integer",
2991
+ "description": "Light observation budget in milliseconds, clamped to 100–60000."
2992
+ }
2993
+ },
2994
+ "allOf": [
2995
+ {
2996
+ "if": {
2997
+ "required": [
2998
+ "expectedState"
2999
+ ]
3000
+ },
3001
+ "then": {
3002
+ "required": [
3003
+ "platform",
3004
+ "deviceId"
3005
+ ],
3006
+ "properties": {
3007
+ "platform": {
3008
+ "enum": [
3009
+ "android"
3010
+ ]
3011
+ },
3012
+ "deviceId": {
3013
+ "type": "string",
3014
+ "minLength": 1,
3015
+ "pattern": "\\S",
3016
+ "not": {
3017
+ "enum": [
3018
+ "booted",
3019
+ "default"
3020
+ ]
3021
+ }
3022
+ }
3023
+ }
3024
+ }
3025
+ }
3026
+ ]
3027
+ }
3028
+ },
3029
+ {
3030
+ "name": "classify_action_outcome",
3031
+ "description": "Classify the outcome of the most recent action into exactly one of: success, no_op, backend_failure, ui_failure, unknown.\n\nUse the runtime action result's `action_type` as `actionType` so the classifier can distinguish local-state actions from side-effect actions.\nUse this when the intended outcome is not already fully verified by the UI signal alone.\nFor 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.\n\nHOW TO GATHER INPUTS before calling:\n1. Call wait_for_screen_change or compare get_screen_fingerprint before/after — set uiChanged accordingly.\n2. If you checked for a specific element with wait_for_ui, set expectedElementVisible.\n3. Pass actionType from the action response when available.\n4. Only provide networkRequests if you already collected them or want to classify a side-effect action with backend evidence.\n\nRULES (applied in order — stop at first match):\n1. If uiChanged=true OR expectedElementVisible=true → outcome=success\n2. If actionType is missing → outcome=unknown\n3. If any request has status=failure or retryable → outcome=backend_failure\n4. If actionType maps to a local-state action → outcome=no_op; prefer state-based verification and avoid default network fallback\n5. If actionType maps to a side-effect action and no networkRequests were supplied → outcome=unknown\n6. If no requests returned → outcome=no_op\n7. If all requests succeeded → outcome=ui_failure\n8. Otherwise → outcome=unknown\n\nBEHAVIOUR after outcome:\n- success → continue\n- no_op → retry with richer state verification or re-resolve the element\n- backend_failure → stop and report the failing endpoint\n- ui_failure → stop and report failure\n- unknown → take one recovery step (e.g. capture_debug_snapshot), then stop",
3032
+ "inputSchema": {
3033
+ "type": "object",
3034
+ "properties": {
3035
+ "uiChanged": {
3036
+ "type": "boolean",
3037
+ "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."
3038
+ },
3039
+ "expectedElementVisible": {
3040
+ "type": "boolean",
3041
+ "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."
3042
+ },
3043
+ "actionType": {
3044
+ "type": "string",
3045
+ "description": "The runtime action_type from the action response (for example tap, tap_element, swipe, type_text, press_back, start_app)."
3046
+ },
3047
+ "networkRequests": {
3048
+ "type": "array",
3049
+ "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.",
3050
+ "items": {
3051
+ "type": "object",
3052
+ "properties": {
3053
+ "endpoint": {
3054
+ "type": "string",
3055
+ "description": "Request endpoint or full URL"
3056
+ },
3057
+ "status": {
3058
+ "type": "string",
3059
+ "enum": [
3060
+ "success",
3061
+ "failure",
3062
+ "retryable"
3063
+ ],
3064
+ "description": "Outcome of the request"
3065
+ }
3066
+ },
3067
+ "required": [
3068
+ "endpoint",
3069
+ "status"
3070
+ ]
3071
+ }
3072
+ },
3073
+ "hasLogErrors": {
3074
+ "type": "boolean",
3075
+ "description": "true if structured log errors were observed (e.g. from read_log_stream). Optional — include if you have already read logs."
3076
+ }
3077
+ },
3078
+ "required": [
3079
+ "uiChanged"
3080
+ ],
3081
+ "allOf": [
3082
+ {
3083
+ "not": {
3084
+ "required": [
3085
+ "expectedState"
3086
+ ]
3087
+ }
3088
+ }
3089
+ ]
3090
+ }
3091
+ },
3092
+ {
3093
+ "name": "run_journey",
3094
+ "description": "Run an ordered, bounded sequence of start_app, tap, wait, and deterministic assertion steps against one device. Stops after the first failed step.\nTap steps may include expectedState from a successful same-device get_ui_tree. A failed condition blocks that input, retains fresh condition evidence even in compact mode, and stops subsequent steps. Conditions are not journey defaults or supported on other step types.",
3095
+ "inputSchema": {
3096
+ "type": "object",
3097
+ "properties": {
3098
+ "platform": {
3099
+ "type": "string",
3100
+ "enum": [
3101
+ "android",
3102
+ "ios"
3103
+ ]
3104
+ },
3105
+ "deviceId": {
3106
+ "type": "string"
3107
+ },
3108
+ "responseMode": {
3109
+ "type": "string",
3110
+ "enum": [
3111
+ "compact",
3112
+ "debug"
3113
+ ],
3114
+ "default": "compact"
3115
+ },
3116
+ "steps": {
3117
+ "type": "array",
3118
+ "minItems": 1,
3119
+ "maxItems": 50,
3120
+ "items": {
3121
+ "oneOf": [
3122
+ {
3123
+ "type": "object",
3124
+ "additionalProperties": false,
3125
+ "properties": {
3126
+ "id": {
3127
+ "type": "string",
3128
+ "minLength": 1
3129
+ },
3130
+ "type": {
3131
+ "const": "start_app"
3132
+ },
3133
+ "appId": {
3134
+ "type": "string",
3135
+ "minLength": 1
3136
+ },
3137
+ "verificationMode": {
3138
+ "type": "string",
3139
+ "enum": [
3140
+ "none",
3141
+ "light",
3142
+ "full"
3143
+ ]
3144
+ }
3145
+ },
3146
+ "required": [
3147
+ "id",
3148
+ "type",
3149
+ "appId"
3150
+ ]
3151
+ },
3152
+ {
3153
+ "type": "object",
3154
+ "additionalProperties": false,
3155
+ "properties": {
3156
+ "id": {
3157
+ "type": "string",
3158
+ "minLength": 1
3159
+ },
3160
+ "type": {
3161
+ "const": "tap"
3162
+ },
3163
+ "selector": {
3164
+ "type": "object",
3165
+ "additionalProperties": false,
3166
+ "properties": {
3167
+ "text": {
3168
+ "type": "string",
3169
+ "minLength": 1
3170
+ },
3171
+ "resource_id": {
3172
+ "type": "string",
3173
+ "minLength": 1
3174
+ },
3175
+ "accessibility_id": {
3176
+ "type": "string",
3177
+ "minLength": 1
3178
+ },
3179
+ "contains": {
3180
+ "type": "boolean"
3181
+ }
3182
+ },
3183
+ "anyOf": [
3184
+ {
3185
+ "required": [
3186
+ "text"
3187
+ ]
3188
+ },
3189
+ {
3190
+ "required": [
3191
+ "resource_id"
3192
+ ]
3193
+ },
3194
+ {
3195
+ "required": [
3196
+ "accessibility_id"
3197
+ ]
3198
+ }
3199
+ ]
3200
+ },
3201
+ "elementId": {
3202
+ "type": "string",
3203
+ "minLength": 1
3204
+ },
3205
+ "verificationMode": {
3206
+ "type": "string",
3207
+ "enum": [
3208
+ "none",
3209
+ "light",
3210
+ "full"
3211
+ ]
3212
+ },
3213
+ "expectedState": {
3214
+ "type": "object",
3215
+ "additionalProperties": false,
3216
+ "properties": {
3217
+ "snapshotSessionId": {
3218
+ "type": "string",
3219
+ "minLength": 1
3220
+ },
3221
+ "snapshotRevision": {
3222
+ "type": "integer",
3223
+ "minimum": 1,
3224
+ "maximum": 9007199254740991
3225
+ },
3226
+ "timeoutMs": {
3227
+ "type": "integer",
3228
+ "minimum": 100,
3229
+ "maximum": 60000,
3230
+ "default": 15000
3231
+ }
3232
+ },
3233
+ "required": [
3234
+ "snapshotSessionId",
3235
+ "snapshotRevision"
3236
+ ]
3237
+ },
3238
+ "waitFor": {
3239
+ "type": "object",
3240
+ "additionalProperties": false,
3241
+ "properties": {
3242
+ "timeoutMs": {
3243
+ "type": "integer",
3244
+ "minimum": 100,
3245
+ "maximum": 10000
3246
+ },
3247
+ "pollIntervalMs": {
3248
+ "type": "integer",
3249
+ "minimum": 50,
3250
+ "maximum": 1000
3251
+ },
3252
+ "condition": {
3253
+ "enum": [
3254
+ "exists",
3255
+ "visible",
3256
+ "clickable"
3257
+ ]
3258
+ },
3259
+ "match": {
3260
+ "type": "object",
3261
+ "additionalProperties": false,
3262
+ "properties": {
3263
+ "index": {
3264
+ "type": "integer",
3265
+ "minimum": 0
3266
+ }
3267
+ },
3268
+ "required": []
3269
+ }
3270
+ },
3271
+ "required": []
3272
+ }
3273
+ },
3274
+ "required": [
3275
+ "id",
3276
+ "type"
3277
+ ],
3278
+ "oneOf": [
3279
+ {
3280
+ "required": [
3281
+ "selector"
3282
+ ],
3283
+ "not": {
3284
+ "required": [
3285
+ "elementId"
3286
+ ]
3287
+ }
3288
+ },
3289
+ {
3290
+ "required": [
3291
+ "elementId"
3292
+ ],
3293
+ "not": {
3294
+ "required": [
3295
+ "selector"
3296
+ ]
3297
+ }
3298
+ }
3299
+ ]
3300
+ },
3301
+ {
3302
+ "type": "object",
3303
+ "additionalProperties": false,
3304
+ "properties": {
3305
+ "id": {
3306
+ "type": "string",
3307
+ "minLength": 1
3308
+ },
3309
+ "type": {
3310
+ "const": "wait"
3311
+ },
3312
+ "selector": {
3313
+ "type": "object",
3314
+ "additionalProperties": false,
3315
+ "properties": {
3316
+ "text": {
3317
+ "type": "string",
3318
+ "minLength": 1
3319
+ },
3320
+ "resource_id": {
3321
+ "type": "string",
3322
+ "minLength": 1
3323
+ },
3324
+ "accessibility_id": {
3325
+ "type": "string",
3326
+ "minLength": 1
3327
+ },
3328
+ "contains": {
3329
+ "type": "boolean"
3330
+ }
3331
+ },
3332
+ "anyOf": [
3333
+ {
3334
+ "required": [
3335
+ "text"
3336
+ ]
3337
+ },
3338
+ {
3339
+ "required": [
3340
+ "resource_id"
3341
+ ]
3342
+ },
3343
+ {
3344
+ "required": [
3345
+ "accessibility_id"
3346
+ ]
3347
+ }
3348
+ ]
3349
+ },
3350
+ "condition": {
3351
+ "enum": [
3352
+ "exists",
3353
+ "not_exists",
3354
+ "visible",
3355
+ "clickable"
3356
+ ]
3357
+ },
3358
+ "timeoutMs": {
3359
+ "type": "integer",
3360
+ "minimum": 100,
3361
+ "maximum": 60000
3362
+ },
3363
+ "pollIntervalMs": {
3364
+ "type": "integer",
3365
+ "minimum": 50,
3366
+ "maximum": 1000
3367
+ }
3368
+ },
3369
+ "required": [
3370
+ "id",
3371
+ "type",
3372
+ "selector"
3373
+ ]
3374
+ },
3375
+ {
3376
+ "type": "object",
3377
+ "additionalProperties": false,
3378
+ "properties": {
3379
+ "id": {
3380
+ "type": "string",
3381
+ "minLength": 1
3382
+ },
3383
+ "type": {
3384
+ "const": "assert"
3385
+ },
3386
+ "timeoutMs": {
3387
+ "type": "integer",
3388
+ "minimum": 100,
3389
+ "maximum": 60000
3390
+ },
3391
+ "pollIntervalMs": {
3392
+ "type": "integer",
3393
+ "minimum": 50,
3394
+ "maximum": 1000
3395
+ },
3396
+ "assertion": {
3397
+ "oneOf": [
3398
+ {
3399
+ "type": "object",
3400
+ "additionalProperties": false,
3401
+ "properties": {
3402
+ "kind": {
3403
+ "const": "element_visible"
3404
+ },
3405
+ "selector": {
3406
+ "type": "object",
3407
+ "additionalProperties": false,
3408
+ "properties": {
3409
+ "text": {
3410
+ "type": "string",
3411
+ "minLength": 1
3412
+ },
3413
+ "resource_id": {
3414
+ "type": "string",
3415
+ "minLength": 1
3416
+ },
3417
+ "accessibility_id": {
3418
+ "type": "string",
3419
+ "minLength": 1
3420
+ },
3421
+ "contains": {
3422
+ "type": "boolean"
3423
+ }
3424
+ },
3425
+ "anyOf": [
3426
+ {
3427
+ "required": [
3428
+ "text"
3429
+ ]
3430
+ },
3431
+ {
3432
+ "required": [
3433
+ "resource_id"
3434
+ ]
3435
+ },
3436
+ {
3437
+ "required": [
3438
+ "accessibility_id"
3439
+ ]
3440
+ }
3441
+ ]
3442
+ }
3443
+ },
3444
+ "required": [
3445
+ "kind",
3446
+ "selector"
3447
+ ]
3448
+ },
3449
+ {
3450
+ "type": "object",
3451
+ "additionalProperties": false,
3452
+ "properties": {
3453
+ "kind": {
3454
+ "const": "element_absent"
3455
+ },
3456
+ "selector": {
3457
+ "type": "object",
3458
+ "additionalProperties": false,
3459
+ "properties": {
3460
+ "text": {
3461
+ "type": "string",
3462
+ "minLength": 1
3463
+ },
3464
+ "resource_id": {
3465
+ "type": "string",
3466
+ "minLength": 1
3467
+ },
3468
+ "accessibility_id": {
3469
+ "type": "string",
3470
+ "minLength": 1
3471
+ },
3472
+ "contains": {
3473
+ "type": "boolean"
3474
+ }
3475
+ },
3476
+ "anyOf": [
3477
+ {
3478
+ "required": [
3479
+ "text"
3480
+ ]
3481
+ },
3482
+ {
3483
+ "required": [
3484
+ "resource_id"
3485
+ ]
3486
+ },
3487
+ {
3488
+ "required": [
3489
+ "accessibility_id"
3490
+ ]
3491
+ }
3492
+ ]
3493
+ }
3494
+ },
3495
+ "required": [
3496
+ "kind",
3497
+ "selector"
3498
+ ]
3499
+ },
3500
+ {
3501
+ "type": "object",
3502
+ "additionalProperties": false,
3503
+ "properties": {
3504
+ "kind": {
3505
+ "const": "screen_fingerprint"
3506
+ },
3507
+ "fingerprint": {
3508
+ "type": "string",
3509
+ "minLength": 1
3510
+ }
3511
+ },
3512
+ "required": [
3513
+ "kind",
3514
+ "fingerprint"
3515
+ ]
3516
+ },
3517
+ {
3518
+ "type": "object",
3519
+ "additionalProperties": false,
3520
+ "properties": {
3521
+ "kind": {
3522
+ "const": "state_equals"
3523
+ },
3524
+ "selector": {
3525
+ "type": "object",
3526
+ "additionalProperties": false,
3527
+ "properties": {
3528
+ "text": {
3529
+ "type": "string",
3530
+ "minLength": 1
3531
+ },
3532
+ "resource_id": {
3533
+ "type": "string",
3534
+ "minLength": 1
3535
+ },
3536
+ "accessibility_id": {
3537
+ "type": "string",
3538
+ "minLength": 1
3539
+ },
3540
+ "contains": {
3541
+ "type": "boolean"
3542
+ }
3543
+ },
3544
+ "anyOf": [
3545
+ {
3546
+ "required": [
3547
+ "text"
3548
+ ]
3549
+ },
3550
+ {
3551
+ "required": [
3552
+ "resource_id"
3553
+ ]
3554
+ },
3555
+ {
3556
+ "required": [
3557
+ "accessibility_id"
3558
+ ]
3559
+ }
3560
+ ]
3561
+ },
3562
+ "elementId": {
3563
+ "type": "string",
3564
+ "minLength": 1
3565
+ },
3566
+ "property": {
3567
+ "type": "string",
3568
+ "minLength": 1
3569
+ },
3570
+ "expected": {
3571
+ "type": [
3572
+ "boolean",
3573
+ "number",
3574
+ "string"
3575
+ ]
3576
+ }
3577
+ },
3578
+ "required": [
3579
+ "kind",
3580
+ "property",
3581
+ "expected"
3582
+ ],
3583
+ "oneOf": [
3584
+ {
3585
+ "required": [
3586
+ "selector"
3587
+ ],
3588
+ "not": {
3589
+ "required": [
3590
+ "elementId"
3591
+ ]
3592
+ }
3593
+ },
3594
+ {
3595
+ "required": [
3596
+ "elementId"
3597
+ ],
3598
+ "not": {
3599
+ "required": [
3600
+ "selector"
3601
+ ]
3602
+ }
3603
+ }
3604
+ ]
3605
+ }
3606
+ ]
3607
+ }
3608
+ },
3609
+ "required": [
3610
+ "id",
3611
+ "type",
3612
+ "assertion"
3613
+ ]
3614
+ }
3615
+ ]
3616
+ }
3617
+ },
3618
+ "systemTraceId": {
3619
+ "type": "string",
3620
+ "format": "uuid",
3621
+ "description": "Explicit active same-device system trace. Invalid references prevent all journey input. Capture lifetime is controlled separately."
3622
+ },
3623
+ "captureOnFailure": {
3624
+ "type": "boolean",
3625
+ "default": false
3626
+ },
3627
+ "defaults": {
3628
+ "type": "object",
3629
+ "additionalProperties": false,
3630
+ "properties": {
3631
+ "verificationMode": {
3632
+ "type": "string",
3633
+ "enum": [
3634
+ "none",
3635
+ "light",
3636
+ "full"
3637
+ ]
3638
+ },
3639
+ "actionTimeoutMs": {
3640
+ "type": "integer"
3641
+ },
3642
+ "verificationTimeoutMs": {
3643
+ "type": "integer"
3644
+ }
3645
+ }
3646
+ }
3647
+ },
3648
+ "required": [
3649
+ "platform",
3650
+ "steps"
3651
+ ],
3652
+ "allOf": [
3653
+ {
3654
+ "not": {
3655
+ "required": [
3656
+ "expectedState"
3657
+ ]
3658
+ }
3659
+ }
3660
+ ]
3661
+ }
3662
+ },
3663
+ {
3664
+ "name": "get_network_activity",
3665
+ "description": "Returns structured network events captured from platform logs since the last action.\n\nCall this immediately after an action when you want backend evidence for a side-effect flow, only if the result is still ambiguous.\nDo not call more than once per action.\n\nEvents are filtered to significant (non-background) requests only.\nEach event includes endpoint, method, statusCode, networkError, status, and durationMs.\n\nstatus values:\n- success: HTTP 2xx or request detected with no error signal\n- failure: HTTP 4xx\n- retryable: HTTP 5xx, network error (timeout, dns_error, tls_error, etc.)\n\nReturns { requests: [], count: 0 } when no credible network signals are found.",
3666
+ "inputSchema": {
3667
+ "type": "object",
3668
+ "properties": {
3669
+ "platform": {
3670
+ "type": "string",
3671
+ "enum": [
3672
+ "android",
3673
+ "ios"
3674
+ ],
3675
+ "description": "Platform to read network logs from"
3676
+ },
3677
+ "deviceId": {
3678
+ "type": "string",
3679
+ "description": "Device Serial (Android) or UDID (iOS). Defaults to connected/booted device."
3680
+ }
3681
+ },
3682
+ "required": [
3683
+ "platform"
3684
+ ],
3685
+ "allOf": [
3686
+ {
3687
+ "not": {
3688
+ "required": [
3689
+ "expectedState"
3690
+ ]
3691
+ }
3692
+ }
3693
+ ]
3694
+ }
3695
+ }
3696
+ ]