mobile-debug-mcp 0.34.0 → 0.35.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 (432) 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/.github/copilot-instructions.md +14 -36
  11. package/.github/workflows/ci.yml +4 -4
  12. package/AGENTS.md +12 -3
  13. package/CONTRIBUTING.md +79 -0
  14. package/README.md +156 -129
  15. package/agent-plugin/.claude-plugin/plugin.json +2 -2
  16. package/agent-plugin/.codex-plugin/plugin.json +1 -1
  17. package/agent-plugin/.cursor-plugin/plugin.json +2 -2
  18. package/agent-plugin/.mcp.json +1 -1
  19. package/agent-plugin/README.md +16 -6
  20. package/agent-plugin/mcp.json +1 -1
  21. package/agent-plugin/plugin.json +1 -1
  22. package/agent-plugin/skills/mobile-debug-mcp/SKILL.md +27 -2
  23. package/dist/contracts/execution-controls.js +24 -0
  24. package/dist/contracts/selector.js +8 -0
  25. package/dist/contracts/target.js +15 -0
  26. package/dist/contracts/ui.js +1 -0
  27. package/dist/debugger/android.js +2 -1
  28. package/dist/debugger/diagnostics.js +54 -0
  29. package/dist/debugger/protocol.js +33 -0
  30. package/dist/debugger/sessions.js +104 -62
  31. package/dist/debugger/worker.js +53 -42
  32. package/dist/interact/adjustment/adjustment-context.js +41 -0
  33. package/dist/interact/adjustment/adjustment-gestures.js +55 -0
  34. package/dist/interact/adjustment/adjustment-plan.js +18 -0
  35. package/dist/interact/adjustment/adjustment-resolution.js +127 -0
  36. package/dist/interact/adjustment/adjustment-result.js +19 -0
  37. package/dist/interact/adjustment/adjustment-semantic.js +64 -0
  38. package/dist/interact/adjustment/adjustment-verification.js +35 -0
  39. package/dist/interact/adjustment/adjustment.js +52 -0
  40. package/dist/interact/adjustment/control-geometry.js +87 -0
  41. package/dist/interact/adjustment/control-values.js +136 -0
  42. package/dist/interact/adjustment/slider-labels.js +84 -0
  43. package/dist/interact/assertions/screen-assertion.js +37 -0
  44. package/dist/interact/assertions/state-assertion-context.js +35 -0
  45. package/dist/interact/assertions/state-assertion.js +76 -0
  46. package/dist/interact/assertions/state-comparison.js +141 -0
  47. package/dist/interact/assertions/visibility-assertion.js +34 -0
  48. package/dist/interact/conditional-action.js +12 -7
  49. package/dist/interact/index.js +65 -3090
  50. package/dist/interact/input-service.js +1 -0
  51. package/dist/interact/interaction-trace.js +21 -0
  52. package/dist/interact/model.js +1 -0
  53. package/dist/interact/observation.js +1 -0
  54. package/dist/interact/targeting/candidate-ancestor.js +58 -0
  55. package/dist/interact/targeting/candidate-result.js +23 -0
  56. package/dist/interact/targeting/candidate-scoring.js +50 -0
  57. package/dist/interact/targeting/element-helpers.js +216 -0
  58. package/dist/interact/targeting/find-element.js +65 -0
  59. package/dist/interact/targeting/nearby-control.js +56 -0
  60. package/dist/interact/targeting/resolved-elements.js +21 -0
  61. package/dist/interact/targeting/tap-target.js +17 -0
  62. package/dist/interact/targeting/target-scope.js +104 -0
  63. package/dist/interact/waits/legacy-log-wait.js +38 -0
  64. package/dist/interact/waits/legacy-wait-observations.js +103 -0
  65. package/dist/interact/waits/legacy-wait-state.js +34 -0
  66. package/dist/interact/waits/legacy-wait.js +48 -0
  67. package/dist/interact/waits/screen-wait.js +49 -0
  68. package/dist/interact/waits/ui-change-helpers.js +157 -0
  69. package/dist/interact/waits/ui-change-state.js +18 -0
  70. package/dist/interact/waits/ui-change-wait.js +77 -0
  71. package/dist/interact/waits/ui-wait-condition.js +56 -0
  72. package/dist/interact/waits/ui-wait-state.js +38 -0
  73. package/dist/interact/waits/ui-wait.js +106 -0
  74. package/dist/manage/android.js +55 -51
  75. package/dist/manage/index.js +38 -75
  76. package/dist/manage/ios/build-types.js +1 -0
  77. package/dist/manage/ios/build.js +210 -0
  78. package/dist/manage/ios/project-discovery.js +29 -0
  79. package/dist/manage/ios/scheme.js +18 -0
  80. package/dist/manage/ios.js +42 -256
  81. package/dist/observe/android/context.js +1 -0
  82. package/dist/observe/android/current-screen.js +55 -0
  83. package/dist/observe/android/fingerprint.js +13 -0
  84. package/dist/observe/android/log-stream.js +132 -0
  85. package/dist/observe/android/logs.js +107 -0
  86. package/dist/observe/android/screenshot.js +70 -0
  87. package/dist/observe/android/ui-tree.js +107 -0
  88. package/dist/observe/android.js +16 -520
  89. package/dist/observe/evidence.js +114 -75
  90. package/dist/observe/index.js +16 -263
  91. package/dist/observe/ios/context.js +16 -0
  92. package/dist/observe/ios/fingerprint.js +12 -0
  93. package/dist/observe/ios/log-stream.js +105 -0
  94. package/dist/observe/ios/logs.js +168 -0
  95. package/dist/observe/ios/screenshot.js +22 -0
  96. package/dist/observe/ios/ui-elements.js +241 -0
  97. package/dist/observe/ios/ui-tree.js +137 -0
  98. package/dist/observe/ios.js +17 -715
  99. package/dist/observe/logs/model.js +1 -0
  100. package/dist/{network → observe/network}/index.js +2 -2
  101. package/dist/observe/readiness-service.js +4 -2
  102. package/dist/observe/readiness.js +29 -10
  103. package/dist/observe/screenshot-encoding.js +41 -0
  104. package/dist/observe/snapshot-collection.js +79 -0
  105. package/dist/observe/snapshot-logs.js +30 -0
  106. package/dist/observe/snapshot-metadata.js +43 -31
  107. package/dist/observe/snapshot-semantic.js +115 -0
  108. package/dist/observe/system-trace.js +22 -13
  109. package/dist/runtime/action-results.js +270 -0
  110. package/dist/runtime/clock.js +4 -0
  111. package/dist/server/common.js +1 -256
  112. package/dist/server/definitions/assert.js +162 -0
  113. package/dist/server/definitions/diagnostic.js +118 -0
  114. package/dist/server/definitions/input.js +274 -0
  115. package/dist/server/definitions/manage.js +194 -0
  116. package/dist/server/definitions/observe.js +149 -0
  117. package/dist/server/definitions/target.js +138 -0
  118. package/dist/server/definitions/wait.js +105 -0
  119. package/dist/server/handlers/action-execution.js +163 -0
  120. package/dist/server/handlers/correlation.js +23 -0
  121. package/dist/server/{debugger-handlers.js → handlers/debugger-handlers.js} +22 -12
  122. package/dist/server/handlers/debugger-response.js +9 -0
  123. package/dist/server/handlers/diagnostic.js +69 -0
  124. package/dist/server/handlers/handler-types.js +1 -0
  125. package/dist/server/handlers/input.js +154 -0
  126. package/dist/server/handlers/interact.js +113 -0
  127. package/dist/server/handlers/journey-assertions.js +35 -0
  128. package/dist/server/handlers/journey.js +147 -0
  129. package/dist/server/handlers/manage.js +119 -0
  130. package/dist/server/handlers/observe.js +95 -0
  131. package/dist/server/handlers/payload.js +4 -0
  132. package/dist/server/handlers/tool-handlers.js +160 -0
  133. package/dist/server/schemas/condition-schema.js +2 -0
  134. package/dist/server/{debugger-schema.js → schemas/debugger-schema.js} +11 -6
  135. package/dist/server/{journey-schema.js → schemas/journey-schema.js} +7 -22
  136. package/dist/server/tool-definitions.js +58 -1135
  137. package/dist/server-core.js +2 -2
  138. package/dist/system/android-status.js +101 -0
  139. package/dist/system/android.js +37 -27
  140. package/dist/system/index.js +13 -439
  141. package/dist/system/ios-status.js +132 -0
  142. package/dist/system/ios.js +11 -8
  143. package/dist/system/model.js +1 -0
  144. package/dist/system/probes.js +105 -0
  145. package/dist/system/status-summary.js +43 -0
  146. package/dist/system/unsupported-status.js +52 -0
  147. package/dist/utils/android/commands.js +89 -0
  148. package/dist/utils/android/gradle.js +139 -0
  149. package/dist/utils/android/logs.js +103 -0
  150. package/dist/utils/android/ui-tree.js +233 -0
  151. package/dist/utils/android/utils.js +6 -564
  152. package/dist/utils/cli/idb/idb-helper.js +4 -6
  153. package/dist/utils/cli/idb/install-idb.js +13 -9
  154. package/dist/utils/cli/ios/preflight-ios.js +42 -38
  155. package/dist/utils/ios/utils.js +45 -46
  156. package/dist/utils/java.js +65 -49
  157. package/dist/utils/resolve-device.js +4 -2
  158. package/dist/utils/ui/index.js +26 -26
  159. package/docs/CHANGELOG.md +44 -0
  160. package/docs/README.md +38 -0
  161. package/docs/benchmarks/README.md +18 -0
  162. package/docs/benchmarks/interaction-latency/README.md +14 -0
  163. package/docs/benchmarks/interaction-latency/final.md +4 -1
  164. package/docs/benchmarks/interaction-latency/ios-validation.md +2 -0
  165. package/docs/benchmarks/ui-tree-performance/README.md +24 -16
  166. package/docs/benchmarks/ui-tree-performance/comparison.md +11 -10
  167. package/docs/code-structure.md +118 -0
  168. package/docs/specs/001-state-verification/spec.md +16 -14
  169. package/docs/specs/002-richer-element-identity/spec.md +12 -10
  170. package/docs/specs/003-wait-and-synchronization-reliability/spec.md +12 -10
  171. package/docs/specs/004-action-verification-routing/spec.md +3 -3
  172. package/docs/specs/005-unified-action-execution-and-verification-model/spec.md +2 -0
  173. package/docs/specs/006-runtime-action-instrumentation-and-binding-layer/spec.md +2 -0
  174. package/docs/specs/007-actionability-resolution-and-executable-target-selection/spec.md +3 -1
  175. package/docs/specs/008-adjustable-control-support-and-semantic-value-manipulation/spec.md +3 -4
  176. package/docs/specs/009-semantic-control-modeling-for-custom-and-composite-controls/spec.md +2 -0
  177. package/docs/specs/010-verification-stabilization-and-temporal-convergence/spec.md +2 -2
  178. package/docs/specs/011-recovery-and-replanning-for-failed-or-ambiguous-interaction-flows/spec.md +2 -2
  179. package/docs/specs/011.1-recovery-contract-types-and-runtime-wiring-spec/spec.md +2 -0
  180. package/docs/specs/012-action-trace-and-xecution-observability/spec.md +2 -3
  181. package/docs/specs/013-wait-and-synchronization-reliability/spec.md +19 -19
  182. package/docs/specs/014-actionability-resolution/spec.md +20 -18
  183. package/docs/specs/015-adjustable-control-support/spec.md +17 -15
  184. package/docs/specs/016-environment-tools/spec.md +20 -20
  185. package/docs/specs/018-interaction-latency-and-batched-journeys/spec.md +2 -0
  186. package/docs/specs/019-ui-tree-observation-performance/spec.md +3 -1
  187. package/docs/specs/020-conditional-actions/intent.md +5 -3
  188. package/docs/specs/020-conditional-actions/plan.md +8 -9
  189. package/docs/specs/020-conditional-actions/spec.md +4 -2
  190. package/docs/specs/021-app-readiness-signals/intent.md +4 -2
  191. package/docs/specs/021-app-readiness-signals/plan.md +7 -6
  192. package/docs/specs/021-app-readiness-signals/spec.md +3 -1
  193. package/docs/specs/022-correlated-evidence/intent.md +4 -4
  194. package/docs/specs/022-correlated-evidence/plan.md +10 -11
  195. package/docs/specs/022-correlated-evidence/spec.md +3 -1
  196. package/docs/specs/023-android-system-traces/intent.md +3 -2
  197. package/docs/specs/023-android-system-traces/plan.md +5 -7
  198. package/docs/specs/023-android-system-traces/spec.md +3 -1
  199. package/docs/specs/024-android-heap-dump-capture/intent.md +3 -1
  200. package/docs/specs/025-android-runtime-debugger/intent.md +4 -3
  201. package/docs/specs/025-android-runtime-debugger/plan.md +3 -1
  202. package/docs/specs/025-android-runtime-debugger/spec.md +4 -3
  203. package/docs/specs/026-code-structure-and-quality-gates/health-plan.md +88 -0
  204. package/docs/specs/026-code-structure-and-quality-gates/intent.md +47 -0
  205. package/docs/specs/026-code-structure-and-quality-gates/plan.md +191 -0
  206. package/docs/specs/026-code-structure-and-quality-gates/spec.md +138 -0
  207. package/docs/specs/026-code-structure-and-quality-gates/verification-final.json +200 -0
  208. package/docs/specs/026-code-structure-and-quality-gates/verification-thin-facade.json +154 -0
  209. package/docs/specs/026-code-structure-and-quality-gates/verification.json +136 -0
  210. package/docs/specs/027-debugger-failure-diagnostics/intent.md +43 -0
  211. package/docs/specs/027-debugger-failure-diagnostics/plan.md +86 -0
  212. package/docs/specs/027-debugger-failure-diagnostics/spec.md +133 -0
  213. package/docs/specs/028-compact-debugger-responses/intent.md +41 -0
  214. package/docs/specs/028-compact-debugger-responses/plan.md +112 -0
  215. package/docs/specs/028-compact-debugger-responses/spec.md +108 -0
  216. package/docs/specs/029-kotlin-locals-validation/report.md +119 -0
  217. package/docs/specs/030-android-coroutine-validation/evidence.json +475 -0
  218. package/docs/specs/030-android-coroutine-validation/intent.md +47 -0
  219. package/docs/specs/030-android-coroutine-validation/plan.md +147 -0
  220. package/docs/specs/030-android-coroutine-validation/report.md +240 -0
  221. package/docs/specs/030-android-coroutine-validation/spec.md +107 -0
  222. package/docs/tools/TOOLS.md +31 -18
  223. package/docs/tools/{evidence.md → correlated-evidence.md} +9 -1
  224. package/docs/tools/debugger.md +76 -0
  225. package/docs/tools/interact.md +42 -20
  226. package/docs/tools/manage.md +25 -44
  227. package/docs/tools/observe.md +55 -23
  228. package/docs/tools/system-traces.md +9 -1
  229. package/docs/tools/system.md +12 -5
  230. package/package.json +11 -8
  231. package/scripts/architecture-graph.mjs +69 -0
  232. package/scripts/check-architecture.mjs +47 -0
  233. package/scripts/code-quality-baseline.json +1 -0
  234. package/scripts/code-quality.mjs +161 -0
  235. package/src/contracts/execution-controls.ts +26 -0
  236. package/src/contracts/selector.ts +17 -0
  237. package/src/contracts/target.ts +19 -0
  238. package/src/contracts/ui.ts +94 -0
  239. package/src/debugger/android.ts +2 -1
  240. package/src/debugger/diagnostics.ts +43 -0
  241. package/src/debugger/guard.ts +6 -1
  242. package/{worker → src/debugger/java}/DebuggerWorker.java +9 -3
  243. package/src/debugger/protocol.ts +37 -0
  244. package/src/debugger/sessions.ts +314 -155
  245. package/src/debugger/worker.ts +51 -38
  246. package/src/interact/adjustment/adjustment-context.ts +83 -0
  247. package/src/interact/adjustment/adjustment-gestures.ts +48 -0
  248. package/src/interact/adjustment/adjustment-plan.ts +23 -0
  249. package/src/interact/adjustment/adjustment-resolution.ts +104 -0
  250. package/src/interact/adjustment/adjustment-result.ts +34 -0
  251. package/src/interact/adjustment/adjustment-semantic.ts +53 -0
  252. package/src/interact/adjustment/adjustment-verification.ts +60 -0
  253. package/src/interact/adjustment/adjustment.ts +49 -0
  254. package/src/interact/adjustment/control-geometry.ts +120 -0
  255. package/src/interact/adjustment/control-values.ts +141 -0
  256. package/src/interact/adjustment/slider-labels.ts +84 -0
  257. package/src/interact/assertions/screen-assertion.ts +39 -0
  258. package/src/interact/assertions/state-assertion-context.ts +48 -0
  259. package/src/interact/assertions/state-assertion.ts +64 -0
  260. package/src/interact/assertions/state-comparison.ts +168 -0
  261. package/src/interact/assertions/visibility-assertion.ts +41 -0
  262. package/src/interact/conditional-action.ts +18 -12
  263. package/src/interact/index.ts +76 -3492
  264. package/src/interact/input-service.ts +11 -0
  265. package/src/interact/interaction-trace.ts +36 -0
  266. package/src/interact/model.ts +109 -0
  267. package/src/interact/observation.ts +7 -0
  268. package/src/interact/targeting/candidate-ancestor.ts +49 -0
  269. package/src/interact/targeting/candidate-result.ts +24 -0
  270. package/src/interact/targeting/candidate-scoring.ts +42 -0
  271. package/src/interact/targeting/element-helpers.ts +243 -0
  272. package/src/interact/targeting/find-element.ts +47 -0
  273. package/src/interact/targeting/nearby-control.ts +46 -0
  274. package/src/interact/targeting/resolved-elements.ts +20 -0
  275. package/src/interact/targeting/tap-target.ts +22 -0
  276. package/src/interact/targeting/target-scope.ts +121 -0
  277. package/src/interact/waits/legacy-log-wait.ts +30 -0
  278. package/src/interact/waits/legacy-wait-observations.ts +55 -0
  279. package/src/interact/waits/legacy-wait-state.ts +48 -0
  280. package/src/interact/waits/legacy-wait.ts +34 -0
  281. package/src/interact/waits/screen-wait.ts +37 -0
  282. package/src/interact/waits/ui-change-helpers.ts +184 -0
  283. package/src/interact/waits/ui-change-state.ts +26 -0
  284. package/src/interact/waits/ui-change-wait.ts +59 -0
  285. package/src/interact/waits/ui-wait-condition.ts +52 -0
  286. package/src/interact/waits/ui-wait-state.ts +55 -0
  287. package/src/interact/waits/ui-wait.ts +84 -0
  288. package/src/manage/android.ts +56 -50
  289. package/src/manage/index.ts +63 -93
  290. package/src/manage/ios/build-types.ts +14 -0
  291. package/src/manage/ios/build.ts +230 -0
  292. package/src/manage/ios/project-discovery.ts +26 -0
  293. package/src/manage/ios/scheme.ts +16 -0
  294. package/src/manage/ios.ts +65 -298
  295. package/src/observe/android/context.ts +1 -0
  296. package/src/observe/android/current-screen.ts +63 -0
  297. package/src/observe/android/fingerprint.ts +13 -0
  298. package/src/observe/android/log-stream.ts +127 -0
  299. package/src/observe/android/logs.ts +110 -0
  300. package/src/observe/android/screenshot.ts +79 -0
  301. package/src/observe/android/ui-tree.ts +113 -0
  302. package/src/observe/android.ts +17 -531
  303. package/src/observe/evidence.ts +122 -70
  304. package/src/observe/index.ts +24 -286
  305. package/src/observe/ios/context.ts +22 -0
  306. package/src/observe/ios/fingerprint.ts +12 -0
  307. package/src/observe/ios/log-stream.ts +103 -0
  308. package/src/observe/ios/logs.ts +179 -0
  309. package/src/observe/ios/screenshot.ts +26 -0
  310. package/src/observe/ios/ui-elements.ts +266 -0
  311. package/src/observe/ios/ui-tree.ts +143 -0
  312. package/src/observe/ios.ts +18 -749
  313. package/src/observe/logs/model.ts +11 -0
  314. package/src/{network → observe/network}/index.ts +2 -2
  315. package/src/observe/readiness-service.ts +5 -3
  316. package/src/observe/readiness.ts +39 -18
  317. package/src/observe/screenshot-encoding.ts +32 -0
  318. package/src/observe/snapshot-collection.ts +69 -0
  319. package/src/observe/snapshot-logs.ts +26 -0
  320. package/src/observe/snapshot-metadata.ts +51 -31
  321. package/src/observe/snapshot-semantic.ts +153 -0
  322. package/src/observe/system-trace.ts +24 -15
  323. package/src/runtime/action-results.ts +376 -0
  324. package/src/runtime/clock.ts +9 -0
  325. package/src/server/common.ts +9 -359
  326. package/src/server/definitions/assert.ts +164 -0
  327. package/src/server/definitions/diagnostic.ts +120 -0
  328. package/src/server/definitions/input.ts +276 -0
  329. package/src/server/definitions/manage.ts +196 -0
  330. package/src/server/definitions/observe.ts +151 -0
  331. package/src/server/definitions/target.ts +140 -0
  332. package/src/server/definitions/wait.ts +107 -0
  333. package/src/server/handlers/action-execution.ts +164 -0
  334. package/src/server/handlers/correlation.ts +20 -0
  335. package/src/server/handlers/debugger-handlers.ts +39 -0
  336. package/src/server/handlers/debugger-response.ts +7 -0
  337. package/src/server/handlers/diagnostic.ts +79 -0
  338. package/src/server/handlers/handler-types.ts +7 -0
  339. package/src/server/handlers/input.ts +173 -0
  340. package/src/server/handlers/interact.ts +135 -0
  341. package/src/server/handlers/journey-assertions.ts +39 -0
  342. package/src/server/handlers/journey.ts +132 -0
  343. package/src/server/handlers/manage.ts +141 -0
  344. package/src/server/handlers/observe.ts +116 -0
  345. package/src/server/handlers/payload.ts +36 -0
  346. package/src/server/handlers/tool-handlers.ts +159 -0
  347. package/src/server/schemas/condition-schema.ts +2 -0
  348. package/src/server/{debugger-schema.ts → schemas/debugger-schema.ts} +13 -7
  349. package/src/server/{journey-schema.ts → schemas/journey-schema.ts} +7 -22
  350. package/src/server/{system-trace-schema.ts → schemas/system-trace-schema.ts} +3 -3
  351. package/src/server/tool-definitions.ts +67 -1143
  352. package/src/server-core.ts +2 -2
  353. package/src/server.ts +1 -1
  354. package/src/system/android-status.ts +124 -0
  355. package/src/system/android.ts +33 -21
  356. package/src/system/index.ts +21 -525
  357. package/src/system/ios-status.ts +147 -0
  358. package/src/system/ios.ts +14 -10
  359. package/src/system/model.ts +41 -0
  360. package/src/system/probes.ts +114 -0
  361. package/src/system/status-summary.ts +47 -0
  362. package/src/system/unsupported-status.ts +55 -0
  363. package/src/types.ts +16 -106
  364. package/src/utils/android/commands.ts +81 -0
  365. package/src/utils/android/gradle.ts +132 -0
  366. package/src/utils/android/logs.ts +103 -0
  367. package/src/utils/android/ui-tree.ts +239 -0
  368. package/src/utils/android/utils.ts +16 -556
  369. package/src/utils/cli/idb/check-idb.ts +4 -4
  370. package/src/utils/cli/idb/idb-helper.ts +6 -8
  371. package/src/utils/cli/idb/install-idb.ts +15 -9
  372. package/src/utils/cli/ios/preflight-ios.ts +39 -31
  373. package/src/utils/cli/ios/run-ios-ui-tree-tap.ts +4 -4
  374. package/src/utils/ios/utils.ts +57 -61
  375. package/src/utils/java.ts +62 -43
  376. package/src/utils/resolve-device.ts +9 -6
  377. package/src/utils/ui/index.ts +28 -28
  378. package/test/device/automated/debugger/coroutine-lifecycle.ts +27 -0
  379. package/test/device/automated/debugger/coroutine-support.ts +140 -0
  380. package/test/device/automated/debugger/coroutine.android.test.ts +169 -0
  381. package/test/device/automated/debugger/kotlin.android.test.ts +127 -0
  382. package/test/device/automated/debugger/runtime.android.test.ts +19 -3
  383. package/test/device/automated/interact/interaction.android.test.ts +56 -0
  384. package/test/device/automated/observe/system-trace.smoke.ts +1 -1
  385. package/test/device/manual/interact/modul8_selector_tap.manual.ts +1 -1
  386. package/test/fixtures/contracts/tool-definitions.json +3536 -0
  387. package/test/fixtures/coroutine-app/MainActivity.kt +100 -0
  388. package/test/fixtures/coroutine-app/README.md +48 -0
  389. package/test/fixtures/coroutine-app/build.ts +35 -0
  390. package/test/fixtures/debugger-app/MainActivity.java +21 -0
  391. package/test/fixtures/debugger-app/MainActivity.kt +32 -0
  392. package/test/fixtures/debugger-app/README.md +52 -0
  393. package/test/fixtures/debugger-app/build.ts +25 -15
  394. package/test/fixtures/latency-journey-app/README.md +2 -0
  395. package/test/fixtures/readiness-app/README.md +2 -0
  396. package/test/unit/debugger/coroutine-lifecycle.test.ts +43 -0
  397. package/test/unit/debugger/diagnostic-sessions.test.ts +67 -0
  398. package/test/unit/debugger/diagnostics.test.ts +80 -0
  399. package/test/unit/debugger/guards.test.ts +4 -0
  400. package/test/unit/debugger/preparation.test.ts +32 -0
  401. package/test/unit/debugger/protocol.test.ts +15 -0
  402. package/test/unit/debugger/sessions.test.ts +1 -1
  403. package/test/unit/interact/adjustment_service.test.ts +42 -0
  404. package/test/unit/interact/adjustment_verification.test.ts +35 -0
  405. package/test/unit/interact/clock_dependencies.test.ts +63 -0
  406. package/test/unit/interact/element_helpers.test.ts +19 -0
  407. package/test/unit/interact/legacy_wait_service.test.ts +17 -0
  408. package/test/unit/interact/state_comparison.test.ts +20 -0
  409. package/test/unit/interact/target_scope.test.ts +35 -0
  410. package/test/unit/network/get_network_activity.test.ts +1 -1
  411. package/test/unit/observe/screenshot-encoding.test.ts +30 -0
  412. package/test/unit/observe/snapshot-logs.test.ts +14 -0
  413. package/test/unit/quality/architecture.test.ts +60 -0
  414. package/test/unit/quality/code-quality.test.ts +58 -0
  415. package/test/unit/quality/interaction_boundaries.test.ts +24 -0
  416. package/test/unit/server/conditional_actions.test.ts +1 -1
  417. package/test/unit/server/conditional_schema.test.ts +2 -2
  418. package/test/unit/server/debugger-response.test.ts +63 -0
  419. package/test/unit/server/tool_definitions_parity.test.ts +8 -0
  420. package/dist/server/tool-handlers.js +0 -1000
  421. package/docs/ROADMAP.md +0 -646
  422. package/docs/benchmarks/ui-tree-performance/bridge-probe.json +0 -29
  423. package/docs/benchmarks/ui-tree-performance/initial-baseline.json +0 -59560
  424. package/docs/specs/baseline-spec-v0.md +0 -312
  425. package/docs/specs/mcp-tooling-spec-v1.md +0 -446
  426. package/src/server/debugger-handlers.ts +0 -29
  427. package/src/server/tool-handlers.ts +0 -1008
  428. /package/dist/{server/condition-schema.js → contracts/condition.js} +0 -0
  429. /package/dist/server/{readiness-schema.js → schemas/readiness-schema.js} +0 -0
  430. /package/dist/server/{system-trace-schema.js → schemas/system-trace-schema.js} +0 -0
  431. /package/src/{server/condition-schema.ts → contracts/condition.ts} +0 -0
  432. /package/src/server/{readiness-schema.ts → schemas/readiness-schema.ts} +0 -0
