mobile-debug-mcp 0.33.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 (448) 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 +23 -2
  12. package/AGENTS.md +12 -3
  13. package/CONTRIBUTING.md +79 -0
  14. package/README.md +158 -124
  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 +20 -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 +113 -4
  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 +79 -0
  28. package/dist/debugger/diagnostics.js +54 -0
  29. package/dist/debugger/guard.js +30 -0
  30. package/dist/debugger/protocol.js +33 -0
  31. package/dist/debugger/sessions.js +304 -0
  32. package/dist/debugger/worker.js +176 -0
  33. package/dist/interact/adjustment/adjustment-context.js +41 -0
  34. package/dist/interact/adjustment/adjustment-gestures.js +55 -0
  35. package/dist/interact/adjustment/adjustment-plan.js +18 -0
  36. package/dist/interact/adjustment/adjustment-resolution.js +127 -0
  37. package/dist/interact/adjustment/adjustment-result.js +19 -0
  38. package/dist/interact/adjustment/adjustment-semantic.js +64 -0
  39. package/dist/interact/adjustment/adjustment-verification.js +35 -0
  40. package/dist/interact/adjustment/adjustment.js +52 -0
  41. package/dist/interact/adjustment/control-geometry.js +87 -0
  42. package/dist/interact/adjustment/control-values.js +136 -0
  43. package/dist/interact/adjustment/slider-labels.js +84 -0
  44. package/dist/interact/assertions/screen-assertion.js +37 -0
  45. package/dist/interact/assertions/state-assertion-context.js +35 -0
  46. package/dist/interact/assertions/state-assertion.js +76 -0
  47. package/dist/interact/assertions/state-comparison.js +141 -0
  48. package/dist/interact/assertions/visibility-assertion.js +34 -0
  49. package/dist/interact/conditional-action.js +12 -7
  50. package/dist/interact/index.js +65 -3074
  51. package/dist/interact/input-service.js +1 -0
  52. package/dist/interact/interaction-trace.js +21 -0
  53. package/dist/interact/model.js +1 -0
  54. package/dist/interact/observation.js +1 -0
  55. package/dist/interact/targeting/candidate-ancestor.js +58 -0
  56. package/dist/interact/targeting/candidate-result.js +23 -0
  57. package/dist/interact/targeting/candidate-scoring.js +50 -0
  58. package/dist/interact/targeting/element-helpers.js +216 -0
  59. package/dist/interact/targeting/find-element.js +65 -0
  60. package/dist/interact/targeting/nearby-control.js +56 -0
  61. package/dist/interact/targeting/resolved-elements.js +21 -0
  62. package/dist/interact/targeting/tap-target.js +17 -0
  63. package/dist/interact/targeting/target-scope.js +104 -0
  64. package/dist/interact/waits/legacy-log-wait.js +38 -0
  65. package/dist/interact/waits/legacy-wait-observations.js +103 -0
  66. package/dist/interact/waits/legacy-wait-state.js +34 -0
  67. package/dist/interact/waits/legacy-wait.js +48 -0
  68. package/dist/interact/waits/screen-wait.js +49 -0
  69. package/dist/interact/waits/ui-change-helpers.js +157 -0
  70. package/dist/interact/waits/ui-change-state.js +18 -0
  71. package/dist/interact/waits/ui-change-wait.js +77 -0
  72. package/dist/interact/waits/ui-wait-condition.js +56 -0
  73. package/dist/interact/waits/ui-wait-state.js +38 -0
  74. package/dist/interact/waits/ui-wait.js +106 -0
  75. package/dist/manage/android.js +55 -51
  76. package/dist/manage/index.js +38 -75
  77. package/dist/manage/ios/build-types.js +1 -0
  78. package/dist/manage/ios/build.js +210 -0
  79. package/dist/manage/ios/project-discovery.js +29 -0
  80. package/dist/manage/ios/scheme.js +18 -0
  81. package/dist/manage/ios.js +42 -256
  82. package/dist/observe/android/context.js +1 -0
  83. package/dist/observe/android/current-screen.js +55 -0
  84. package/dist/observe/android/fingerprint.js +13 -0
  85. package/dist/observe/android/log-stream.js +132 -0
  86. package/dist/observe/android/logs.js +107 -0
  87. package/dist/observe/android/screenshot.js +70 -0
  88. package/dist/observe/android/ui-tree.js +107 -0
  89. package/dist/observe/android.js +16 -520
  90. package/dist/observe/evidence.js +122 -76
  91. package/dist/observe/index.js +16 -263
  92. package/dist/observe/ios/context.js +16 -0
  93. package/dist/observe/ios/fingerprint.js +12 -0
  94. package/dist/observe/ios/log-stream.js +105 -0
  95. package/dist/observe/ios/logs.js +168 -0
  96. package/dist/observe/ios/screenshot.js +22 -0
  97. package/dist/observe/ios/ui-elements.js +241 -0
  98. package/dist/observe/ios/ui-tree.js +137 -0
  99. package/dist/observe/ios.js +17 -715
  100. package/dist/observe/logs/model.js +1 -0
  101. package/dist/{network → observe/network}/index.js +2 -2
  102. package/dist/observe/readiness-service.js +13 -2
  103. package/dist/observe/readiness.js +44 -18
  104. package/dist/observe/screenshot-encoding.js +41 -0
  105. package/dist/observe/snapshot-collection.js +79 -0
  106. package/dist/observe/snapshot-logs.js +30 -0
  107. package/dist/observe/snapshot-metadata.js +43 -31
  108. package/dist/observe/snapshot-semantic.js +115 -0
  109. package/dist/observe/system-trace-android.js +135 -0
  110. package/dist/observe/system-trace.js +294 -0
  111. package/dist/runtime/action-results.js +270 -0
  112. package/dist/runtime/clock.js +4 -0
  113. package/dist/server/common.js +1 -256
  114. package/dist/server/definitions/assert.js +162 -0
  115. package/dist/server/definitions/diagnostic.js +118 -0
  116. package/dist/server/definitions/input.js +274 -0
  117. package/dist/server/definitions/manage.js +194 -0
  118. package/dist/server/definitions/observe.js +149 -0
  119. package/dist/server/definitions/target.js +138 -0
  120. package/dist/server/definitions/wait.js +105 -0
  121. package/dist/server/handlers/action-execution.js +163 -0
  122. package/dist/server/handlers/correlation.js +23 -0
  123. package/dist/server/handlers/debugger-handlers.js +48 -0
  124. package/dist/server/handlers/debugger-response.js +9 -0
  125. package/dist/server/handlers/diagnostic.js +69 -0
  126. package/dist/server/handlers/handler-types.js +1 -0
  127. package/dist/server/handlers/input.js +154 -0
  128. package/dist/server/handlers/interact.js +113 -0
  129. package/dist/server/handlers/journey-assertions.js +35 -0
  130. package/dist/server/handlers/journey.js +147 -0
  131. package/dist/server/handlers/manage.js +119 -0
  132. package/dist/server/handlers/observe.js +95 -0
  133. package/dist/server/handlers/payload.js +4 -0
  134. package/dist/server/handlers/tool-handlers.js +160 -0
  135. package/dist/server/schemas/condition-schema.js +2 -0
  136. package/dist/server/schemas/debugger-schema.js +47 -0
  137. package/dist/server/{journey-schema.js → schemas/journey-schema.js} +8 -22
  138. package/dist/server/schemas/system-trace-schema.js +17 -0
  139. package/dist/server/tool-definitions.js +62 -1134
  140. package/dist/server-core.js +4 -4
  141. package/dist/server.js +34 -0
  142. package/dist/system/android-status.js +101 -0
  143. package/dist/system/android.js +37 -27
  144. package/dist/system/index.js +13 -438
  145. package/dist/system/ios-status.js +132 -0
  146. package/dist/system/ios.js +11 -8
  147. package/dist/system/model.js +1 -0
  148. package/dist/system/probes.js +105 -0
  149. package/dist/system/status-summary.js +43 -0
  150. package/dist/system/unsupported-status.js +52 -0
  151. package/dist/utils/android/commands.js +89 -0
  152. package/dist/utils/android/gradle.js +139 -0
  153. package/dist/utils/android/logs.js +103 -0
  154. package/dist/utils/android/ui-tree.js +233 -0
  155. package/dist/utils/android/utils.js +6 -564
  156. package/dist/utils/cli/idb/idb-helper.js +4 -6
  157. package/dist/utils/cli/idb/install-idb.js +13 -9
  158. package/dist/utils/cli/ios/preflight-ios.js +42 -38
  159. package/dist/utils/exec.js +2 -0
  160. package/dist/utils/ios/utils.js +45 -46
  161. package/dist/utils/java.js +75 -57
  162. package/dist/utils/operation-budget.js +2 -0
  163. package/dist/utils/resolve-device.js +6 -2
  164. package/dist/utils/ui/index.js +26 -26
  165. package/docs/CHANGELOG.md +48 -0
  166. package/docs/README.md +38 -0
  167. package/docs/benchmarks/README.md +18 -0
  168. package/docs/benchmarks/interaction-latency/README.md +14 -0
  169. package/docs/benchmarks/interaction-latency/final.md +4 -1
  170. package/docs/benchmarks/interaction-latency/ios-validation.md +2 -0
  171. package/docs/benchmarks/ui-tree-performance/README.md +24 -16
  172. package/docs/benchmarks/ui-tree-performance/comparison.md +11 -10
  173. package/docs/code-structure.md +118 -0
  174. package/docs/specs/001-state-verification/spec.md +16 -14
  175. package/docs/specs/002-richer-element-identity/spec.md +12 -10
  176. package/docs/specs/003-wait-and-synchronization-reliability/spec.md +12 -10
  177. package/docs/specs/004-action-verification-routing/spec.md +3 -3
  178. package/docs/specs/005-unified-action-execution-and-verification-model/spec.md +2 -0
  179. package/docs/specs/006-runtime-action-instrumentation-and-binding-layer/spec.md +2 -0
  180. package/docs/specs/007-actionability-resolution-and-executable-target-selection/spec.md +3 -1
  181. package/docs/specs/008-adjustable-control-support-and-semantic-value-manipulation/spec.md +3 -4
  182. package/docs/specs/009-semantic-control-modeling-for-custom-and-composite-controls/spec.md +2 -0
  183. package/docs/specs/010-verification-stabilization-and-temporal-convergence/spec.md +2 -2
  184. package/docs/specs/011-recovery-and-replanning-for-failed-or-ambiguous-interaction-flows/spec.md +2 -2
  185. package/docs/specs/011.1-recovery-contract-types-and-runtime-wiring-spec/spec.md +2 -0
  186. package/docs/specs/012-action-trace-and-xecution-observability/spec.md +2 -3
  187. package/docs/specs/013-wait-and-synchronization-reliability/spec.md +19 -19
  188. package/docs/specs/014-actionability-resolution/spec.md +20 -18
  189. package/docs/specs/015-adjustable-control-support/spec.md +17 -15
  190. package/docs/specs/016-environment-tools/spec.md +20 -20
  191. package/docs/specs/018-interaction-latency-and-batched-journeys/spec.md +2 -0
  192. package/docs/specs/019-ui-tree-observation-performance/spec.md +3 -1
  193. package/docs/specs/020-conditional-actions/intent.md +5 -3
  194. package/docs/specs/020-conditional-actions/plan.md +8 -9
  195. package/docs/specs/020-conditional-actions/spec.md +4 -2
  196. package/docs/specs/021-app-readiness-signals/intent.md +4 -2
  197. package/docs/specs/021-app-readiness-signals/plan.md +7 -6
  198. package/docs/specs/021-app-readiness-signals/spec.md +3 -1
  199. package/docs/specs/022-correlated-evidence/intent.md +4 -4
  200. package/docs/specs/022-correlated-evidence/plan.md +10 -11
  201. package/docs/specs/022-correlated-evidence/spec.md +3 -1
  202. package/docs/specs/023-android-system-traces/device-evidence.json +38 -0
  203. package/docs/specs/023-android-system-traces/emulator-recheck.json +38 -0
  204. package/docs/specs/023-android-system-traces/intent.md +41 -0
  205. package/docs/specs/023-android-system-traces/plan.md +115 -0
  206. package/docs/specs/023-android-system-traces/spec.md +122 -0
  207. package/docs/specs/024-android-heap-dump-capture/intent.md +41 -0
  208. package/docs/specs/025-android-runtime-debugger/intent.md +41 -0
  209. package/docs/specs/025-android-runtime-debugger/plan.md +106 -0
  210. package/docs/specs/025-android-runtime-debugger/spec.md +183 -0
  211. package/docs/specs/026-code-structure-and-quality-gates/health-plan.md +88 -0
  212. package/docs/specs/026-code-structure-and-quality-gates/intent.md +47 -0
  213. package/docs/specs/026-code-structure-and-quality-gates/plan.md +191 -0
  214. package/docs/specs/026-code-structure-and-quality-gates/spec.md +138 -0
  215. package/docs/specs/026-code-structure-and-quality-gates/verification-final.json +200 -0
  216. package/docs/specs/026-code-structure-and-quality-gates/verification-thin-facade.json +154 -0
  217. package/docs/specs/026-code-structure-and-quality-gates/verification.json +136 -0
  218. package/docs/specs/027-debugger-failure-diagnostics/intent.md +43 -0
  219. package/docs/specs/027-debugger-failure-diagnostics/plan.md +86 -0
  220. package/docs/specs/027-debugger-failure-diagnostics/spec.md +133 -0
  221. package/docs/specs/028-compact-debugger-responses/intent.md +41 -0
  222. package/docs/specs/028-compact-debugger-responses/plan.md +112 -0
  223. package/docs/specs/028-compact-debugger-responses/spec.md +108 -0
  224. package/docs/specs/029-kotlin-locals-validation/report.md +119 -0
  225. package/docs/specs/030-android-coroutine-validation/evidence.json +475 -0
  226. package/docs/specs/030-android-coroutine-validation/intent.md +47 -0
  227. package/docs/specs/030-android-coroutine-validation/plan.md +147 -0
  228. package/docs/specs/030-android-coroutine-validation/report.md +240 -0
  229. package/docs/specs/030-android-coroutine-validation/spec.md +107 -0
  230. package/docs/tools/TOOLS.md +31 -16
  231. package/docs/tools/{evidence.md → correlated-evidence.md} +14 -3
  232. package/docs/tools/debugger.md +180 -0
  233. package/docs/tools/interact.md +42 -20
  234. package/docs/tools/manage.md +25 -44
  235. package/docs/tools/observe.md +64 -25
  236. package/docs/tools/system-traces.md +134 -0
  237. package/docs/tools/system.md +12 -5
  238. package/package.json +11 -8
  239. package/scripts/architecture-graph.mjs +69 -0
  240. package/scripts/check-architecture.mjs +47 -0
  241. package/scripts/code-quality-baseline.json +1 -0
  242. package/scripts/code-quality.mjs +161 -0
  243. package/src/contracts/execution-controls.ts +26 -0
  244. package/src/contracts/selector.ts +17 -0
  245. package/src/contracts/target.ts +19 -0
  246. package/src/contracts/ui.ts +94 -0
  247. package/src/debugger/android.ts +66 -0
  248. package/src/debugger/diagnostics.ts +43 -0
  249. package/src/debugger/guard.ts +31 -0
  250. package/src/debugger/java/DebuggerWorker.java +166 -0
  251. package/src/debugger/protocol.ts +37 -0
  252. package/src/debugger/sessions.ts +327 -0
  253. package/src/debugger/worker.ts +135 -0
  254. package/src/interact/adjustment/adjustment-context.ts +83 -0
  255. package/src/interact/adjustment/adjustment-gestures.ts +48 -0
  256. package/src/interact/adjustment/adjustment-plan.ts +23 -0
  257. package/src/interact/adjustment/adjustment-resolution.ts +104 -0
  258. package/src/interact/adjustment/adjustment-result.ts +34 -0
  259. package/src/interact/adjustment/adjustment-semantic.ts +53 -0
  260. package/src/interact/adjustment/adjustment-verification.ts +60 -0
  261. package/src/interact/adjustment/adjustment.ts +49 -0
  262. package/src/interact/adjustment/control-geometry.ts +120 -0
  263. package/src/interact/adjustment/control-values.ts +141 -0
  264. package/src/interact/adjustment/slider-labels.ts +84 -0
  265. package/src/interact/assertions/screen-assertion.ts +39 -0
  266. package/src/interact/assertions/state-assertion-context.ts +48 -0
  267. package/src/interact/assertions/state-assertion.ts +64 -0
  268. package/src/interact/assertions/state-comparison.ts +168 -0
  269. package/src/interact/assertions/visibility-assertion.ts +41 -0
  270. package/src/interact/conditional-action.ts +18 -12
  271. package/src/interact/index.ts +76 -3491
  272. package/src/interact/input-service.ts +11 -0
  273. package/src/interact/interaction-trace.ts +36 -0
  274. package/src/interact/model.ts +109 -0
  275. package/src/interact/observation.ts +7 -0
  276. package/src/interact/targeting/candidate-ancestor.ts +49 -0
  277. package/src/interact/targeting/candidate-result.ts +24 -0
  278. package/src/interact/targeting/candidate-scoring.ts +42 -0
  279. package/src/interact/targeting/element-helpers.ts +243 -0
  280. package/src/interact/targeting/find-element.ts +47 -0
  281. package/src/interact/targeting/nearby-control.ts +46 -0
  282. package/src/interact/targeting/resolved-elements.ts +20 -0
  283. package/src/interact/targeting/tap-target.ts +22 -0
  284. package/src/interact/targeting/target-scope.ts +121 -0
  285. package/src/interact/waits/legacy-log-wait.ts +30 -0
  286. package/src/interact/waits/legacy-wait-observations.ts +55 -0
  287. package/src/interact/waits/legacy-wait-state.ts +48 -0
  288. package/src/interact/waits/legacy-wait.ts +34 -0
  289. package/src/interact/waits/screen-wait.ts +37 -0
  290. package/src/interact/waits/ui-change-helpers.ts +184 -0
  291. package/src/interact/waits/ui-change-state.ts +26 -0
  292. package/src/interact/waits/ui-change-wait.ts +59 -0
  293. package/src/interact/waits/ui-wait-condition.ts +52 -0
  294. package/src/interact/waits/ui-wait-state.ts +55 -0
  295. package/src/interact/waits/ui-wait.ts +84 -0
  296. package/src/manage/android.ts +56 -50
  297. package/src/manage/index.ts +63 -93
  298. package/src/manage/ios/build-types.ts +14 -0
  299. package/src/manage/ios/build.ts +230 -0
  300. package/src/manage/ios/project-discovery.ts +26 -0
  301. package/src/manage/ios/scheme.ts +16 -0
  302. package/src/manage/ios.ts +65 -298
  303. package/src/observe/android/context.ts +1 -0
  304. package/src/observe/android/current-screen.ts +63 -0
  305. package/src/observe/android/fingerprint.ts +13 -0
  306. package/src/observe/android/log-stream.ts +127 -0
  307. package/src/observe/android/logs.ts +110 -0
  308. package/src/observe/android/screenshot.ts +79 -0
  309. package/src/observe/android/ui-tree.ts +113 -0
  310. package/src/observe/android.ts +17 -531
  311. package/src/observe/evidence.ts +130 -71
  312. package/src/observe/index.ts +24 -286
  313. package/src/observe/ios/context.ts +22 -0
  314. package/src/observe/ios/fingerprint.ts +12 -0
  315. package/src/observe/ios/log-stream.ts +103 -0
  316. package/src/observe/ios/logs.ts +179 -0
  317. package/src/observe/ios/screenshot.ts +26 -0
  318. package/src/observe/ios/ui-elements.ts +266 -0
  319. package/src/observe/ios/ui-tree.ts +143 -0
  320. package/src/observe/ios.ts +18 -749
  321. package/src/observe/logs/model.ts +11 -0
  322. package/src/{network → observe/network}/index.ts +2 -2
  323. package/src/observe/readiness-service.ts +10 -3
  324. package/src/observe/readiness.ts +49 -22
  325. package/src/observe/screenshot-encoding.ts +32 -0
  326. package/src/observe/snapshot-collection.ts +69 -0
  327. package/src/observe/snapshot-logs.ts +26 -0
  328. package/src/observe/snapshot-metadata.ts +51 -31
  329. package/src/observe/snapshot-semantic.ts +153 -0
  330. package/src/observe/system-trace-android.ts +133 -0
  331. package/src/observe/system-trace.ts +227 -0
  332. package/src/runtime/action-results.ts +376 -0
  333. package/src/runtime/clock.ts +9 -0
  334. package/src/server/common.ts +9 -359
  335. package/src/server/definitions/assert.ts +164 -0
  336. package/src/server/definitions/diagnostic.ts +120 -0
  337. package/src/server/definitions/input.ts +276 -0
  338. package/src/server/definitions/manage.ts +196 -0
  339. package/src/server/definitions/observe.ts +151 -0
  340. package/src/server/definitions/target.ts +140 -0
  341. package/src/server/definitions/wait.ts +107 -0
  342. package/src/server/handlers/action-execution.ts +164 -0
  343. package/src/server/handlers/correlation.ts +20 -0
  344. package/src/server/handlers/debugger-handlers.ts +39 -0
  345. package/src/server/handlers/debugger-response.ts +7 -0
  346. package/src/server/handlers/diagnostic.ts +79 -0
  347. package/src/server/handlers/handler-types.ts +7 -0
  348. package/src/server/handlers/input.ts +173 -0
  349. package/src/server/handlers/interact.ts +135 -0
  350. package/src/server/handlers/journey-assertions.ts +39 -0
  351. package/src/server/handlers/journey.ts +132 -0
  352. package/src/server/handlers/manage.ts +141 -0
  353. package/src/server/handlers/observe.ts +116 -0
  354. package/src/server/handlers/payload.ts +36 -0
  355. package/src/server/handlers/tool-handlers.ts +159 -0
  356. package/src/server/schemas/condition-schema.ts +2 -0
  357. package/src/server/schemas/debugger-schema.ts +43 -0
  358. package/src/server/{journey-schema.ts → schemas/journey-schema.ts} +8 -22
  359. package/src/server/schemas/system-trace-schema.ts +17 -0
  360. package/src/server/tool-definitions.ts +69 -1140
  361. package/src/server-core.ts +4 -4
  362. package/src/server.ts +25 -1
  363. package/src/system/android-status.ts +124 -0
  364. package/src/system/android.ts +33 -21
  365. package/src/system/index.ts +21 -523
  366. package/src/system/ios-status.ts +147 -0
  367. package/src/system/ios.ts +14 -10
  368. package/src/system/model.ts +41 -0
  369. package/src/system/probes.ts +114 -0
  370. package/src/system/status-summary.ts +47 -0
  371. package/src/system/unsupported-status.ts +55 -0
  372. package/src/types.ts +16 -106
  373. package/src/utils/android/commands.ts +81 -0
  374. package/src/utils/android/gradle.ts +132 -0
  375. package/src/utils/android/logs.ts +103 -0
  376. package/src/utils/android/ui-tree.ts +239 -0
  377. package/src/utils/android/utils.ts +16 -556
  378. package/src/utils/cli/idb/check-idb.ts +4 -4
  379. package/src/utils/cli/idb/idb-helper.ts +6 -8
  380. package/src/utils/cli/idb/install-idb.ts +15 -9
  381. package/src/utils/cli/ios/preflight-ios.ts +39 -31
  382. package/src/utils/cli/ios/run-ios-ui-tree-tap.ts +4 -4
  383. package/src/utils/exec.ts +2 -0
  384. package/src/utils/ios/utils.ts +57 -61
  385. package/src/utils/java.ts +71 -51
  386. package/src/utils/operation-budget.ts +2 -0
  387. package/src/utils/resolve-device.ts +11 -6
  388. package/src/utils/ui/index.ts +28 -28
  389. package/test/device/automated/debugger/coroutine-lifecycle.ts +27 -0
  390. package/test/device/automated/debugger/coroutine-support.ts +140 -0
  391. package/test/device/automated/debugger/coroutine.android.test.ts +169 -0
  392. package/test/device/automated/debugger/kotlin.android.test.ts +127 -0
  393. package/test/device/automated/debugger/runtime.android.test.ts +219 -0
  394. package/test/device/automated/interact/interaction.android.test.ts +56 -0
  395. package/test/device/automated/observe/system-trace.smoke.ts +104 -0
  396. package/test/device/manual/interact/modul8_selector_tap.manual.ts +1 -1
  397. package/test/fixtures/contracts/tool-definitions.json +3536 -0
  398. package/test/fixtures/coroutine-app/MainActivity.kt +100 -0
  399. package/test/fixtures/coroutine-app/README.md +48 -0
  400. package/test/fixtures/coroutine-app/build.ts +35 -0
  401. package/test/fixtures/debugger-app/MainActivity.java +67 -0
  402. package/test/fixtures/debugger-app/MainActivity.kt +32 -0
  403. package/test/fixtures/debugger-app/NoLocals.java +7 -0
  404. package/test/fixtures/debugger-app/README.md +65 -0
  405. package/test/fixtures/debugger-app/build.ts +39 -0
  406. package/test/fixtures/latency-journey-app/README.md +2 -0
  407. package/test/fixtures/readiness-app/README.md +2 -0
  408. package/test/helpers/perfetto.ts +59 -0
  409. package/test/unit/debugger/coroutine-lifecycle.test.ts +43 -0
  410. package/test/unit/debugger/diagnostic-sessions.test.ts +67 -0
  411. package/test/unit/debugger/diagnostics.test.ts +80 -0
  412. package/test/unit/debugger/guards.test.ts +50 -0
  413. package/test/unit/debugger/native.test.ts +33 -0
  414. package/test/unit/debugger/preparation.test.ts +32 -0
  415. package/test/unit/debugger/protocol.test.ts +15 -0
  416. package/test/unit/debugger/sessions.test.ts +83 -0
  417. package/test/unit/interact/adjustment_service.test.ts +42 -0
  418. package/test/unit/interact/adjustment_verification.test.ts +35 -0
  419. package/test/unit/interact/clock_dependencies.test.ts +63 -0
  420. package/test/unit/interact/element_helpers.test.ts +19 -0
  421. package/test/unit/interact/legacy_wait_service.test.ts +17 -0
  422. package/test/unit/interact/state_comparison.test.ts +20 -0
  423. package/test/unit/interact/target_scope.test.ts +35 -0
  424. package/test/unit/network/get_network_activity.test.ts +1 -1
  425. package/test/unit/observe/readiness.test.ts +3 -1
  426. package/test/unit/observe/screenshot-encoding.test.ts +30 -0
  427. package/test/unit/observe/snapshot-logs.test.ts +14 -0
  428. package/test/unit/observe/system-trace-android.test.ts +52 -0
  429. package/test/unit/observe/system-trace.test.ts +166 -0
  430. package/test/unit/quality/architecture.test.ts +60 -0
  431. package/test/unit/quality/code-quality.test.ts +58 -0
  432. package/test/unit/quality/interaction_boundaries.test.ts +24 -0
  433. package/test/unit/server/conditional_actions.test.ts +1 -1
  434. package/test/unit/server/conditional_schema.test.ts +2 -2
  435. package/test/unit/server/debugger-response.test.ts +63 -0
  436. package/test/unit/server/system-trace.test.ts +64 -0
  437. package/test/unit/server/tool_definitions_parity.test.ts +8 -0
  438. package/dist/server/tool-handlers.js +0 -893
  439. package/docs/ROADMAP.md +0 -646
  440. package/docs/benchmarks/ui-tree-performance/bridge-probe.json +0 -29
  441. package/docs/benchmarks/ui-tree-performance/initial-baseline.json +0 -59560
  442. package/docs/specs/baseline-spec-v0.md +0 -312
  443. package/docs/specs/mcp-tooling-spec-v1.md +0 -446
  444. package/src/server/tool-handlers.ts +0 -923
  445. /package/dist/{server/condition-schema.js → contracts/condition.js} +0 -0
  446. /package/dist/server/{readiness-schema.js → schemas/readiness-schema.js} +0 -0
  447. /package/src/{server/condition-schema.ts → contracts/condition.ts} +0 -0
  448. /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,25 +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).
