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,475 @@
1
+ {
2
+ "status": "PASS",
3
+ "device": "emulator-5554",
4
+ "api": "36",
5
+ "runtime": "v22.23.4",
6
+ "source_sha256": "5978b835673876642c256b1c688975e78018addc1f68219371bc47c8cc29a92b",
7
+ "apk_sha256": "65d6bc4931f6532a7488da10fde9e211b75172ed0bb8d04fcc372bc0765b48ef",
8
+ "dist_sha256": "4f7bf452fc0022c8feb492f11a25c34ac5e360baff9f77d752dd0d248105d581",
9
+ "worker_sha256": "fb15e7add65fb3682d86153818d02378084a46fcd49b2c23c0eafdba290f8323",
10
+ "compiler": "info: kotlinc-jvm 2.0.21 (JRE 17.0.11+7-LTS-207)",
11
+ "dependencies": [
12
+ {
13
+ "name": "MCP_KOTLIN_STDLIB",
14
+ "sha256": "f31cc53f105a7e48c093683bbd5437561d1233920513774b470805641bedbc09"
15
+ },
16
+ {
17
+ "name": "MCP_COROUTINES_CORE",
18
+ "sha256": "ad89c2892235e670f222d819cb3d81188143cb19a05b59df9889ae4269f5c70a"
19
+ }
20
+ ],
21
+ "metadata_sha256": "8988c515f6b1e345d6f9d8910bcb12c5f65f57b2b5cd454b27c4eca587b0b3f1",
22
+ "observations": [
23
+ {
24
+ "marker": "BREAK_BEFORE",
25
+ "location": {
26
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
27
+ "method": "completeWork",
28
+ "source": "MainActivity.kt",
29
+ "line": 53,
30
+ "code_index": 73,
31
+ "class_loader_id": "2"
32
+ }
33
+ },
34
+ {
35
+ "label": "before suspension",
36
+ "top_frame": {
37
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
38
+ "method": "completeWork",
39
+ "source": "MainActivity.kt",
40
+ "line": 53,
41
+ "code_index": 73,
42
+ "class_loader_id": "2"
43
+ },
44
+ "locals": {
45
+ "availability": "available",
46
+ "locals": [
47
+ {
48
+ "name": "$completion",
49
+ "type": "kotlin.coroutines.Continuation",
50
+ "value": {
51
+ "object_id": "158",
52
+ "type": "dev.mobiledebugmcp.coroutinefixture.MainActivity$start$1"
53
+ },
54
+ "truncated": false
55
+ },
56
+ {
57
+ "name": "$continuation",
58
+ "type": "kotlin.coroutines.Continuation",
59
+ "value": {
60
+ "object_id": "159",
61
+ "type": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$1"
62
+ },
63
+ "truncated": false
64
+ },
65
+ {
66
+ "name": "$result",
67
+ "type": "java.lang.Object",
68
+ "value": null,
69
+ "truncated": false
70
+ },
71
+ {
72
+ "name": "firstThread",
73
+ "type": "java.lang.String",
74
+ "value": "fixture-first",
75
+ "truncated": false
76
+ },
77
+ {
78
+ "name": "known",
79
+ "type": "int",
80
+ "value": "42",
81
+ "truncated": false
82
+ }
83
+ ],
84
+ "truncated": false
85
+ }
86
+ },
87
+ {
88
+ "marker": "BREAK_AFTER",
89
+ "location": {
90
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
91
+ "method": "completeWork",
92
+ "source": "MainActivity.kt",
93
+ "line": 56,
94
+ "code_index": 102,
95
+ "class_loader_id": "2"
96
+ }
97
+ },
98
+ {
99
+ "label": "after suspension",
100
+ "top_frame": {
101
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
102
+ "method": "completeWork",
103
+ "source": "MainActivity.kt",
104
+ "line": 56,
105
+ "code_index": 102,
106
+ "class_loader_id": "2"
107
+ },
108
+ "locals": {
109
+ "availability": "available",
110
+ "locals": [
111
+ {
112
+ "name": "$completion",
113
+ "type": "kotlin.coroutines.Continuation",
114
+ "value": {
115
+ "object_id": "159",
116
+ "type": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$1"
117
+ },
118
+ "truncated": false
119
+ },
120
+ {
121
+ "name": "$continuation",
122
+ "type": "kotlin.coroutines.Continuation",
123
+ "value": {
124
+ "object_id": "159",
125
+ "type": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$1"
126
+ },
127
+ "truncated": false
128
+ },
129
+ {
130
+ "name": "$result",
131
+ "type": "java.lang.Object",
132
+ "value": {
133
+ "object_id": "177",
134
+ "type": "kotlin.Unit"
135
+ },
136
+ "truncated": false
137
+ },
138
+ {
139
+ "name": "known",
140
+ "type": "int",
141
+ "value": "42",
142
+ "truncated": false
143
+ }
144
+ ],
145
+ "truncated": false
146
+ }
147
+ },
148
+ {
149
+ "marker": "BREAK_DISPATCH",
150
+ "location": {
151
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$2",
152
+ "method": "invokeSuspend",
153
+ "source": "MainActivity.kt",
154
+ "line": 59,
155
+ "code_index": 38,
156
+ "class_loader_id": "2"
157
+ }
158
+ },
159
+ {
160
+ "label": "second dispatcher",
161
+ "top_frame": {
162
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$2",
163
+ "method": "invokeSuspend",
164
+ "source": "MainActivity.kt",
165
+ "line": 59,
166
+ "code_index": 38,
167
+ "class_loader_id": "2"
168
+ },
169
+ "locals": {
170
+ "availability": "available",
171
+ "locals": [
172
+ {
173
+ "name": "$result",
174
+ "type": "java.lang.Object",
175
+ "value": {
176
+ "object_id": "177",
177
+ "type": "kotlin.Unit"
178
+ },
179
+ "truncated": false
180
+ },
181
+ {
182
+ "name": "$this$withContext",
183
+ "type": "kotlinx.coroutines.CoroutineScope",
184
+ "value": {
185
+ "object_id": "181",
186
+ "type": "kotlinx.coroutines.DispatchedCoroutine"
187
+ },
188
+ "truncated": false
189
+ },
190
+ {
191
+ "name": "dispatcherThread",
192
+ "type": "java.lang.String",
193
+ "value": "fixture-second",
194
+ "truncated": false
195
+ }
196
+ ],
197
+ "truncated": false
198
+ }
199
+ },
200
+ {
201
+ "marker": "BREAK_HELPER",
202
+ "location": {
203
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
204
+ "method": "helper",
205
+ "source": "MainActivity.kt",
206
+ "line": 67,
207
+ "code_index": 0,
208
+ "class_loader_id": "2"
209
+ }
210
+ },
211
+ {
212
+ "label": "nested child helper",
213
+ "top_frame": {
214
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
215
+ "method": "helper",
216
+ "source": "MainActivity.kt",
217
+ "line": 67,
218
+ "code_index": 0,
219
+ "class_loader_id": "2"
220
+ },
221
+ "locals": {
222
+ "availability": "available",
223
+ "locals": [
224
+ {
225
+ "name": "value",
226
+ "type": "int",
227
+ "value": "43",
228
+ "truncated": false
229
+ }
230
+ ],
231
+ "truncated": false
232
+ }
233
+ },
234
+ {
235
+ "marker": "BREAK_INCREMENT",
236
+ "location": {
237
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
238
+ "method": "increment",
239
+ "source": "MainActivity.kt",
240
+ "line": 72,
241
+ "code_index": 0,
242
+ "class_loader_id": "2"
243
+ }
244
+ },
245
+ {
246
+ "marker": "BREAK_INCREMENT_RETURN",
247
+ "location": {
248
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
249
+ "method": "increment",
250
+ "source": "MainActivity.kt",
251
+ "line": 73,
252
+ "code_index": 2,
253
+ "class_loader_id": "2"
254
+ }
255
+ },
256
+ {
257
+ "stop": {
258
+ "event": "stopped",
259
+ "state": "paused",
260
+ "stop_id": "c2a29373-ce16-46e3-9fa8-f6793f92f8e6",
261
+ "thread_id": "c2a29373-ce16-46e3-9fa8-f6793f92f8e6:180",
262
+ "stops": [
263
+ {
264
+ "reason": "step",
265
+ "location": {
266
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
267
+ "method": "helper",
268
+ "source": "MainActivity.kt",
269
+ "line": 67,
270
+ "code_index": 3,
271
+ "class_loader_id": "2"
272
+ }
273
+ }
274
+ ],
275
+ "sequence": 7,
276
+ "received_at_ms": 1793639490534
277
+ }
278
+ },
279
+ {
280
+ "marker": "BREAK_RESULT",
281
+ "location": {
282
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$2",
283
+ "method": "invokeSuspend",
284
+ "source": "MainActivity.kt",
285
+ "line": 62,
286
+ "code_index": 88,
287
+ "class_loader_id": "2"
288
+ }
289
+ },
290
+ {
291
+ "label": "nested result",
292
+ "top_frame": {
293
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$2",
294
+ "method": "invokeSuspend",
295
+ "source": "MainActivity.kt",
296
+ "line": 62,
297
+ "code_index": 88,
298
+ "class_loader_id": "2"
299
+ },
300
+ "locals": {
301
+ "availability": "available",
302
+ "locals": [
303
+ {
304
+ "name": "$result",
305
+ "type": "java.lang.Object",
306
+ "value": {
307
+ "object_id": "184",
308
+ "type": "java.lang.Integer"
309
+ },
310
+ "truncated": false
311
+ },
312
+ {
313
+ "name": "answer",
314
+ "type": "int",
315
+ "value": "44",
316
+ "truncated": false
317
+ }
318
+ ],
319
+ "truncated": false
320
+ }
321
+ },
322
+ {
323
+ "journey": "completion, breakpoint workaround, synchronous steps, guards, cancelled wait",
324
+ "status": "PASS"
325
+ },
326
+ {
327
+ "marker": "BREAK_SUSPEND",
328
+ "location": {
329
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
330
+ "method": "completeWork",
331
+ "source": "MainActivity.kt",
332
+ "line": 55,
333
+ "code_index": 86,
334
+ "class_loader_id": "2"
335
+ }
336
+ },
337
+ {
338
+ "stop": {
339
+ "event": "stopped",
340
+ "state": "paused",
341
+ "stop_id": "f4dfa658-f209-467b-98bc-f207cf3721f9",
342
+ "thread_id": "f4dfa658-f209-467b-98bc-f207cf3721f9:3",
343
+ "stops": [
344
+ {
345
+ "reason": "step",
346
+ "location": {
347
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
348
+ "method": "completeWork",
349
+ "source": "MainActivity.kt",
350
+ "line": 50,
351
+ "code_index": 100,
352
+ "class_loader_id": "2"
353
+ }
354
+ }
355
+ ],
356
+ "sequence": 2,
357
+ "received_at_ms": 1793639498222
358
+ }
359
+ },
360
+ {
361
+ "label": "suspension step observed stop",
362
+ "top_frame": {
363
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
364
+ "method": "completeWork",
365
+ "source": "MainActivity.kt",
366
+ "line": 50,
367
+ "code_index": 100,
368
+ "class_loader_id": "2"
369
+ },
370
+ "locals": {
371
+ "availability": "available",
372
+ "locals": [
373
+ {
374
+ "name": "$completion",
375
+ "type": "kotlin.coroutines.Continuation",
376
+ "value": {
377
+ "object_id": "10",
378
+ "type": "dev.mobiledebugmcp.coroutinefixture.MainActivity$start$1"
379
+ },
380
+ "truncated": false
381
+ },
382
+ {
383
+ "name": "$continuation",
384
+ "type": "kotlin.coroutines.Continuation",
385
+ "value": {
386
+ "object_id": "11",
387
+ "type": "dev.mobiledebugmcp.coroutinefixture.MainActivity$completeWork$1"
388
+ },
389
+ "truncated": false
390
+ },
391
+ {
392
+ "name": "$result",
393
+ "type": "java.lang.Object",
394
+ "value": null,
395
+ "truncated": false
396
+ },
397
+ {
398
+ "name": "known",
399
+ "type": "int",
400
+ "value": "42",
401
+ "truncated": false
402
+ }
403
+ ],
404
+ "truncated": false
405
+ }
406
+ },
407
+ {
408
+ "journey": "suspension boundary step",
409
+ "status": "PASS",
410
+ "observation": {
411
+ "event": "stopped",
412
+ "state": "paused",
413
+ "stop_id": "f4dfa658-f209-467b-98bc-f207cf3721f9",
414
+ "thread_id": "f4dfa658-f209-467b-98bc-f207cf3721f9:3",
415
+ "stops": [
416
+ {
417
+ "reason": "step",
418
+ "location": {
419
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity",
420
+ "method": "completeWork",
421
+ "source": "MainActivity.kt",
422
+ "line": 50,
423
+ "code_index": 100,
424
+ "class_loader_id": "2"
425
+ }
426
+ }
427
+ ],
428
+ "sequence": 2,
429
+ "received_at_ms": 1793639498222
430
+ }
431
+ },
432
+ {
433
+ "marker": "BREAK_CANCEL",
434
+ "location": {
435
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity$cancelWork$2$child$1",
436
+ "method": "invokeSuspend",
437
+ "source": "MainActivity.kt",
438
+ "line": 83,
439
+ "code_index": 21,
440
+ "class_loader_id": "152"
441
+ }
442
+ },
443
+ {
444
+ "label": "cancelled child finally",
445
+ "top_frame": {
446
+ "class_name": "dev.mobiledebugmcp.coroutinefixture.MainActivity$cancelWork$2$child$1",
447
+ "method": "invokeSuspend",
448
+ "source": "MainActivity.kt",
449
+ "line": 83,
450
+ "code_index": 21,
451
+ "class_loader_id": "152"
452
+ },
453
+ "locals": {
454
+ "availability": "available",
455
+ "locals": [
456
+ {
457
+ "name": "$result",
458
+ "type": "java.lang.Object",
459
+ "value": {
460
+ "object_id": "201",
461
+ "type": "kotlin.Result$Failure"
462
+ },
463
+ "truncated": false
464
+ }
465
+ ],
466
+ "truncated": false
467
+ }
468
+ },
469
+ {
470
+ "journey": "job cancellation, child finally, cancelAndJoin and recovery",
471
+ "status": "PASS"
472
+ }
473
+ ],
474
+ "cleanup": "PASS: detach complete, owned package/build directory removed, original forwards preserved"
475
+ }
@@ -0,0 +1,47 @@
1
+ # Android coroutine debugger validation — issue #93
2
+
3
+ Date: 2026-11-02. Originator: repository maintainer, through
4
+ [issue #93](https://github.com/clivejefferies/mobile-debug-tools/issues/93).
5
+ Status: intent accepted. The maintainer replied “ok” on 2026-11-02 to the
6
+ proposed scope in this chat. This approves investigation and specification of
7
+ the bounded fixture assessment; the specification was subsequently accepted by a second “ok”.
8
+
9
+ ## Problem and outcome
10
+
11
+ The Android JDI debugger exposes executing threads. Existing Kotlin validation
12
+ establishes ordinary named locals, but does not establish behaviour across
13
+ coroutine suspension, dispatcher changes or generated state machines. MCP clients
14
+ need evidence of which existing debugger operations remain useful and where
15
+ thread-based inspection stops representing a coroutine's logical execution.
16
+
17
+ Validate an isolated debuggable Kotlin fixture with known values before and
18
+ after suspension, a dispatcher/thread change, nested work, cancellation and
19
+ completion. Exercise existing attach, breakpoints, events, stacks, locals,
20
+ stepping, resume and detach. Record source/compiler/runtime correspondence,
21
+ stale-reference rejection, pause guards, app recovery and owned-resource cleanup.
22
+ Evaluate before/after breakpoints as a workaround without claiming stepping
23
+ follows a coroutine across threads. Report emulator and physical-device evidence
24
+ separately, including blocked and unrun paths.
25
+
26
+ ## Boundaries and decisions
27
+
28
+ Deliver reproducible fixture checks, a supported-behaviour report, documentation
29
+ and a go/no-go recommendation for separately designed coroutine inspection.
30
+ No new MCP capability, automatic debug probes, arbitrary evaluation or
31
+ coroutine-following stepping is authorised by this assessment. Any reproduced
32
+ runtime defect or proposed capability follows the shared development process.
33
+
34
+ The specification must select coroutine/compiler versions and explicit fixture
35
+ dependencies, define deterministic stop points and cancellation outcomes, and
36
+ identify available targets. Full coroutine reconstruction must not delay iOS
37
+ parity.
38
+
39
+ ## Initial investigation
40
+
41
+ - The existing Kotlin fixture tests synchronous calculation only; its current
42
+ build helper packages the Kotlin standard library but no coroutine runtime.
43
+ - Reuse existing disposable-fixture and MCP device-test conventions. The
44
+ ordinary Kotlin journey must retain its current behaviour.
45
+ - The earlier [Kotlin report](../029-kotlin-locals-validation/report.md) records
46
+ emulator evidence; it does not establish coroutine or physical-device support.
47
+ - No coroutine implementation or device verification has run for this ticket.
@@ -0,0 +1,147 @@
1
+ # Coroutine validation implementation plan
2
+
3
+ Intent and [specification](spec.md) accepted by two successive “ok” responses
4
+ in this chat on 2026-11-02. No new debugger capability is included.
5
+
6
+ ## Work and verification
7
+
8
+ - [x] Add a separate-package Kotlin coroutine fixture and explicit local-jar build.
9
+ - [x] Add opt-in automated MCP journey with bounded subprocesses and owned cleanup.
10
+ - [x] Exercise completion, gate suspension, two dispatcher threads and nested work.
11
+ - [x] Assess synchronous stepping and a bounded suspension-boundary step attempt.
12
+ - [x] Check cancellation/finally, stale references, pause guard and cancelled wait.
13
+ - [x] Record fingerprints, compiler metadata and per-journey evidence in report.
14
+ - [x] Update fixture README, debugger guide and packaged usage skill.
15
+ - [x] Complete repository verify, focused coroutine checks and full device suite.
16
+
17
+ Acceptance criteria 1–3 map to the opt-in device runner and dated report; criterion
18
+ 4 maps to repository verification, existing device regressions and doc/link checks;
19
+ criterion 5 maps to the evidence-based recommendation in the report.
20
+
21
+ Use Node 22+, JDK 17, Kotlin/stdlib 2.0.21, coroutines 1.9.0 and Android SDK 36.
22
+ Initial fixture state: package absent, emulator-5554 authorized, no owned session.
23
+ Start the generated APK, attach existing MCP debugger, assert source/event/locals
24
+ observations, resume/detach, assert fresh completion or cancellation UI, then
25
+ remove owned package, temporary files and forwards. Keep source/compiler/APK/server
26
+ hashes and distinguish emulator from optional physical-device evidence.
27
+
28
+ Commands (with documented compiler/stdlib/coroutine paths set):
29
+
30
+ ```sh
31
+ npm run verify
32
+ MCP_COROUTINE_DEVICE=emulator-5554 npx tsx test/device/automated/debugger/coroutine.android.test.ts
33
+ MCP_COROUTINE_DEVICE=emulator-5554 MCP_KOTLIN_DEVICE=emulator-5554 MCP_DEBUGGER_DEVICE=emulator-5554 npm run test:device
34
+ ```
35
+
36
+ Check prerequisite availability before install. Missing jars/compiler/device are
37
+ blocked; unspecified opt-in serial is unrun. No automatic dependency downloads.
38
+ Physical device is optional and reported separately; hosted CI does not provision
39
+ this compiler/fixture. Compiler-generated locations and absent ART locals are
40
+ assessment findings, not permission to weaken safety assertions. Runtime defects
41
+ or follow-up capabilities require separate scope decisions.
42
+
43
+ ## Results — 2026-11-02
44
+
45
+ - Focused coroutine check **PASS**, emulator-5554, Android 16/API 36. Completion,
46
+ dispatcher names, synchronous steps, bounded suspension-step observation,
47
+ breakpoint workaround, cancelled wait, stale frame, pause guard, cancellation
48
+ and cleanup passed. Evidence: [report](report.md), [compact record](evidence.json)
49
+ and `/tmp/mobile-debug-93-emulator.log`.
50
+ - Final `npm run verify` **PASS**, Node 22.23.4: lint/quality/architecture,
51
+ TypeScript build, all 89 unit files and plugin consistency. Log:
52
+ `/tmp/mobile-debug-93-final-verify.log`. The sandbox denied tsx IPC pipe creation;
53
+ the authorized run outside the sandbox passed without changing checks.
54
+ - Full `npm run test:device` **PASS**, all 12 files, with all three debugger
55
+ opt-ins above. Coroutine and existing Kotlin/Java debugger, interaction,
56
+ Android/iOS observation smoke, correlation and Android system-trace checks
57
+ passed. Log: `/tmp/mobile-debug-93-device.log`. iOS observation does not verify
58
+ iOS runtime debugging. The coroutine fixture/package/forwards were cleaned up.
59
+ - Changed Markdown relative links and `git diff --check` **PASS**.
60
+ - Physical coroutine checks, forced termination/device disconnect and hosted CI
61
+ **UNRUN**. No new runtime capability or production-code fix was required.
62
+ - Focused review checked device/package targeting, pause/stale guards, event
63
+ cursor overflow, compiler source mapping, subprocess bounds and owned cleanup.
64
+ Compiler scope elimination and fixture starting-state problems were addressed
65
+ in test setup; no server contract change was introduced.
66
+
67
+ ## PR #96 review repairs — 2026-11-02
68
+
69
+ Lightweight repair of the three attached review comments; no capability or
70
+ contract change. `feature/coroutines` started clean at
71
+ `a46c9091d5df8f064e4c1d5961a708964b2ed74d`.
72
+
73
+ - Overall JSON reporting now encloses work and cleanup. PASS is emitted only
74
+ after cleanup; cleanup failures emit FAIL and reject the run. Unit regression
75
+ checks cover successful cleanup, work failure and cleanup failure with either
76
+ successful or failed work.
77
+ - Both gate-readiness messages are posted by work queued on the waiting
78
+ coroutine's single-thread executor, after its gate wait yields. Compiler
79
+ metadata changed the dispatcher/result breakpoint class to `completeWork$3`;
80
+ both bindings were updated.
81
+ - All forwarding snapshots filter the exact device serial and normalize ordering.
82
+ Unit coverage changes another device's forwards, reorders the target's table
83
+ and confirms target forward removal still fails comparison.
84
+ - `npm run verify` **PASS**, Node 22.23.3, all 90 unit files, lint, quality,
85
+ architecture, build and plugin consistency. Log: `/tmp/pr96-verify.log`.
86
+ - First device run **FAIL** due to the restored emulator snapshot becoming
87
+ unresponsive during installation and uninstall. The actual cleanup failure
88
+ emitted JSON FAIL with no overall JSON PASS. Log: `/tmp/pr96-device.log`.
89
+ Cold-started the existing Android 36 AVD without wiping data; removed the
90
+ task-owned leftover package once the guest recovered. The Pixel_8 AVD could
91
+ not start because its configured Android 37.1 system image is absent.
92
+ - Final `npm run verify` **PASS** after preserving simultaneous work/cleanup
93
+ errors in an AggregateError; all 90 unit files. Log: `/tmp/pr96-final-verify.log`.
94
+ - Full device-suite attempts **FAIL** at fixture setup on this emulator:
95
+ incremental installation timed out and continued installing in the guest;
96
+ cold-start logs: `/tmp/pr96-device-cold.log`. No checks were weakened.
97
+ - Focused Android 36 rerun using a temporary `ADB_PATH` wrapper that adds
98
+ `--no-incremental` only to installation: completion, gate-readiness,
99
+ dispatcher/result source bindings, synchronous stepping, pause/stale guards,
100
+ cancelled-wait recovery and bounded suspension-step observation **PASS**.
101
+ The run then **FAIL**ed restarting the owned fixture before cancellation
102
+ (`am start -W` timeout), with an additional uninstall timeout. The overall JSON
103
+ result is FAIL and preserves both errors; cancellation remains **UNRUN** for
104
+ the repaired fixture. Log: `/tmp/pr96-focused-streamed.log`.
105
+ - Final independent package query confirmed the owned package absent; the
106
+ forwarding table was empty. Temporary build output was removed. Physical
107
+ checks and hosted CI remain unrun. Native verification is partial, not a full
108
+ suite pass; the remaining limitation is recorded rather than bypassing it.
109
+
110
+ ## Retry on the maintainer's running emulator — 2026-11-02
111
+
112
+ The complete repaired coroutine journey **PASS**ed on the already-running
113
+ emulator-5554, Android 16/API 36, at commit `1497693`. This includes cancellation
114
+ readiness, the child finally breakpoint, cancelAndJoin, fresh cancellation UI,
115
+ completion, synchronous steps, guards, cancelled-wait recovery and final cleanup.
116
+ Overall JSON PASS was emitted after package/build-output/forward cleanup.
117
+ Log: `/tmp/pr96-user-emulator.log`. No test source, assertions or deadlines changed.
118
+
119
+ Runtime: Node 22.23.3, fixture compiler Kotlin 2.0.21/JDK 17.0.11, coroutines 1.9.0.
120
+ The local `ADB_PATH` wrapper selected streamed (`--no-incremental`) installation;
121
+ `JAVA_TOOL_OPTIONS='-Xmx512m -XX:TieredStopAtLevel=1'` reduced host JVM startup cost.
122
+ The existing emulator was used directly and is left running. Its existing user
123
+ apps/data were not cleared. Full device regression results are recorded below.
124
+
125
+ The full `npm run test:device` retry passed coroutine, Kotlin/Java debugger,
126
+ interaction and Android screenshot checks, then **FAIL**ed at the iOS screenshot
127
+ check because multiple matching iOS simulators were available and no target was
128
+ selected. Log: `/tmp/pr96-user-device-suite.log`. Separate Android logs and UI-tree
129
+ checks **PASS**ed, as did the Android correlated-evidence portion; its required
130
+ iOS portion **FAIL**ed because no iOS simulator was running. Log:
131
+ `/tmp/pr96-user-android-remaining.log`. These iOS setup failures do not represent
132
+ an Android emulator failure; they prevent claiming a complete suite pass.
133
+
134
+ The separate Android system-trace check **FAIL**ed its cancellation assertion:
135
+ `cancel_system_trace` returned `failed` / `ACTION_TIMEOUT` instead of `cancelled`.
136
+ The test's finally cleanup retry completed. Log: `/tmp/pr96-user-trace.log`.
137
+ This does not change the repaired coroutine journey's PASS result and prevents
138
+ claiming all Android smoke checks passed. No tracing code or assertions changed.
139
+
140
+ Perfetto investigation: three direct start/cancel probes and three full MCP smoke
141
+ journeys subsequently **PASS**ed with unchanged production code/assertions. The
142
+ final MCP run recorded command timings; process lookup max 111 ms, signal max
143
+ 63 ms, no command timeouts. Owned artifacts/files/forwards were cleaned up. The
144
+ original ACTION_TIMEOUT was not reproduced and is not root-caused; no runtime
145
+ fix or relaxed deadline is claimed. See the report's Perfetto investigation and
146
+ `/tmp/pr96-perfetto-mcp-timings.log`. This supplies passing current trace evidence
147
+ without erasing the original failed run; iOS setup limitations remain separate.