@@ -0,0 +1,240 @@
1
+ # Android coroutine debugger assessment — issue #93
2
+
3
+ Date: 2026-11-02. Source: [issue #93](https://github.com/clivejefferies/mobile-debug-tools/issues/93).
4
+ Scope: [accepted specification](spec.md); [fixture/reproduction](../../../test/fixtures/coroutine-app/README.md).
5
+
6
+ ## Method and evidence boundaries
7
+
8
+ The fixture uses explicit CompletableDeferred gates, two named single-thread
9
+ executor dispatchers, a nested async child and a cancellation/finally path.
10
+ It uses no debug probes or app instrumentation. The runner uses the existing
11
+ MCP stdio server and records source/APK/server/worker/dependency fingerprints,
12
+ compiler line/local tables and actual stops, stacks and locals. Fresh UI-tree
13
+ assertions independently establish completion and cancellation recovery.
14
+ Opaque MCP thread IDs are scoped to each stop; different ID strings alone do
15
+ not establish a dispatcher change. Live synthetic thread-name locals and fixture
16
+ checks establish the named dispatcher execution instead.
17
+
18
+ Environment selected: emulator-5554, Android 16/API 36; Node 22.23.4;
19
+ Kotlin compiler/stdlib 2.0.21; kotlinx-coroutines-core-jvm 1.9.0;
20
+ fixture compiler JDK 17.0.11; Android SDK/build-tools 36. The debugger's existing
21
+ Java discovery selects Android Studio JBR, which reports 25.0.3 on this host;
22
+ setting fixture JAVA_HOME does not override that debugger discovery order.
23
+ The local run used a temporary wrapper around the cached Kotlin embeddable
24
+ compiler; the fixture README documents a standard Kotlin CLI installation.
25
+ No result is inferred for other compiler/runtime versions.
26
+
27
+ ## Results
28
+
29
+ Focused emulator journey: **PASS**. Full local output:
30
+ `/tmp/mobile-debug-93-emulator.log`; compact checked-in [evidence](evidence.json).
31
+
32
+ | Check | Observed result |
33
+ | --- | --- |
34
+ | Before/after gate suspension | PASS: source stops; `known=42` readable on both sides |
35
+ | Dispatcher change | PASS: live locals `fixture-first` then `fixture-second` |
36
+ | Nested child work | PASS: helper argument `43`; final `answer=44` |
37
+ | Into/over/out | PASS inside the synchronous helper/increment calls |
38
+ | Suspension-boundary step | Observed stop at `completeWork` entry, line 50; no logical-coroutine-following claim |
39
+ | Safety and recovery | PASS: pause guard, stale-frame rejection, cancelled event wait with usable session |
40
+ | Job cancellation | PASS: child finally source stop, joined cancellation, fresh `Coroutine cancelled` UI |
41
+ | Completion/recovery | PASS: fresh `Coroutine result 44` UI after detach |
42
+ | Owned cleanup | PASS: complete detach, forwards preserved, package/build directory removed |
43
+ | Physical-device journey | UNRUN; explicit serial selection is required |
44
+
45
+ Source SHA-256: `5978b835673876642c256b1c688975e78018addc1f68219371bc47c8cc29a92b`.
46
+ Built server/dist SHA-256: `4f7bf452fc0022c8feb492f11a25c34ac5e360baff9f77d752dd0d248105d581`.
47
+ Worker source SHA-256: `fb15e7add65fb3682d86153818d02378084a46fcd49b2c23c0eafdba290f8323`.
48
+ Compiler/APK/dependency metadata and hashes are in the evidence file. APK signing
49
+ is ephemeral, so subsequent APK hashes can differ.
50
+
51
+ Initial cancellation recovery failed to reach its expected UI state while
52
+ retaining the prior completion text. The test now starts cancellation from a
53
+ fresh fixture process after detaching the boundary-step assessment. This is
54
+ fixture-owned lifecycle isolation, not a debugger cleanup operation.
55
+ An initial thread-name assertion also exposed compiler elimination of unused
56
+ locals; the fixture now uses those values after the breakpoint so their emitted
57
+ scope covers inspection. Assertions were not weakened to treat absent values
58
+ as a dispatcher proof.
59
+
60
+ ## Interpretation and follow-up recommendation
61
+
62
+ Existing source breakpoints can be a useful way to inspect separately executing
63
+ parts of a coroutine. Source bindings must include generated binary class names
64
+ from the actual compiler output. A shallow locals result and current-thread stack
65
+ are execution evidence; they do not enumerate suspended coroutines, establish a
66
+ parent/child job identity or recover an asynchronous logical stack. A local spilled
67
+ into a continuation field need not appear in the current frame's local table.
68
+
69
+ **No-go for implementing generic coroutine reconstruction in this ticket.** A
70
+ separate feasibility design should first prove Android-compatible discovery of
71
+ active and suspended continuations, stable job identity and ownership/parent-child
72
+ relationships, and a versioned mapping from DebugMetadata/state labels to logical
73
+ source frames. This would require inspection beyond the existing shallow locals
74
+ API, or explicitly agreed app instrumentation, with privacy and compatibility
75
+ limits. No such mechanism has been validated here.
76
+
77
+ The upstream [kotlinx-coroutines-debug documentation](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-debug/)
78
+ describes JVM agent-based coroutine tracking and explicitly identifies Android
79
+ instrumentation limitations. It is not evidence that installing that JVM agent
80
+ would supply an Android solution. The [DebugProbes API](https://kotlinlang.org/api/kotlinx.coroutines/kotlinx-coroutines-debug/kotlinx.coroutines.debug/-debug-probes/)
81
+ describes tracking creation, suspension and resumption with instrumentation and
82
+ overhead; this fixture does not enable it. Android-specific alternatives and
83
+ metadata compatibility remain design questions. Defer that capability design
84
+ until after the bounded assessment and iOS parity, as the issue requires.
85
+
86
+ ## Limits
87
+
88
+ Physical-device verification, other Kotlin/coroutine versions, optimized or
89
+ obfuscated apps, inline suspend functions, process/device disconnect and forced
90
+ host termination are unrun unless separately recorded below. Signal handling
91
+ requests MCP cancellation then finally attempts owned cleanup; SIGKILL/host loss
92
+ cannot run finally. No iOS runtime-debugger support is claimed. Hosted CI has not
93
+ run; it separately compiles the worker with JDK 17 and checks package contents,
94
+ and its ordinary device workflow does not provision this opt-in Kotlin compiler.
95
+ Local build/test evidence is not an installed or published-package check.
96
+
97
+ ## Repository verification
98
+
99
+ `npm run verify` **PASS** on Node 22.23.4: lint, structural/architecture checks,
100
+ TypeScript build, all 89 unit files and plugin consistency. Final log:
101
+ `/tmp/mobile-debug-93-final-verify.log`. The sandbox blocked tsx IPC creation;
102
+ verification passed in the authorized run outside the sandbox without changing
103
+ checks. Changed relative links, new-file whitespace and `git diff --check` passed.
104
+
105
+ The focused review found no required production-code or schema change. Fixture
106
+ subprocesses/polls are bounded; package targeting is explicit; the runner refuses
107
+ pre-existing fixture installations and keeps normal debugger cleanup separate
108
+ from resetting its own app between independent cases. At the original verification,
109
+ changes were local, uncommitted and unpushed.
110
+
111
+ Full `npm run test:device` **PASS**, all 12 files, with
112
+ `MCP_COROUTINE_DEVICE=emulator-5554 MCP_KOTLIN_DEVICE=emulator-5554 MCP_DEBUGGER_DEVICE=emulator-5554`
113
+ and the documented local compiler/stdlib/coroutine paths set. Log:
114
+ `/tmp/mobile-debug-93-device.log`. The coroutine assessment passed again on the
115
+ same source/server/worker fingerprints (ephemeral APK signing produced SHA-256
116
+ `6cc95ae8ad9d254444e9704a7526d62a0ab1c8354a5624d6695789eedd429f82`).
117
+ Existing Kotlin/Java debugger, interaction, Android/iOS observation smoke,
118
+ correlated-evidence and Android system-trace checks passed. These iOS checks do
119
+ not verify iOS runtime debugging. The new fixture's package, temporary outputs
120
+ and owned forwards were removed; no physical-device coroutine check ran.
121
+
122
+ ## PR #96 repair evidence
123
+
124
+ The original results above predate the readiness-race fix: they establish the
125
+ recorded locations/values, but the original UI readiness alone did not prove
126
+ that the gate wait had suspended before release/cancellation. New readiness
127
+ runs as queued work behind the coroutine on its own single-thread executor,
128
+ which cannot execute until that coroutine yields. The repaired dispatcher
129
+ breakpoint class is `MainActivity$completeWork$3`.
130
+
131
+ Overall JSON PASS now follows cleanup, and cleanup failures are reported as FAIL.
132
+ Forward comparisons select only the target serial and sort entries. The new
133
+ unit regressions and repository verification passed (90 unit files, Node 22.23.3;
134
+ `/tmp/pr96-verify.log`). The first attempt on a restored emulator
135
+ snapshot hit install/uninstall timeouts; that real cleanup failure emitted JSON FAIL
136
+ without an overall PASS (`/tmp/pr96-device.log`). The task-owned leftover package
137
+ was removed after a cold start. Final device-rerun evidence is recorded below;
138
+ the original suspension-readiness evidence is superseded.
139
+
140
+ Final repair verification: `npm run verify` **PASS**, all 90 unit files, Node
141
+ 22.23.3 (`/tmp/pr96-final-verify.log`). Unit checks cover successful cleanup before
142
+ PASS, work failure, cleanup failure, simultaneous failures without losing either
143
+ error, exact serial filtering, other-device churn and order normalization.
144
+
145
+ Full device-suite attempts **FAIL** during installation/cleanup on the restored
146
+ and cold-started emulator (`/tmp/pr96-device.log`, `/tmp/pr96-device-cold.log`).
147
+ Incremental installation continued after host-side timeout, leaving a differently
148
+ signed package; the task-owned package was removed. A focused streamed-install
149
+ run used an external temporary ADB_PATH wrapper adding `--no-incremental` only
150
+ for install, without changing repository timeouts or assertions.
151
+
152
+ That focused run **passed** completion, verified the queued readiness and updated
153
+ `completeWork$3` breakpoints, named dispatchers, known values, synchronous steps,
154
+ stale/pause guards, cancelled wait recovery and the bounded suspension-step
155
+ observation. It then **failed** at `am start -W` restarting the fixture before
156
+ cancellation, followed by an uninstall timeout. Its overall JSON FAIL preserves
157
+ both errors (`/tmp/pr96-focused-streamed.log`). Repaired cancellation readiness
158
+ is compiler-checked but its device journey is **UNRUN**; remaining suite checks
159
+ were not reached. No full native pass is claimed for this repair.
160
+
161
+ Current fixture source SHA-256:
162
+ `d4656e3736cc245230bc000c6574288b145df47957dd7ee511ea98717afde4df`.
163
+ Final independent package query returned no owned fixture package; no ADB forwards
164
+ remained and temporary build output was removed. The review fixes introduce no
165
+ production server behaviour or contract change. Physical-device checks and hosted
166
+ CI are unrun for this revision.
167
+
168
+ ## Successful retry on the maintainer's running emulator
169
+
170
+ The repaired coroutine assessment **PASS**ed in full on emulator-5554, Android
171
+ 16/API 36, commit `1497693`, Node 22.23.3. This supersedes the earlier incomplete
172
+ cancellation verification: queued readiness, cancellation/finally, cancelAndJoin,
173
+ fresh `Coroutine cancelled` UI, completion, stepping, guards, cancelled event wait
174
+ and owned cleanup all passed. The overall JSON PASS followed successful cleanup.
175
+ Log: `/tmp/pr96-user-emulator.log`.
176
+
177
+ Fixture source SHA-256 remains
178
+ `d4656e3736cc245230bc000c6574288b145df47957dd7ee511ea98717afde4df`;
179
+ server/dist remains `4f7bf452fc0022c8feb492f11a25c34ac5e360baff9f77d752dd0d248105d581`.
180
+ APK SHA-256: `3ec87db96cd87f9bd7ca27472dde8c1b57d2789d9f808714362ca4ba2ee95c83`.
181
+ Kotlin/stdlib 2.0.21, coroutines 1.9.0 and fixture JDK 17.0.11 were unchanged.
182
+ Local setup used the temporary ADB_PATH wrapper for streamed installation and
183
+ `JAVA_TOOL_OPTIONS='-Xmx512m -XX:TieredStopAtLevel=1'` for host JVM startup.
184
+ No assertions or deadlines changed. The user-started emulator remains running;
185
+ only fixture-owned resources were removed. Physical-device coroutine validation
186
+ remains unrun.
187
+
188
+ The full device-suite retry passed coroutine, Kotlin/Java debugger, interaction
189
+ and Android screenshot checks before failing the iOS screenshot test's ambiguous
190
+ target selection (`/tmp/pr96-user-device-suite.log`). Separate Android logs,
191
+ UI-tree and correlated-evidence checks passed; the correlation script then failed
192
+ its iOS prerequisite because no iOS simulator was running
193
+ (`/tmp/pr96-user-android-remaining.log`). Full-suite status remains **FAIL** for
194
+ those iOS setup requirements, while the repaired Android coroutine journey is
195
+ verified **PASS**, including cancellation and cleanup.
196
+
197
+ A separate Android system-trace check failed its cancellation-state assertion
198
+ (`failed` / `ACTION_TIMEOUT`, expected `cancelled`); its finally cleanup retry
199
+ completed. Log: `/tmp/pr96-user-trace.log`. This is an additional observed
200
+ limitation in the broader smoke checks; it does not invalidate the coroutine
201
+ journey's successful cancellation and cleanup. No trace code or assertions were
202
+ changed, and no complete device-suite pass is claimed.
203
+
204
+ ## Perfetto timeout investigation — 2026-11-02
205
+
206
+ The earlier `cancel_system_trace` failure reported ACTION_TIMEOUT in the bounded
207
+ stop/termination phase. Its original log does not identify which ADB command or
208
+ process-exit wait exhausted the budget, so the root cause remains undetermined.
209
+ No tracing source or smoke-test changes appear in PR #96.
210
+
211
+ On the same running Android 16/API 36 emulator-5554 and server build
212
+ `e90ed0831de4059f1e2b213ed0c050298cf2e55c0cc0aef9ff4ea2a38b6062a0`:
213
+
214
+ - Three direct native/session start-cancel probes **PASS**ed with complete cleanup;
215
+ cancellation took 372, 373 and 390 ms. Log: `/tmp/pr96-perfetto-probe.log`.
216
+ - Three full MCP smoke journeys **PASS**ed: Settings journey assertion, readable
217
+ trace content, explicit stop, cancellation, automatic duration completion,
218
+ stale-trace rejection and active shutdown cleanup. Logs:
219
+ `/tmp/pr96-perfetto-retest.log`, `/tmp/pr96-perfetto-instrumented-1.log`,
220
+ `/tmp/pr96-perfetto-instrumented-2.log`.
221
+ - The final run used an assertion-identical temporary test copy with a server
222
+ preloader recording native-command timing. Across 71 commands, the only
223
+ nonzero exits were five expected Perfetto help probes (exit 1 is supported).
224
+ Maximum process lookup was 111 ms; maximum signal command 63 ms; maximum start
225
+ 247 ms. No command timed out. Log: `/tmp/pr96-perfetto-mcp-timings.log`.
226
+ - The first attempted instrumentation relied on NODE_OPTIONS, which the SDK's
227
+ default subprocess environment did not forward to the server. That smoke pass
228
+ remains valid but supplies no server timing evidence. The final run explicitly
229
+ preloaded the diagnostic module in both server subprocesses.
230
+ - Final independent checks found no MCP trace files and no forwards on the
231
+ emulator. Host test artifacts were removed by each smoke journey. The emulator
232
+ remains running; no settings or user-app data were changed.
233
+
234
+ Classification: the previously observed timeout is **not reproduced**, with an
235
+ intermittent timing failure still possible. Passing reruns do not establish its
236
+ cause or prove it fixed. No production change, timeout increase, assertion change
237
+ or test suppression was made. Current Perfetto verification passes; the earlier
238
+ failed observation is retained rather than reclassified as a pass. Any recurrence
239
+ needs command timings at the failing invocation to distinguish ADB transport,
240
+ process identity lookup, signalling and process-exit delay.
@@ -0,0 +1,107 @@
1
+ # Android coroutine validation specification — issue #93
2
+
3
+ Status: accepted by the maintainer’s second “ok” in this chat on 2026-11-02. Implements the
4
+ [accepted intent](intent.md), approved by “ok” in this chat on 2026-11-02.
5
+
6
+ ## Outcome and compatibility
7
+
8
+ Establish what the existing Android JDI tools actually expose for an isolated
9
+ Kotlin coroutine, and publish a reproducible assessment. No server capability,
10
+ schema, response shape, error code or default changes. Android only; iOS runtime
11
+ debugging remains unsupported. Java and synchronous Kotlin fixture journeys
12
+ retain their current behaviour. Any reproduced production defect is reported
13
+ with evidence and handled separately through the shared process.
14
+
15
+ ## Fixture and prerequisites
16
+
17
+ Add an opt-in coroutine variant of the disposable debugger fixture, built from
18
+ checked-in source using the existing direct Kotlin/D8/aapt2 pipeline. Initially
19
+ target Kotlin compiler/stdlib 2.0.21, kotlinx-coroutines-core-jvm 1.9.0, JDK 17,
20
+ Android SDK/build-tools 36 and Node 22+. Require explicit local dependency paths;
21
+ do not download dependencies at test runtime, add server dependencies, enable
22
+ debug probes or instrument user apps. Record actual versions and dependency
23
+ hashes. Missing or incompatible prerequisites produce an actionable blocked
24
+ result, not a pass.
25
+
26
+ Use a separate fixture package so the coroutine journey cannot replace the
27
+ existing Java/Kotlin fixture. Refuse installation if that package is already
28
+ present; remove only the package installed by this run. Run sequentially on an
29
+ explicit device serial. Initial target is emulator-5554; an attached Pixel 9 Pro
30
+ is a separate optional verification target, never selected automatically.
31
+
32
+ The fixture owns two named single-thread executor dispatchers. This makes a
33
+ thread change observable without relying on scheduler chance. A run exposes a
34
+ known local, suspends on a controllable gate, continues on the other dispatcher,
35
+ performs nested child work, then completes with a fixed visible result. A
36
+ separate cancellation run suspends a child, cancels and joins it, executes its
37
+ finally block and shows a cancellation result. Gates and UI state establish
38
+ ordering; arbitrary sleeps do not establish suspension. Close jobs/executors
39
+ on activity destruction. Use compiler-emitted line/class metadata to identify
40
+ generated continuation classes; do not assume every source line belongs to
41
+ MainActivity or has a usable breakpoint.
42
+
43
+ ## Existing MCP workflow
44
+
45
+ Use `get_debugger_capabilities`, `attach_debugger`,
46
+ `set_debugger_breakpoint`, `wait_for_debugger_event`, `get_debugger_stack`,
47
+ `get_debugger_locals`, `step_debugger`, `resume_debugger`,
48
+ `remove_debugger_breakpoint`, `get_debugger_state` and `detach_debugger` with
49
+ their current inputs and response contracts in the [debugger guide](../../tools/debugger.md).
50
+ Keep session IDs, stop/thread/frame IDs and event cursors scoped to that run;
51
+ reject overflow as incomplete evidence. Inspect thread-based frames and shallow
52
+ locals without evaluating expressions or traversing continuation objects.
53
+
54
+ Verify source stops before and after suspension and across the dispatcher
55
+ change; compare known values with compiler scope tables. Report missing or
56
+ unavailable locals honestly. Compiler spilling into continuation fields does
57
+ not imply the locals API exposes those fields. Compare observed thread IDs and
58
+ stack locations, without calling a thread stack a logical coroutine stack.
59
+
60
+ Exercise into/over/out on a deterministic synchronous helper inside the coroutine.
61
+ Separately attempt a bounded step across a suspension boundary and record where
62
+ the event actually stops, including generated/runtime code or absence of a stop.
63
+ Do not require that step to follow the coroutine; remove the step request through
64
+ normal detach if it cannot make useful progress. A fresh session can then verify
65
+ the before/after source-breakpoint workaround independently.
66
+
67
+ ## Safety, failure and cleanup
68
+
69
+ All stops suspend the app. Verify an MCP interaction is rejected with the existing
70
+ `DEBUGGER_PAUSED` result; no UI action is needed to release a gate while paused.
71
+ Resume before further input. Old stop/frame references must return
72
+ `DEBUGGER_STALE_REFERENCE` after execution resumes. Cancel an event wait and
73
+ confirm the session remains usable; distinguish MCP request cancellation from
74
+ fixture job cancellation.
75
+
76
+ Bound subprocesses and polls with explicit deadlines. Keep normal inspection
77
+ below the existing 60-second pause limit. On timeout, failure or interruption,
78
+ attempt bounded detach, close the client, remove only owned forwards/package
79
+ and temporary build output, and report unresolved cleanup. Never kill ADB,
80
+ unrelated debugger sessions or user apps, nor automatically retry uncertain
81
+ attach/step/resume operations. Preserve unrelated forwards. After normal detach,
82
+ use a fresh UI-tree assertion of the expected completion/cancellation text to
83
+ prove app recovery; detach acknowledgement alone is insufficient.
84
+
85
+ ## Acceptance and assessment
86
+
87
+ 1. A reproducible opt-in runner records source/APK/server fingerprints, dependency
88
+ versions, Android target and per-journey pass/fail/blocked/unrun results.
89
+ 2. Completion, cancellation, breakpoint workaround, stepping observations,
90
+ stale references, pause guards, cancelled wait recovery and owned cleanup
91
+ have explicit evidence. An unsupported debugging observation is an assessment
92
+ finding; a failed safety or cleanup assertion remains a failure.
93
+ 3. Emulator and physical-device evidence are separate. No physical run or
94
+ version compatibility is inferred from emulator success.
95
+ 4. Tool docs, usage skill and fixture README explain verified behaviour,
96
+ limitations and reproduction. Existing journeys and `npm run verify` pass;
97
+ applicable `npm run test:device` coverage and skips are reported.
98
+ 5. A report recommends go/no-go for separately scoped inspection of active and
99
+ suspended coroutine state, parent/child identity and logical stacks. Describe
100
+ metadata/probe requirements and setup friction as evidence or open questions.
101
+ No follow-up capability is implemented or approved by this specification.
102
+
103
+ Only synthetic fixture values are collected. Retain local evidence intentionally;
104
+ do not upload app data. Principal risks are compiler source mapping, ART variable
105
+ metadata and scheduler/debugger interaction. No live coroutine behaviour has been
106
+ verified yet. Prerequisite discovery found the proposed compiler/coroutine jars,
107
+ JDK 17 and an authorized emulator; this is availability evidence only.
@@ -1,27 +1,40 @@
1
- # Tools index
1
+ # Tool reference
2
2
 
3
- This repository groups the MCP tools into four areas aligned with the codebase:
3
+ [Documentation](../README.md)
4
4
 
5
- - [manage](manage.md) — build, install, launch, restart, and device-management tools
6
- - [observe](observe.md) — screenshots, logs, UI trees, fingerprints, and debug snapshots
7
- - [interact](interact.md) — UI resolution, actions, waits, and deterministic verification
8
- - [system](system.md) — environment and health checks
5
+ Use the guides below when you need a tool contract or a specific workflow.
9
6
 
10
- Correlation metadata and explicit action references are documented in
11
- [correlated evidence](evidence.md). Android performance capture is documented in
12
- [system traces](system-traces.md). Android bytecode debugging is documented in
13
- [runtime debugger](debugger.md).
7
+ ## Reference guides
14
8
 
15
- ## Agent guidance
9
+ - [App management](manage.md) — build, install, launch, restart, and device management.
10
+ - [Observation](observe.md) — screenshots, logs, UI trees, fingerprints, debug snapshots, and app readiness.
11
+ - [Interaction](interact.md) — UI resolution, actions, waits, and deterministic verification.
12
+ - [Environment diagnostics](system.md) — toolchain discovery and health checks.
13
+ - [Evidence correlation](correlated-evidence.md) — action references, capture timing, and freshness.
14
+ - [Android system traces](system-traces.md) — performance capture and local Perfetto artifacts.
15
+ - [Android runtime debugger](debugger.md) — process attachment, breakpoints, and bounded runtime inspection.
16
16
 
17
- For interactive flows, the intended deterministic pattern is:
17
+ ## Interaction principles
18
18
 
19
- **RESOLVE -> ACT -> WAIT (if needed) -> EXPECT**
19
+ Interactive flows follow a common sequence:
20
20
 
21
- - **wait_for_\*** tools are for resolution and synchronization
22
- - **expect_\*** tools are for final outcome verification
23
- - observation tools are supporting context, not primary success signals
21
+ **RESOLVE → ACT → WAIT (if needed) → EXPECT**
24
22
 
25
- For environment-sensitive work, call `get_system_status` first so the client can rely on automatic discovery when it is available and fall back to explicit tool paths only when needed.
23
+ - Resolution identifies the target before an action.
24
+ - Actions report execution; successful dispatch alone does not establish the intended outcome.
25
+ - `wait_for_*` tools resolve targets and synchronize with UI changes.
26
+ - `expect_*` tools verify the final outcome using explicit assertions.
27
+ - Observation tools provide evidence for targeting, assertions, and diagnosis; collecting evidence alone does not establish success.
28
+ - `get_system_status` identifies available toolchains and missing prerequisites before environment-sensitive operations. Explicit tool paths override automatic discovery when needed.
26
29
 
27
- Use the linked documents below for per-tool inputs, outputs, and usage guidance.
30
+ ## Reading examples
31
+
32
+ Inputs are MCP tool arguments, not shell commands. Replace example device IDs,
33
+ app identifiers, and UI labels with values from your environment. Response
34
+ examples show relevant fields and may omit optional metadata, execution traces,
35
+ and [evidence correlation](correlated-evidence.md). Clients receive JSON in MCP
36
+ text content blocks, with additional image blocks for screenshot tools.
37
+
38
+ Parameter spelling varies by tool: for example, standalone UI waits use
39
+ `timeout_ms`, while journeys and readiness tools use `timeoutMs`. Follow the
40
+ individual tool's input contract rather than translating names between tools.
@@ -1,4 +1,12 @@
1
- # Correlated evidence
1
+ # Evidence correlation
2
+
3
+ [Documentation](../README.md) · [Tool reference](TOOLS.md)
4
+
5
+ Use evidence correlation to connect an action with later screenshots, UI trees,
6
+ and logs, and to understand when those observations were captured. Association
7
+ does not prove that the action caused an observed change.
8
+
9
+ ## Associate an observation with an action
2
10
 
3
11
  Covered actions (`start_app`, `restart_app`, `tap`, `tap_element`, `swipe`,
4
12
  `scroll_to_element`, `type_text`, `press_back`, `adjust_control`) return an
@@ -1,5 +1,7 @@
1
1
  # Android runtime debugger
2
2
 
3
+ [Documentation](../README.md) · [Tool reference](TOOLS.md)
4
+
3
5
  Optional managed Java/Kotlin bytecode debugging through an independently developed
4
6
  JDI worker. Requires JDK 17+ (`java`, `javac`, `jdk.jdi`), Android platform-tools,
5
7
  an authorized device and an already-running JDWP-visible debuggable app.
@@ -50,6 +52,54 @@ Failures carry `error: {code, message, retryable}`. Event polls use top-level
50
52
  `events`, `next_cursor`, `overflow`, `timed_out`; empty waits are successful.
51
53
  The 256-event ring returns at most 100 entries; overflow must not be ignored.
52
54
 
55
+ ## Response modes
56
+
57
+ All eleven debugger tools accept `responseMode: "compact" | "debug"` (default
58
+ `"debug"`, the existing full response). Selection applies only to the current call.
59
+ For routine session commands, compact mode omits only top-level `device`, `target`
60
+ and `capabilities` when `debug_session_id` is non-null. Attach, capabilities and
61
+ state calls retain their full payload in either mode. Use `get_debugger_state`
62
+ or request `debug` to recover target/capability context.
63
+
64
+ Errors and sanitized diagnostics, identifiers, stop and execution state, event
65
+ cursors/overflow, limitations, truncation and cleanup remain intact. Unknown
66
+ session IDs still fail explicitly. Compact mode does not redact locals or prove
67
+ execution resumed: detach retains `execution_state: "unknown"`. Retry incomplete
68
+ cleanup according to its remaining resources. Invalid modes are rejected.
69
+
70
+ ## Failure diagnostics
71
+
72
+ Debugger operation failures add `error.diagnostic: {stage, reason, recovery}` while
73
+ preserving existing error codes, messages and retryability. `stage` identifies
74
+ prerequisite checks, compilation, worker startup, IPC, target resolution,
75
+ forwarding, JDI attach, command execution, transport or cleanup; `unknown` is
76
+ explicit when evidence is insufficient. `reason` is a fixed classification,
77
+ such as `spawn_failed`, `process_exited`, `invalid_message`, `message_limit`,
78
+ `write_failed`, `connection_refused`, `transport_lost`, `timeout` or `cancelled`.
79
+ Remaining catalog values and the exact schema are defined in the
80
+ [accepted specification](../specs/027-debugger-failure-diagnostics/spec.md).
81
+
82
+ `recovery` is static guidance, not raw stderr or exception text. Each diagnostic
83
+ is at most 512 UTF-8 bytes with guidance at most 240 ASCII characters. Untrusted
84
+ worker fields are validated and reconstructed. No new logging or app-value
85
+ collection is introduced. Startup classification means no valid worker reply had
86
+ yet arrived; it does not establish the underlying cause of an unexpected exit.
87
+ Argument, stale-reference and pause/state validation errors may omit diagnostics.
88
+
89
+ Capability probes retain `success: true` and `supported: false` for unavailable
90
+ prerequisites; optional top-level `diagnostics` contains at most two entries,
91
+ ordered JDK then target. Successful probes omit it. Terminal session failures
92
+ retain sanitized diagnostics until normal summary expiry, even after inspection
93
+ data is cleared. A cleanup failure has its own diagnostic; inspect the existing
94
+ session reason and `cleanup.remaining_resources` as well.
95
+
96
+ Follow recovery guidance and inspect session/cleanup state before another
97
+ state-changing command. Timeout or cancellation does not prove nondelivery.
98
+ Retry incomplete cleanup with `detach_debugger`; never automatically retry
99
+ attach, step or resume, or kill the app/ADB server. Diagnostics improve failure
100
+ classification and do not establish the cause of a previously intermittent error.
101
+ This contract applies to the Android backend; iOS debugging remains unsupported.
102
+
53
103
  ## Suspension, limits and cleanup
54
104
 
55
105
  Stops suspend all app threads. UI actions, app lifecycle/data changes, waits and
@@ -90,15 +140,41 @@ useful source lines or locals. Locals may contain private data: values are retur
90
140
  only on request, without protocol/value logging, persistent dumps or upload.
91
141
  Worker heap is capped at 128 MiB; IPC and messages are bounded; forwarding remains loopback-only.
92
142
 
143
+ For Kotlin, stop after a local's assignment before expecting its value. A stop
144
+ on the assignment line may precede initialization and the compiler's variable
145
+ scope. Compare source location and emitted debug tables before classifying a
146
+ missing local as a debugger failure. The isolated
147
+ [Kotlin validation](../specs/029-kotlin-locals-validation/report.md) covers a plain
148
+ calculation; it does not establish coroutine, inline/suspend, optimized or
149
+ obfuscated-code support.
150
+
151
+ An opt-in [coroutine fixture](../../test/fixtures/coroutine-app/README.md) assesses
152
+ source breakpoints across suspension, dispatcher changes, nested work and
153
+ cancellation with explicit Kotlin/coroutine dependencies. Use source breakpoints
154
+ at both sides of a suspension point and inspect each actual stop. A thread-based
155
+ step may stop in generated coroutine code; its acknowledgement does not establish
156
+ that it followed a coroutine. Stop/thread/frame references expire when execution
157
+ resumes. Shallow locals do not expose spilled continuation fields or reconstruct
158
+ parent/child coroutine identity. The [assessment record](../specs/030-android-coroutine-validation/report.md)
159
+ distinguishes device evidence from follow-up proposals.
160
+
93
161
  Verified environments and remaining checks are recorded in
94
162
  [the implementation plan](../specs/025-android-runtime-debugger/plan.md).
95
163
  To run the isolated fixture journey (installs then removes its own test package):
96
164
 
97
165
  ```sh
98
166
  MCP_DEBUGGER_DEVICE=emulator-5554 npx tsx test/device/automated/debugger/runtime.android.test.ts
167
+ # Exercise opt-in compact responses across the same assertions:
168
+ MCP_DEBUGGER_DEVICE=emulator-5554 MCP_DEBUGGER_RESPONSE_MODE=compact npx tsx test/device/automated/debugger/runtime.android.test.ts
99
169
  # Also exercise the real 60-second pause expiry:
100
170
  MCP_DEBUGGER_DEVICE=emulator-5554 MCP_DEBUGGER_EXTENDED=1 npx tsx test/device/automated/debugger/runtime.android.test.ts
101
171
  ```
102
172
 
103
173
  The ordinary device suite explicitly reports this journey unrun unless the device
104
174
  is selected. Fixture compilation requires SDK platform/build-tools 36 and `javac -g`.
175
+
176
+ ## Related guides
177
+
178
+ - [App management](manage.md): build, install, and launch the app before attaching.
179
+ - [App readiness](observe.md#app-readiness): understand known debugger-pause evidence.
180
+ - [Android system traces](system-traces.md): investigate performance without paused-state inspection.
@@ -1,23 +1,23 @@
1
- # Interact (UI actions, waits, and verification)
1
+ # Interaction
2
2
 
3
- This document covers deterministic UI resolution, actions, waits, and outcome verification.
3
+ [Documentation](../README.md) · [Tool reference](TOOLS.md)
4
4
 
5
- ## Verification pattern
5
+ Use these tools to select UI targets, perform actions, wait for transitions, and
6
+ verify the resulting state. See [interaction principles](TOOLS.md#interaction-principles)
7
+ for the distinction between execution, synchronization, and verification.
6
8
 
7
- For mutation actions, the intended agent loop is:
9
+ ## On this page
8
10
 
9
- **RESOLVE -> ACT -> WAIT (if needed) -> EXPECT**
11
+ - Find a target: [find_element](#find_element), [wait_for_ui](#wait_for_ui).
12
+ - Act on it: [basic input](#tap--swipe--type_text--press_back), [tap_element](#tap_element), [scroll_to_element](#scroll_to_element), [adjust_control](#adjust_control).
13
+ - Wait for change: [screen changes](#wait_for_screen_change), [UI changes](#wait_for_ui_change), [readiness-aware waits](#readiness-aware-waits).
14
+ - Verify the outcome: [screen](#expect_screen), [visible element](#expect_element_visible), [control state](#expect_state).
15
+ - Control execution: [conditional actions](#conditional-actions), [verification modes and journeys](#interaction-execution-controls-rfc-018).
16
+ - Investigate failures: [outcome classification and network activity](#classify_action_outcome--get_network_activity), [evidence correlation](correlated-evidence.md).
10
17
 
11
- Role split:
12
-
13
- - `wait_for_*` = resolution and synchronization
14
- - `expect_*` = final outcome verification
15
-
16
- Important:
17
-
18
- - `wait_for_*` tools must not be used as the final verification of action success when an applicable `expect_*` tool exists.
19
- - action tools report execution success, not outcome correctness.
20
- - `classify_action_outcome` should receive the runtime `action_type` when you want routing to distinguish local-state and side-effect actions.
18
+ When classifying a result, pass the runtime `action_type` to
19
+ `classify_action_outcome` so local-state changes and backend side effects can be
20
+ distinguished.
21
21
 
22
22
  ## Conditional actions
23
23
 
@@ -125,7 +125,7 @@ Example response:
125
125
  "target": { "selector": { "x": 100, "y": 200 }, "resolved": null },
126
126
  "success": true,
127
127
  "trace": {
128
- "action_id": "tap_element_1710000000002_3",
128
+ "action_id": "tap_1710000000000_1",
129
129
  "steps": [
130
130
  {
131
131
  "stage": "resolve",
@@ -292,6 +292,8 @@ Notes:
292
292
  - initial support is for slider-like controls that expose `value_range` or readable numeric value state
293
293
  - `expect_state` is the verification surface used to read back the resulting value
294
294
  - direct target placement is preferred; drag fallback is treated as degraded mode
295
+ - `maxAttempts` defaults to 5; omitted tolerance is 0 for discrete controls, or
296
+ the larger of half a step and 1% of the range for continuous controls
295
297
  - the tool returns `target_state`, `actual_state`, `within_tolerance`, `converged`, `attempts`, and `adjustment_mode`
296
298
 
297
299
  Input example:
@@ -458,7 +460,10 @@ Notes:
458
460
 
459
461
  ## tap_element
460
462
 
461
- Tap a previously resolved UI element using its `elementId`.
463
+ Tap a previously resolved `elementId`, or provide a `selector` to resolve and tap
464
+ in one call. Supply exactly one of these targets. Selector calls can use
465
+ `waitFor`; handle-based calls cannot. See [execution controls](#interaction-execution-controls-rfc-018)
466
+ for lookup budgets and selector options.
462
467
 
463
468
  Input:
464
469
 
@@ -734,8 +739,25 @@ the journey; remaining steps report `not_run`. Journey responses default to comp
734
739
  `defaults` supplies execution controls; step verification overrides the default.
735
740
  `captureOnFailure: true` includes a screenshot-free failure snapshot in debug mode.
736
741
 
737
- See [RFC 018](../specs/018-interaction-latency-and-batched-journeys/spec.md) for
738
- contracts and the device acceptance criteria.
742
+ Example `run_journey` request:
743
+
744
+ ```json
745
+ {
746
+ "platform": "android",
747
+ "deviceId": "emulator-5554",
748
+ "steps": [
749
+ { "id": "open-settings", "type": "tap", "selector": { "text": "Settings" } },
750
+ { "id": "verify-account", "type": "assert", "timeoutMs": 15000,
751
+ "assertion": { "kind": "element_visible", "selector": { "text": "Account" } } }
752
+ ]
753
+ }
754
+ ```
755
+
756
+ Replace the labels with elements from your own UI. Journey timeouts use camelCase
757
+ (`timeoutMs`, `pollIntervalMs`), unlike standalone UI wait/assertion fields
758
+ (`timeout_ms`, `poll_interval_ms`). See
759
+ [RFC 018](../specs/018-interaction-latency-and-batched-journeys/spec.md) for design
760
+ history and device acceptance criteria.
739
761
 
740
762
  ## Readiness-aware waits
741
763
 
@@ -768,4 +790,4 @@ for supported states and limits.
768
790
  ## Correlated evidence
769
791
 
770
792
  Actions and journeys expose identifiers and phase timestamps for linking later
771
- observations. See [correlated evidence](evidence.md) for scope and limitations.
793
+ observations. See [evidence correlation](correlated-evidence.md) for scope and limitations.