7
+ ## Reference guides
12
8
 
13
- ## 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.
14
16
 
15
- For interactive flows, the intended deterministic pattern is:
17
+ ## Interaction principles
16
18
 
17
- **RESOLVE -> ACT -> WAIT (if needed) -> EXPECT**
19
+ Interactive flows follow a common sequence:
18
20
 
19
- - **wait_for_\*** tools are for resolution and synchronization
20
- - **expect_\*** tools are for final outcome verification
21
- - observation tools are supporting context, not primary success signals
21
+ **RESOLVE → ACT → WAIT (if needed) → EXPECT**
22
22
 
23
- 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.
24
29
 
25
- 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
@@ -73,7 +81,10 @@ after it, or causality. No implicit action-window filtering is applied.
73
81
 
74
82
  Existing payloads, image blocks, and log blocks remain available. Snapshot evidence
75
83
  sits alongside `raw` and `semantic`. Android ADB and supported iOS simulators share
76
- this contract; existing provider limitations still apply. `trace_context` reports
77
- `{ "supported": false, "trace_id": null, "markers": [] }` for future trace linkage.
84
+ this contract; existing provider limitations still apply. `trace_context` defaults
85
+ to `{ "supported": false, "trace_id": null, "markers": [] }`. Journeys explicitly
86
+ linked to an active Android [system trace](system-traces.md) and their steps expose
87
+ `{ "supported": true, "trace_id": "…", "markers": [] }`; association does not align
88
+ clocks or inject device markers.
78
89
  Correlation history stores identifiers, scope, timing, and ordering only, without
79
90
  captured content, arguments, persistence, or telemetry.
@@ -0,0 +1,180 @@
1
+ # Android runtime debugger
2
+
3
+ [Documentation](../README.md) · [Tool reference](TOOLS.md)
4
+
5
+ Optional managed Java/Kotlin bytecode debugging through an independently developed
6
+ JDI worker. Requires JDK 17+ (`java`, `javac`, `jdk.jdi`), Android platform-tools,
7
+ an authorized device and an already-running JDWP-visible debuggable app.
8
+ Android Studio JBR/standard JDK discovery follows existing Java helpers; `ADB_PATH`
9
+ is supported. The worker is compiled on demand into a private source/JDK-keyed
10
+ host temporary cache. Ordinary tools do not require Java or start a debugger.
11
+ Cache directories named `mobile-debug-jdi-*` can be removed when the server exits.
12
+
13
+ ## Tools and flow
14
+
15
+ 1. `get_debugger_capabilities` with `platform: "android"`, explicit `deviceId`,
16
+ `appId`, and optional positive `processId` probes prerequisites/candidate processes.
17
+ General `get_system_status` does not establish target-specific debugger readiness.
18
+ 2. `attach_debugger` with the same target returns `debug_session_id`. If multiple
19
+ matching debuggable processes exist, provide `processId`. Package UID, process
20
+ name, PID and process-start identity are checked. Other debuggers are not replaced.
21
+ 3. `set_debugger_breakpoint` takes `debugSessionId`, exact binary `className` and
22
+ 1-based executable `line`. It returns `result.breakpoint_id`, status and resolved
23
+ source locations/class-loader IDs. Unloaded classes remain `pending`; missing
24
+ line metadata is rejected explicitly. No automatic source search/line relocation.
25
+ 4. Trigger execution, then `wait_for_debugger_event` with `debugSessionId` and
26
+ `afterSequence` (initially zero). Retain `next_cursor`. Stop events contain
27
+ `stop_id`, `thread_id` and source locations. A step acknowledgement is not a stop.
28
+ 5. `get_debugger_stack` takes `debugSessionId`, `stopId`, `threadId`, optional
29
+ `offset` and `limit` (20 default, 100 maximum; 1000-frame cap).
30
+ `get_debugger_locals` takes `debugSessionId`, `stopId`, `frameId`. It returns
31
+ `result.availability`, up to 100 shallow locals, and truncation information.
32
+ Primitive values are textual; strings truncate at 256 characters; objects have
33
+ type/identity summaries. Missing variable metadata is explicit. ART can return an empty table without
34
+ distinguishing absent metadata from a genuinely empty scope; these responses
35
+ use `availability: "unknown"`, `reason: "EMPTY_OR_UNAVAILABLE_VARIABLE_METADATA"`.
36
+ 6. `step_debugger` takes `debugSessionId`, current `stopId`, `threadId` and
37
+ `kind: "into" | "over" | "out"`. It resumes and requests one line step.
38
+ `resume_debugger` takes `debugSessionId`, `stopId`. Both expire all old stop,
39
+ thread and frame references. Await the next stop using the event cursor.
40
+ 7. `remove_debugger_breakpoint` takes `debugSessionId`, `breakpointId` and is
41
+ idempotent for an owned ID. `get_debugger_state` reads stop, breakpoint, terminal
42
+ reason and cleanup status. `detach_debugger` disposes the session and supports
43
+ repeated calls/retrying incomplete cleanup.
44
+
45
+ Every tool accepts integer `timeoutMs`, 100–30000 (default 10000; event waits
46
+ 1000). Unknown arguments are rejected. Other strings are limited to 512 characters.
47
+ All session tools use camelCase input IDs; response fields use snake_case.
48
+ Successful operation payloads are under `result` where applicable; common fields
49
+ include `success`, `debug_session_id`, `device`, `target`, `state`,
50
+ `captured_at_ms`, `capabilities`, `limitations`, `cleanup`, `reason`, and `stop`.
51
+ Failures carry `error: {code, message, retryable}`. Event polls use top-level
52
+ `events`, `next_cursor`, `overflow`, `timed_out`; empty waits are successful.
53
+ The 256-event ring returns at most 100 entries; overflow must not be ignored.
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
+
103
+ ## Suspension, limits and cleanup
104
+
105
+ Stops suspend all app threads. UI actions, app lifecycle/data changes, waits and
106
+ assertions on that device return `DEBUGGER_PAUSED`; inputs are not queued. A pause
107
+ racing input submission preserves delivery uncertainty and blocks verification.
108
+ Journeys preserve completed steps. Other devices are unaffected.
109
+
110
+ `get_app_readiness` returns evidence-backed `debugger_paused` without reading the
111
+ UI; readiness waits fail with `DEBUGGER_PAUSED`. This signal covers managed Android
112
+ sessions only and does not establish foreground app identity. Raw trees, screenshots
113
+ and logs remain available within their own timeouts; snapshot/log acquisition may
114
+ still fail while the app is suspended. Known pauses are annotated on observations.
115
+
116
+ The worker and host enforce automatic detach after 60 seconds continuously paused,
117
+ five minutes without client commands or 30 minutes total. Polling cannot extend
118
+ the pause or total limit. One active session per device, four per server; at most
119
+ 100 distinct breakpoint IDs per session. Terminal summaries expire after ten
120
+ minutes and are capped at 100; inspection values and event history are cleared.
121
+
122
+ Detach releases debugger-owned suspension and removes only owned requests,
123
+ worker and the exact ADB forward. Cleanup is bounded separately to ten seconds;
124
+ retry `detach_debugger` if `cleanup.status` is `failed`. Never kill an app or ADB
125
+ server to clean up. Unexpected worker/transport loss reports execution state as
126
+ unknown; no resumption claim is inferred. Hard host/device loss can prevent
127
+ confirmed cleanup. Server shutdown and worker parent-pipe EOF request cleanup.
128
+
129
+ MCP request cancellation is supported. Cancelling an event wait leaves the
130
+ session intact. Inspection cancellation/timeouts preserve a known session;
131
+ uncertain mutation/attach outcomes trigger teardown. Do not automatically retry
132
+ step, resume or attach.
133
+
134
+ ## Limits, privacy and evidence
135
+
136
+ There is no expression evaluation, object traversal, method invocation, mutation,
137
+ coroutine reconstruction, native debugger, iOS debugger or heap capture. Kotlin
138
+ results follow emitted bytecode/debug metadata; optimized/obfuscated apps may lack
139
+ useful source lines or locals. Locals may contain private data: values are returned
140
+ only on request, without protocol/value logging, persistent dumps or upload.
141
+ Worker heap is capped at 128 MiB; IPC and messages are bounded; forwarding remains loopback-only.
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
+
161
+ Verified environments and remaining checks are recorded in
162
+ [the implementation plan](../specs/025-android-runtime-debugger/plan.md).
163
+ To run the isolated fixture journey (installs then removes its own test package):
164
+
165
+ ```sh
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
169
+ # Also exercise the real 60-second pause expiry:
170
+ MCP_DEBUGGER_DEVICE=emulator-5554 MCP_DEBUGGER_EXTENDED=1 npx tsx test/device/automated/debugger/runtime.android.test.ts
171
+ ```
172
+
173
+ The ordinary device suite explicitly reports this journey unrun unless the device
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.